Hello community, here is the log from the commit of package yast2-network for openSUSE:Factory checked in at 2016-05-23 16:36:09 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/yast2-network (Old) and /work/SRC/openSUSE:Factory/.yast2-network.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-network" Changes: -------- --- /work/SRC/openSUSE:Factory/yast2-network/yast2-network.changes 2016-05-10 09:24:57.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.yast2-network.new/yast2-network.changes 2016-05-23 16:36:10.000000000 +0200 @@ -1,0 +2,22 @@ +Tue May 17 16:04:49 UTC 2016 - [email protected] + +- bnc#971175 + - /etc/hosts is correctly updated with static address, hostname + when static net configuration is done via linuxrc and hostname + is provided by AY profile +- 3.1.151 + +------------------------------------------------------------------- +Fri May 13 10:19:39 UTC 2016 - [email protected] + +- fate#315995 + - Added physical port id to device overview and bond slaves item + description if supported. + - Warn the user when two or more bonded interfaces share the + same physical port. + - Available interfaces for bonding in bond slaves tab are now + sorted and moving them up or down maintain the interface + selected. +- 3.1.150 + +------------------------------------------------------------------- Old: ---- yast2-network-3.1.149.tar.bz2 New: ---- yast2-network-3.1.151.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ yast2-network.spec ++++++ --- /var/tmp/diff_new_pack.imYbXS/_old 2016-05-23 16:36:11.000000000 +0200 +++ /var/tmp/diff_new_pack.imYbXS/_new 2016-05-23 16:36:11.000000000 +0200 @@ -17,7 +17,7 @@ Name: yast2-network -Version: 3.1.149 +Version: 3.1.151 Release: 0 BuildRoot: %{_tmppath}/%{name}-%{version}-build ++++++ yast2-network-3.1.149.tar.bz2 -> yast2-network-3.1.151.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.1.149/package/yast2-network.changes new/yast2-network-3.1.151/package/yast2-network.changes --- old/yast2-network-3.1.149/package/yast2-network.changes 2016-05-04 21:43:30.000000000 +0200 +++ new/yast2-network-3.1.151/package/yast2-network.changes 2016-05-17 18:24:00.000000000 +0200 @@ -1,4 +1,26 @@ ------------------------------------------------------------------- +Tue May 17 16:04:49 UTC 2016 - [email protected] + +- bnc#971175 + - /etc/hosts is correctly updated with static address, hostname + when static net configuration is done via linuxrc and hostname + is provided by AY profile +- 3.1.151 + +------------------------------------------------------------------- +Fri May 13 10:19:39 UTC 2016 - [email protected] + +- fate#315995 + - Added physical port id to device overview and bond slaves item + description if supported. + - Warn the user when two or more bonded interfaces share the + same physical port. + - Available interfaces for bonding in bond slaves tab are now + sorted and moving them up or down maintain the interface + selected. +- 3.1.150 + +------------------------------------------------------------------- Mon May 2 11:35:45 UTC 2016 - [email protected] - bnc#977953 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.1.149/package/yast2-network.spec new/yast2-network-3.1.151/package/yast2-network.spec --- old/yast2-network-3.1.149/package/yast2-network.spec 2016-05-04 21:43:30.000000000 +0200 +++ new/yast2-network-3.1.151/package/yast2-network.spec 2016-05-17 18:24:00.000000000 +0200 @@ -17,7 +17,7 @@ Name: yast2-network -Version: 3.1.149 +Version: 3.1.151 Release: 0 BuildRoot: %{_tmppath}/%{name}-%{version}-build diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.1.149/src/clients/save_network.rb new/yast2-network-3.1.151/src/clients/save_network.rb --- old/yast2-network-3.1.149/src/clients/save_network.rb 2016-05-04 21:43:31.000000000 +0200 +++ new/yast2-network-3.1.151/src/clients/save_network.rb 2016-05-17 18:24:00.000000000 +0200 @@ -36,8 +36,6 @@ include Logger def main - Yast.import "UI" - textdomain "network" Yast.import "DNS" @@ -86,6 +84,8 @@ SYSCONFIG = "/etc/sysconfig/network/" def CopyConfiguredNetworkFiles + return if Mode.autoinst && !NetworkAutoYast.instance.keep_net_config? + log.info( "Copy network configuration files from 1st stage into installed system" ) @@ -247,15 +247,28 @@ nil end + # Creates target's default DNS configuration + # + # It uses DNS configuration as defined in AY profile (if any) or + # proposes a predefined default values. + def configure_dns + configured = false + configured = NetworkAutoYast.instance.configure_dns if Mode.autoinst + NetworkAutoconfiguration.instance.configure_dns if !configured + + DNS.create_hostname_link + end + # It does an automatic configuration of installed system # # Basically, it runs several proposals. def configure_target NetworkAutoconfiguration.instance.configure_virtuals - NetworkAutoconfiguration.instance.configure_dns - NetworkAutoconfiguration.instance.configure_hosts - DNS.create_hostname_link + configure_dns + + # this depends on DNS configuration + NetworkAutoconfiguration.instance.configure_hosts set_network_service diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.1.149/src/include/network/lan/address.rb new/yast2-network-3.1.151/src/include/network/lan/address.rb --- old/yast2-network-3.1.149/src/include/network/lan/address.rb 2016-05-04 21:43:31.000000000 +0200 +++ new/yast2-network-3.1.151/src/include/network/lan/address.rb 2016-05-17 18:24:00.000000000 +0200 @@ -28,6 +28,8 @@ # module Yast module NetworkLanAddressInclude + include Yast::Logger + def initialize_network_lan_address(include_target) Yast.import "UI" @@ -226,8 +228,8 @@ "help" => Ops.get_string(@help, "etherdevice", "") }, "BONDSLAVE" => { - "widget" => :custom, - "custom_widget" => Frame( + "widget" => :custom, + "custom_widget" => Frame( _("Bond Slaves and Order"), VBox( MultiSelectionBox(Id(:msbox_items), Opt(:notify), "", []), @@ -237,18 +239,23 @@ ) ) ), - "label" => _("Bond &Slaves"), + "label" => _("Bond &Slaves"), # "opt": [`shrinkable], - "init" => fun_ref( + "init" => fun_ref( method(:InitSlave), "void (string)" ), - "handle" => fun_ref( + "handle" => fun_ref( method(:HandleSlave), "symbol (string, map)" ), - "store" => fun_ref(method(:StoreSlave), "void (string, map)"), - "help" => Ops.get_string(@help, "bondslave", "") + "validate_type" => :function, + "validate_function" => fun_ref( + method(:validate_bond), + "boolean (string, map)" + ), + "store" => fun_ref(method(:StoreSlave), "void (string, map)"), + "help" => @help["bondslave"].to_s }, "BONDOPTION" => { "widget" => :combobox, @@ -576,22 +583,14 @@ nil end + # Given a device name returns the position in the bond slaves table + # or -1 if not present + # + # @param [String] slave name + # @return [Integer] index of the given slave in msbox_items table def getISlaveIndex(slave) - items = Convert.convert( - UI.QueryWidget(:msbox_items, :Items), - from: "any", - to: "list <term>" - ) - index = -1 - pos = 0 - Builtins.foreach(items) do |it| - if Ops.get_string(it, [0, 0], "") == slave - index = pos - raise Break - end - pos = Ops.add(pos, 1) - end - index + items = UI.QueryWidget(:msbox_items, :Items) + items.index { |i| i[0][0] == slave } || -1 end def enableSlaveButtons @@ -615,14 +614,14 @@ # Default function to init the value of slave devices box for bonding. # @param [String] key id of the widget def InitSlave(_key) - Ops.set(@settings, "SLAVES", LanItems.bond_slaves) + @settings["SLAVES"] = LanItems.bond_slaves || [] UI.ChangeWidget( :msbox_items, :SelectedItems, - Ops.get_list(@settings, "SLAVES", []) + @settings["SLAVES"] ) - Ops.set(@settings, "BONDOPTION", LanItems.bond_option) + @settings["BONDOPTION"] = LanItems.bond_option items = CreateSlaveItems( LanItems.GetBondableInterfaces(LanItems.GetCurrentName), @@ -630,95 +629,59 @@ ) # reorder the items - l2 = [] - l1 = [] - Builtins.foreach( - Convert.convert(items, from: "list", to: "list <term>") - ) do |t| - if Builtins.contains( - Ops.get_list(@settings, "SLAVES", []), - Ops.get_string(t, [0, 0], "") - ) - l1 = Builtins.add(l1, t) - else - l2 = Builtins.add(l2, t) - end - end + l1, l2 = items.partition { |t| @settings["SLAVES"].include? t[0][0] } - items = [] - Builtins.foreach(Ops.get_list(@settings, "SLAVES", [])) do |s| - Builtins.foreach( - Convert.convert(l1, from: "list", to: "list <term>") - ) do |t| - items = Builtins.add(items, t) if Ops.get_string(t, [0, 0], "") == s - end - end + items = l1 + l2.sort_by { |t| justify_dev_name(t[0][0]) } - items = Builtins.union(items, l2) UI.ChangeWidget(:msbox_items, :Items, items) enableSlaveButtons nil end + # A helper for sort devices by name. It justify at right with 0's numeric parts of given + # device name until 5 digits. + # + # ==== Examples + # + # justify_dev_name("eth0") # => "eth00000" + # justify_dev_name("eth111") # => "eth00111" + # justify_dev_name("enp0s25") # => "enp00000s00025" + # + # @param name [String] device name + # @return [String] given name with numbers justified at right + def justify_dev_name(name) + splited_dev_name = name.scan(/\p{Alpha}+|\p{Digit}+/) + splited_dev_name.map! do |d| + if d.match(/\p{Digit}+/) + d.rjust(5, "0") + else + d + end + end.join + end + def HandleSlave(_key, event) - event = deep_copy(event) - if Ops.get_string(event, "EventReason", "") == "SelectionChanged" + if event["EventReason"] == "SelectionChanged" enableSlaveButtons - elsif Ops.get_string(event, "EventReason", "") == "Activated" && - Ops.get(event, "WidgetClass") == :PushButton - items = Convert.convert( - UI.QueryWidget(:msbox_items, :Items), - from: "any", - to: "list <term>" - ) - current = Builtins.tostring(UI.QueryWidget(:msbox_items, :CurrentItem)) + elsif event["EventReason"] == "Activated" && event["WidgetClass"] == :PushButton + items = UI.QueryWidget(:msbox_items, :Items) || [] + current = UI.QueryWidget(:msbox_items, :CurrentItem).to_s index = getISlaveIndex(current) - new_items = [] - pos = 0 - case Ops.get_symbol(event, "ID", :nil) + case event["ID"] when :up - while Ops.greater_than(index, Ops.add(pos, 1)) - new_items = Builtins.add(new_items, Ops.get(items, pos)) - pos = Ops.add(pos, 1) - end - new_items = Builtins.add(new_items, Ops.get(items, index)) - new_items = Builtins.add( - new_items, - Ops.get(items, Ops.subtract(index, 1)) - ) - new_items = Convert.convert( - Builtins.union(new_items, Builtins.sublist(items, index)), - from: "list", - to: "list <term>" - ) + items[index], items[index - 1] = items[index - 1], items[index] when :down - while Ops.greater_than(index, pos) - new_items = Builtins.add(new_items, Ops.get(items, pos)) - pos = Ops.add(pos, 1) - end - new_items = Builtins.add( - new_items, - Ops.get(items, Ops.add(index, 1)) - ) - new_items = Builtins.add(new_items, Ops.get(items, index)) - new_items = Convert.convert( - Builtins.union( - new_items, - Builtins.sublist(items, Ops.add(index, 1)) - ), - from: "list", - to: "list <term>" - ) + items[index], items[index + 1] = items[index + 1], items[index] else - Builtins.y2warning("unknown action") + log.warn("unknown action") return nil end - items = deep_copy(new_items) UI.ChangeWidget(:msbox_items, :Items, items) + UI.ChangeWidget(:msbox_items, :CurrentItem, current) enableSlaveButtons else - Builtins.y2debug("event:%1", event) + log.debug("event:#{event}") end nil @@ -728,36 +691,70 @@ # @param [String] key id of the widget # @param [String] key id of the widget def StoreSlave(_key, _event) - configured_slaves = Ops.get_list(@settings, "SLAVES", []) + configured_slaves = @settings["SLAVES"] || [] - Ops.set( - @settings, - "SLAVES", - Convert.convert( - UI.QueryWidget(:msbox_items, :SelectedItems), - from: "any", - to: "list <string>" - ) - ) - Ops.set(@settings, "BONDOPTION", UI.QueryWidget(Id("BONDOPTION"), :Value)) + @settings["SLAVES"] = get_selected_slaves - LanItems.bond_slaves = Ops.get_list(@settings, "SLAVES", []) - LanItems.bond_option = Ops.get_string(@settings, "BONDOPTION", "") + @settings["BONDOPTION"] = UI.QueryWidget(Id("BONDOPTION"), :Value).to_s + + LanItems.bond_slaves = @settings["SLAVES"] + LanItems.bond_option = @settings["BONDOPTION"] # create list of "unconfigured" slaves - new_slaves = Builtins.filter(Ops.get_list(@settings, "SLAVES", [])) do |slave| - !Builtins.contains(configured_slaves, slave) + new_slaves = @settings["SLAVES"].select do |slave| + !configured_slaves.include? slave end - Lan.bond_autoconf_slaves = Convert.convert( - Builtins.toset(Builtins.merge(Lan.bond_autoconf_slaves, new_slaves)), - from: "list", - to: "list <string>" - ) + Lan.bond_autoconf_slaves = (Lan.bond_autoconf_slaves + new_slaves).uniq.sort nil end + # Validates created bonding. Currently just prevent the user to create a + # bond with more than one interface sharing the same physical port id + # + # @param [String] key the widget being validated + # @param [Hash] event the event being handled + # @return true if valid or user decision if not + def validate_bond(_key, _event) + physical_ports = repeated_physical_port_ids(get_selected_slaves) + + physical_ports.empty? ? true : continue_with_duplicates?(physical_ports) + end + + # FIXME: This method should be moved to a more generic class. + # Wrap given text breaking lines longer than given wrap size. It supports + # custom separator, max number of lines to split in and cut text to add + # as last line if cut was needed. + # + # @param [String] text to be wrapped + # @param [String] wrap size + # @param [Hash <String>] optional parameters as separator and prepend_text. + # @return [String] wrap text + def wrap_text(text, wrap = 78, separator: " ", prepend_text: "", + n_lines: nil, cut_text: nil) + lines = [] + message_line = prepend_text + text.split(/\s+/).each_with_index do |t, i| + if !message_line.empty? && "#{message_line}#{t}".size > wrap + lines << message_line + message_line = "" + end + + message_line << separator if !message_line.empty? && i != 0 + message_line << t + end + + lines << message_line if !message_line.empty? + + if n_lines && lines.size > n_lines + lines = lines[0..n_lines - 1] + lines << cut_text if cut_text + end + + lines.join("\n") + end + def initTunnel(_key) Builtins.y2internal("initTunnel %1", @settings) UI.ChangeWidget( @@ -1600,5 +1597,52 @@ deep_copy(ret) end + + private + + def get_selected_slaves + UI.QueryWidget(:msbox_items, :SelectedItems) || [] + end + + # Given a map of duplicated port ids with device names, aks the user if he + # would like to continue or not. + # + # @param [Hash{String => Array<String>}] hash of duplicated physical port ids + # mapping to an array of device names + # @return [Boolean] true if continue with duplicates, otherwise false + def continue_with_duplicates?(physical_ports) + message = physical_ports.map do |port, slave| + label = "PhysicalPortID (#{port}): " + wrap_text(slave.join(", "), 76, prepend_text: label) + end.join("\n") + + Popup.YesNoHeadline( + Label.WarningMsg, + # Translators: Warn the user about not desired effect + _("The interfaces selected share the same physical port and bonding " \ + "them \nmay not have the desired effect of redundancy.\n\n%s\n\n" \ + "Really continue?\n") % message + ) + end + + # Given a list of device names returns a hash of physical port ids mapping + # device names if at least two devices shared the same physical port id + # + # @param [Array<String] bonding slaves + # @return [Hash{String => Array<String>}] of duplicated physical port ids + def repeated_physical_port_ids(slaves) + physical_port_ids = {} + + slaves.each do |slave| + if physical_port_id?(slave) + p = physical_port_ids[physical_port_id(slave)] ||= [] + p << slave + end + end + + physical_port_ids.select! { |_k, v| v.size > 1 } + + physical_port_ids + end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.1.149/src/include/network/routines.rb new/yast2-network-3.1.151/src/include/network/routines.rb --- old/yast2-network-3.1.149/src/include/network/routines.rb 2016-05-04 21:43:31.000000000 +0200 +++ new/yast2-network-3.1.151/src/include/network/routines.rb 2016-05-17 18:24:00.000000000 +0200 @@ -746,6 +746,25 @@ ).to_i != 0 end + # With NPAR and SR-IOV capabilities, one device could divide a ethernet + # port in various. If the driver module support it, we can check the phys + # port id via sysfs reading the /sys/class/net/$dev_name/phys_port_id + # + # @param [String] device name to check + # @return [String] physical port id if supported or a empty string if not + def physical_port_id(dev_name) + SCR.Read( + path(".target.string"), + "/sys/class/net/#{dev_name}/phys_port_id" + ).to_s.strip + end + + # @return [boolean] true if the physical port id is not empty + # @see #physical_port_id + def physical_port_id?(dev_name) + !physical_port_id(dev_name).empty? + end + # Checks if device is physically connected to a network # # It does neccessary steps which might be needed for proper initialization diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.1.149/src/include/network/widgets.rb new/yast2-network-3.1.151/src/include/network/widgets.rb --- old/yast2-network-3.1.149/src/include/network/widgets.rb 2016-05-04 21:43:31.000000000 +0200 +++ new/yast2-network-3.1.151/src/include/network/widgets.rb 2016-05-17 18:24:00.000000000 +0200 @@ -574,6 +574,8 @@ selected = false selected = enslavedIfaces.include?(dev_name) if enslavedIfaces + description << " (Port ID: #{physical_port_id(dev_name)})" if physical_port_id?(dev_name) + items << Item( Id(dev_name), "#{dev_name} - #{description}", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.1.149/src/lib/network/network_autoyast.rb new/yast2-network-3.1.151/src/lib/network/network_autoyast.rb --- old/yast2-network-3.1.149/src/lib/network/network_autoyast.rb 2016-05-04 21:43:31.000000000 +0200 +++ new/yast2-network-3.1.151/src/lib/network/network_autoyast.rb 2016-05-17 18:24:00.000000000 +0200 @@ -104,6 +104,37 @@ NetworkService.EnableDisableNow end + # Initializates DNS setup according AY profile + # + # FIXME: it currently doesn't write DNS configuration. It is used for initialization + # of DNS setup according AY profile in 1st stage as part of network setup was moved + # here already and some parts of network configuration needs to know it. DNS write + # is still done in 2nd stage. + # + # @return [Boolean] true when configuration was present and loaded from the profile + def configure_dns + ay_dns_config = ay_networking_section["dns"] + + return false if !ay_dns_config + + DNS.Import(ay_dns_config) + + log.info("NetworkAutoYast: DNS / Hostname configuration") + log.info("dhcp hostname: #{DNS.dhcp_hostname}") + log.info("write hostname: #{DNS.write_hostname}") + + true + end + + # Checks if the profile asks for keeping installation network configuration + def keep_net_config? + ret = ay_networking_section.fetch("keep_install_network", false) + + log.info("NetworkAutoYast: keep installation network: #{ret}") + + ret + end + private # Merges two devices map into one. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.1.149/src/modules/LanItems.rb new/yast2-network-3.1.151/src/modules/LanItems.rb --- old/yast2-network-3.1.149/src/modules/LanItems.rb 2016-05-04 21:43:31.000000000 +0200 +++ new/yast2-network-3.1.151/src/modules/LanItems.rb 2016-05-17 18:24:00.000000000 +0200 @@ -813,7 +813,7 @@ result = [] - Builtins.foreach(@Items) do |itemId, _attribs| + LanItems.Items.each do |itemId, _attribs| if @current != itemId && validator.call(master, itemId) result = Builtins.add(result, itemId) else @@ -1407,9 +1407,11 @@ mac_dev = HTML.Bold("MAC : ") + item_hwinfo["mac"].to_s + "<br>" bus_id = HTML.Bold("BusID : ") + item_hwinfo["busid"].to_s + "<br>" + physical_port_id = HTML.Bold("PhysicalPortID : ") + physical_port_id(ifcfg_name) + "<br>" rich << " " << conn << "<br>" << mac_dev if IsNotEmpty(item_hwinfo["mac"]) rich << bus_id if IsNotEmpty(item_hwinfo["busid"]) + rich << physical_port_id if physical_port_id?(ifcfg_name) # display it only if we need it, don't duplicate "ifcfg_name" above if IsNotEmpty(item_hwinfo["dev_name"]) && ifcfg_name.empty? dev_name = _("Device Name: %s") % item_hwinfo["dev_name"] @@ -2284,7 +2286,7 @@ SCR.Execute(path(".target.bash_output"), command1), from: "any", to: "map <string, any>" - ) + ) if Ops.get_integer(output1, "exit", -1) == 0 && Builtins.size(Ops.get_string(output1, "stderr", "")) == 0 Builtins.y2milestone("Success : %1", output1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.1.149/test/address_test.rb new/yast2-network-3.1.151/test/address_test.rb --- old/yast2-network-3.1.149/test/address_test.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-network-3.1.151/test/address_test.rb 2016-05-17 18:24:00.000000000 +0200 @@ -0,0 +1,131 @@ +#!/usr/bin/env rspec + +require_relative "test_helper" + +Yast.import "UI" + +class DummyClass < Yast::Module + def initialize + Yast.include self, "network/lan/address.rb" + end +end + +describe "NetworkLanAddressInclude" do + subject { DummyClass.new } + + describe "#justify_dev_name" do + + it "returns given device name justified by 0's at right" do + expect(subject.justify_dev_name("em5p1")).to eq("em00005p00001") + end + + end + + describe "wrap_text" do + subject(:routines) { DummyClass.new } + let(:devices) { ["eth0", "eth1", "eth2", "eth3", "a_very_long_device_name"] } + let(:more_devices) do + [ + "enp5s0", "enp5s1", "enp5s2", "enp5s3", + "enp5s4", "enp5s5", "enp5s6", "enp5s7" + ] + end + + context "given a text" do + it "returns same text if it does not exceed wrap size" do + text = "eth0, eth1, eth2, eth3, a_very_long_device_name" + + expect(routines.wrap_text(devices.join(", "))).to eql(text) + end + + context "given a line size" do + it "returns given text splitted in lines by given line size" do + text = "eth0, eth1, eth2,\n" \ + "eth3,\n" \ + "a_very_long_device_name" + + expect(routines.wrap_text(devices.join(", "), 16)).to eql(text) + end + end + + context "given a number of lines and '...' as cut text" do + it "returns wrapped text until given line's number adding '...' as a new line" do + devices_s = (devices + more_devices).join(", ") + text = "eth0, eth1, eth2,\n" \ + "eth3,\n" \ + "a_very_long_device_name,\n" \ + "..." + + expect(routines.wrap_text(devices_s, 20, n_lines: 3, cut_text: "...")).to eql(text) + end + end + + end + end + + describe "#getISlaveIndex" do + let(:msbox_items) do + [ + Yast::Term.new(:item, Yast::Term.new(:id, "eth0")), + Yast::Term.new(:item, Yast::Term.new(:id, "eth1")), + Yast::Term.new(:item, Yast::Term.new(:id, "eth1.5")), + Yast::Term.new(:item, Yast::Term.new(:id, "eth2")) + ] + end + + before do + allow(Yast::UI).to receive(:QueryWidget).with(:msbox_items, :Items).and_return(msbox_items) + end + + it "returns the index position of the given slave in the mbox_items table" do + expect(subject.getISlaveIndex("eth2")).to eql(3) + expect(subject.getISlaveIndex("eth1.5")).to eql(2) + end + + it "returns -1 in case the slave is not in the msbox_items table" do + expect(subject.getISlaveIndex("eth4")).to eql(-1) + end + end + + describe "#validate_bond" do + before do + allow(Yast::UI).to receive(:QueryWidget) + .with(:msbox_items, :SelectedItems) + .and_return(msbox_items) + end + + context "when there is not more than one physical port id per interface" do + let(:msbox_items) { ["eth0", "eth1", "eth2", "eth3"] } + + it "returns true" do + allow(subject).to receive(:physical_port_id?).with("eth0").and_return(false) + allow(subject).to receive(:physical_port_id?).with("eth1").and_return(false) + allow(subject).to receive(:physical_port_id?).with("eth2").and_return(true) + allow(subject).to receive(:physical_port_id?).with("eth3").and_return(true) + allow(subject).to receive(:physical_port_id).with("eth2").and_return("00010486fd348") + allow(subject).to receive(:physical_port_id).with("eth3").and_return("00010486fd34a") + + expect(subject.validate_bond("key", "Event")).to eql(true) + end + end + + context "when there is more than one physical port id per interface" do + let(:msbox_items) do + ["eth0", "eth1", "eth2", "eth3", "eth4", "eth5", "eth6", "eth7", + "enp0sp25", "enp0sp26", "enp0sp27", "enp0sp28", "enp0sp29"] + end + + it "warns the user and request confirmation to continue" do + msbox_items.map do |i| + allow(subject).to receive(:physical_port_id?).with(i).and_return(true) + allow(subject).to receive(:physical_port_id).with(i).and_return("00010486fd348") + end + + expect(Yast::Popup).to receive(:YesNoHeadline).and_return(:request_answer) + + expect(subject.validate_bond("key", "Event")).to eql(:request_answer) + end + end + end + +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.1.149/test/network_autoyast_test.rb new/yast2-network-3.1.151/test/network_autoyast_test.rb --- old/yast2-network-3.1.149/test/network_autoyast_test.rb 2016-05-04 21:43:31.000000000 +0200 +++ new/yast2-network-3.1.151/test/network_autoyast_test.rb 2016-05-17 18:24:00.000000000 +0200 @@ -209,6 +209,47 @@ end end + describe "#configure_dns" do + let(:network_autoyast) { Yast::NetworkAutoYast.instance } + + it "imports DNS configuration when available in profile" do + Yast.import "DNS" + + allow(network_autoyast) + .to receive(:ay_networking_section) + .and_return("dns" => { "dhcp_hostname" => false }) + + expect(Yast::DNS).to receive(:Import) + + network_autoyast.configure_dns + end + end + + describe "#keep_net_config?" do + let(:network_autoyast) { Yast::NetworkAutoYast.instance } + + def keep_install_network_value(value) + allow(network_autoyast) + .to receive(:ay_networking_section) + .and_return(value) + end + + it "succeedes when keep_install_network is set in AY profile" do + keep_install_network_value("keep_install_network" => true) + expect(network_autoyast.keep_net_config?).to be true + end + + it "fails when keep_install_network is not set in AY profile" do + keep_install_network_value("keep_install_network" => false) + expect(network_autoyast.keep_net_config?).to be false + end + + it "fails when keep_install_network is not present in AY profile" do + keep_install_network_value({}) + expect(network_autoyast.keep_net_config?).to be false + end + end + context "When AY profile contains old style name" do let(:ay_old_id) do { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-network-3.1.149/test/routines_test.rb new/yast2-network-3.1.151/test/routines_test.rb --- old/yast2-network-3.1.149/test/routines_test.rb 2016-05-04 21:43:31.000000000 +0200 +++ new/yast2-network-3.1.151/test/routines_test.rb 2016-05-17 18:24:00.000000000 +0200 @@ -121,3 +121,38 @@ .to match_array([Item(Id(0), "x", false), Item(Id(1), "y", true)]) end end + +describe "physical_port_id" do + subject(:routines) { RoutinesTestClass.new } + let(:phys_port_id) { "physical_port_id" } + + before do + allow(Yast::SCR).to receive(:Read) + .with(Yast::Path.new(".target.string"), "/sys/class/net/eth0/phys_port_id") + .and_return(phys_port_id) + end + + context "when the module driver support it" do + it "returns ethernet physical port id" do + expect(routines.physical_port_id("eth0")).to eql("physical_port_id") + end + end + + context "when the module driver doesn't support it" do + let(:phys_port_id) { nil } + + it "returns an empty string" do + expect(routines.physical_port_id("eth0")).to be_empty + end + end +end + +describe "#physical_port_id?" do + subject(:routines) { RoutinesTestClass.new } + + it "returns true if physical port id is not empty" do + allow(routines).to receive(:physical_port_id).with("eth0") { "physical_port_id" } + + expect(routines.physical_port_id?("eth0")).to eql(true) + end +end
