Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package yast2-s390 for openSUSE:Factory checked in at 2023-06-09 20:40:08 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/yast2-s390 (Old) and /work/SRC/openSUSE:Factory/.yast2-s390.new.15902 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-s390" Fri Jun 9 20:40:08 2023 rev:31 rq:1091788 version:4.6.2 Changes: -------- --- /work/SRC/openSUSE:Factory/yast2-s390/yast2-s390.changes 2023-05-10 17:39:29.835693566 +0200 +++ /work/SRC/openSUSE:Factory/.yast2-s390.new.15902/yast2-s390.changes 2023-06-09 20:43:31.304674130 +0200 @@ -1,0 +2,7 @@ +Mon Jun 5 10:09:02 UTC 2023 - José Iván López González <jlo...@suse.com> + +- Expose zFCP core functionallity (related to + gh#openSUSUE/agama#594) +- 4.6.2 + +------------------------------------------------------------------- Old: ---- yast2-s390-4.6.1.tar.bz2 New: ---- yast2-s390-4.6.2.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ yast2-s390.spec ++++++ --- /var/tmp/diff_new_pack.Vf2mpk/_old 2023-06-09 20:43:32.296679892 +0200 +++ /var/tmp/diff_new_pack.Vf2mpk/_new 2023-06-09 20:43:32.316680007 +0200 @@ -17,7 +17,7 @@ Name: yast2-s390 -Version: 4.6.1 +Version: 4.6.2 Release: 0 Group: System/YaST License: GPL-2.0-only ++++++ yast2-s390-4.6.1.tar.bz2 -> yast2-s390-4.6.2.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-s390-4.6.1/package/yast2-s390.changes new/yast2-s390-4.6.2/package/yast2-s390.changes --- old/yast2-s390-4.6.1/package/yast2-s390.changes 2023-05-10 17:09:12.000000000 +0200 +++ new/yast2-s390-4.6.2/package/yast2-s390.changes 2023-06-09 11:19:12.000000000 +0200 @@ -1,4 +1,11 @@ ------------------------------------------------------------------- +Mon Jun 5 10:09:02 UTC 2023 - José Iván López González <jlo...@suse.com> + +- Expose zFCP core functionallity (related to + gh#openSUSUE/agama#594) +- 4.6.2 + +------------------------------------------------------------------- Wed May 10 13:35:34 UTC 2023 - Stefan Hundhammer <shundham...@suse.com> - Prevent crash when the user closes the DASD context menu diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-s390-4.6.1/package/yast2-s390.spec new/yast2-s390-4.6.2/package/yast2-s390.spec --- old/yast2-s390-4.6.1/package/yast2-s390.spec 2023-05-10 17:09:12.000000000 +0200 +++ new/yast2-s390-4.6.2/package/yast2-s390.spec 2023-06-09 11:19:12.000000000 +0200 @@ -17,7 +17,7 @@ Name: yast2-s390 -Version: 4.6.1 +Version: 4.6.2 Release: 0 Group: System/YaST License: GPL-2.0-only diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-s390-4.6.1/src/lib/y2s390/zfcp.rb new/yast2-s390-4.6.2/src/lib/y2s390/zfcp.rb --- old/yast2-s390-4.6.1/src/lib/y2s390/zfcp.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-s390-4.6.2/src/lib/y2s390/zfcp.rb 2023-06-09 11:19:12.000000000 +0200 @@ -0,0 +1,183 @@ +# Copyright (c) [2023] SUSE LLC +# +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, contact SUSE LLC. +# +# To contact SUSE LLC about this file by physical or electronic mail, you may +# find current contact information at www.suse.com. + +require "yast" +require "yaml" + +module Y2S390 + # Manager for zFCP devices + class ZFCP + include Yast + include Yast::Logger + + # Detected controllers + # + # @return [Array<Hash>] keys for each hash: + # "sysfs_bus_id", "resource" + attr_reader :controllers + + # Detected LUN disks + # + # @return [Array<Hash>] keys for each hash: + # "dev_name", "detail", "vendor", "device" and "io". + attr_reader :disks + + def initialize + @controllers = [] + @disks = [] + end + + # Probes the zFCP controllers + def probe_controllers + make_all_devices_visible + + storage_devices = Yast::SCR.Read(path(".probe.storage")) + controllers = storage_devices.select { |i| i["device"] == "zFCP controller" } + + @controllers = controllers.map { |c| c.slice("sysfs_bus_id", "resource") } + end + + # Probes the zFCP disks + def probe_disks + storage_disks = read_mock_disks || Yast::SCR.Read(path(".probe.disk")) + zfcp_disks = storage_disks.select { |d| d["driver"] == "zfcp" } + + tapes = Yast::SCR.Read(path(".probe.tape")) + scsi_tapes = tapes.select { |t| t["bus"] == "SCSI" } + + disks = zfcp_disks + scsi_tapes + + @disks = disks.map { |d| d.slice("dev_name", "detail", "vendor", "device", "io") } + end + + # Runs the command for activating a controller + # + # @note All LUNs are automatically activated if "allow_lun_scan" is active, see + # https://www.ibm.com/docs/en/linux-on-systems?topic=wsd-configuring-devices. + # + # @param channel [String] E.g., "0.0.fa00" + # @return [Hash] See {#run}. The exit code corresponds to the chzdev one. + def activate_controller(channel) + command = format("/sbin/zfcp_host_configure '%s' %d", channel, 1) + run(command) + end + + # Whether the controller is activated + # + # @param channel [String] E.g., "0.0.fa00" + # @return [Boolean] + def activated_controller?(channel) + controller = controllers.find { |c| c["sysfs_bus_id"] == channel } + return false unless controller + + io = controller.dig("resource", "io") || [] + io.any? { |i| i["active"] } + end + + # Runs the command for activating a zFCP disk + # + # @param channel [String] E.g., "0.0.fa00" + # @param wwpn [String] E.g., "0x500507630708d3b3" + # @param lun [String] E.g., "0x0013000000000000" + # + # @return [Hash] See {#run}. The exit code corresponds to the chzdev one. + def activate_disk(channel, wwpn, lun) + command = format("/sbin/zfcp_disk_configure '%s' '%s' '%s' %d", channel, wwpn, lun, 1) + run(command) + end + + # Runs the command for deactivating a zFCP disk + # + # @note Deactivate fails if "allow_lun_scan" is active, see + # https://www.ibm.com/docs/en/linux-on-systems?topic=wsd-configuring-devices. + # + # @param channel [String] E.g., "0.0.fa00" + # @param wwpn [String] E.g., "0x500507630708d3b3" + # @param lun [String] E.g., "0x0013000000000000" + # + # @return [Hash] See {#run}. The exit code corresponds to the chzdev one. + def deactivate_disk(channel, wwpn, lun) + command = format("/sbin/zfcp_disk_configure '%s' '%s' '%s' %d", channel, wwpn, lun, 0) + run(command) + end + + # Runs the command for finding WWPNs + # + # @param channel [String] E.g., "0.0.fa00" + # @return [Hash] See {#run} + def find_wwpns(channel) + command = format("zfcp_san_disc -b '%s' -W", channel) + run(command) + end + + # Runs the command for finding LUNs + # + # @param channel [String] E.g., "0.0.fa00" + # @param wwpn [String] E.g., "0x500507630708d3b3" + # + # @return [Hash] See {#run} + def find_luns(channel, wwpn) + command = format("zfcp_san_disc -b '%s' -p '%s' -L", channel, wwpn) + run(command) + end + + private + + # Sets all detected controllers as visible + def make_all_devices_visible + # Checking if it is a z/VM and evaluating all FCP controllers in order to activate + output = run("/sbin/vmcp q v fcp") + return if output["exit"] != 0 + + fcp_lines = output["stdout"].map(&:split).select { |l| l.first == "FCP" } + devices = fcp_lines.map { |l| l[1].downcase } + + # Remove all needed devices from CIO device driver blacklist in order to see it + devices.each do |device| + log.info "Removing #{device} from the CIO device driver blacklist" + run("/sbin/cio_ignore -r #{device}") + end + end + + # Runs the given command + # + # @param command [String] + # @return [Hash] Output of the command which has these keys: "exit", "stdout", "stderr". + def run(command) + Yast::SCR.Execute(path(".target.bash_output"), command).tap do |output| + log.info("command #{command} output #{output}") + + output["exit"] = output["exit"].to_i + output["stdout"] = output["stdout"].split("\n").reject(&:empty?) + end + end + + # Reads the mock disks from the YAML file pointed by YAST2_S390_PROBE_DISK + # + # Suggestion: YAST2_S390_PROBE_DISK=test/data/probe_disk.yml rake run[zfcp] + # + # @return [Array<Hash>, nil] List of mocked LUN disks or nil if no file found + def read_mock_disks + mock_filename = ENV["YAST2_S390_PROBE_DISK"] + return nil unless mock_filename + + YAML.safe_load(File.read(mock_filename)) + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-s390-4.6.1/src/modules/ZFCPController.rb new/yast2-s390-4.6.2/src/modules/ZFCPController.rb --- old/yast2-s390-4.6.1/src/modules/ZFCPController.rb 2023-05-10 17:09:12.000000000 +0200 +++ new/yast2-s390-4.6.2/src/modules/ZFCPController.rb 2023-06-09 11:19:12.000000000 +0200 @@ -29,6 +29,7 @@ require "yaml" require "yast" +require "y2s390/zfcp" module Yast class ZFCPControllerClass < Module @@ -43,6 +44,8 @@ Yast.import "Popup" Yast.import "Arch" + @zfcp = Y2S390::ZFCP.new + @devices = {} @filter_min = "0.0.0000" @@ -50,7 +53,9 @@ @previous_settings = {} - @controllers = nil + @probed_controllers = false + + @probed_disks = false @activated_controllers = nil @@ -296,49 +301,22 @@ # Get available zfcp controllers # @return [Array<Hash{String => Object>}] of availabel Controllers def GetControllers - if @controllers.nil? - # Checking if it is a z/VM and evaluating all fcp controllers in - # order to activate - ret_vmcp = SCR.Execute(path(".target.bash_output"), "/sbin/vmcp q v fcp") - if ret_vmcp["exit"] == 0 - devices = ret_vmcp["stdout"].split("\n").collect do |line| - columns = line.split - columns[1].downcase if columns[0] == "FCP" - end.compact - - # Remove all needed devices from CIO device driver blacklist - # in order to see it - devices.each do |device| - log.info "Removing #{device} from the CIO device driver blacklist" - SCR.Execute(path(".target.bash"), "/sbin/cio_ignore -r #{device}") - end - end - - @controllers = Convert.convert( - SCR.Read(path(".probe.storage")), - from: "any", - to: "list <map <string, any>>" - ) - @controllers = Builtins.filter(@controllers) do |c| - Ops.get_string(c, "device", "") == "zFCP controller" - end - - @controllers = Builtins.maplist(@controllers) do |c| - Builtins.filter(c) do |k, _v| - Builtins.contains(["sysfs_bus_id", "resource"], k) - end - end + if !@probed_controllers + zfcp.probe_controllers # zKVM uses virtio devices instead of ZFCP, skip the warning in that case - if ret_vmcp != 0 && @controllers.empty? && !Arch.is_zkvm + if zfcp.controllers.none? && !Arch.is_zkvm # TRANSLATORS: warning message Report.Warning(_("Cannot evaluate ZFCP controllers (e.g. in LPAR).\n" \ "You will have to set it manually.")) end - Builtins.y2milestone("probed ZFCP controllers %1", @controllers) + Builtins.y2milestone("probed ZFCP controllers %1", zfcp.controllers) + + @probed_controllers = true end - deep_copy(@controllers) + + zfcp.controllers end # Check if ZFCP subsystem is available @@ -541,21 +519,11 @@ def activate_controller(channel) return if activated_controller?(channel) - command2 = Builtins.sformat( - "/sbin/zfcp_host_configure '%1' %2", - channel, - 1 - ) - Builtins.y2milestone("Running command \"%1\"", command2) - ret2 = Convert.to_integer(SCR.Execute(path(".target.bash"), command2)) - Builtins.y2milestone( - "Command \"%1\" returned with exit code %2", - command2, - ret2 - ) + output = zfcp.activate_controller(channel) + exit_code = output["exit"] - if ret2 != 0 - ReportControllerActivationError(channel, ret2) + if exit_code != 0 + ReportControllerActivationError(channel, exit_code) else register_as_activated(channel) end @@ -574,22 +542,8 @@ end if disk.nil? && (wwpn != "" || lun != "") # we are not using allow_lun_scan - command = Builtins.sformat( - "/sbin/zfcp_disk_configure '%1' '%2' '%3' %4", - channel, - wwpn, - lun, - 1 - ) - Builtins.y2milestone("Running command \"%1\"", command) - ret = Convert.to_integer(SCR.Execute(path(".target.bash"), command)) - Builtins.y2milestone( - "Command \"%1\" returned with exit code %2", - command, - ret - ) - - ReportActivationError(channel, ret) + output = zfcp.activate_disk(channel, wwpn, lun) + ReportActivationError(channel, output["exit"]) end @disk_configured = true @@ -602,58 +556,26 @@ # @param [String] wwpn string wwpn (hexa number) # @param [String] lun string lun (hexa number) def DeactivateDisk(channel, wwpn, lun) - command = Builtins.sformat( - "/sbin/zfcp_disk_configure '%1' '%2' '%3' %4", - channel, - wwpn, - lun, - 0 - ) - Builtins.y2milestone("Running command \"%1\"", command) - ret = Convert.to_integer(SCR.Execute(path(".target.bash"), command)) - Builtins.y2milestone( - "Command \"%1\" returned with exit code %2", - command, - ret - ) - - ReportActivationError(channel, ret) + output = zfcp.deactivate_disk(channel, wwpn, lun) + ReportActivationError(channel, output["exit"]) @disk_configured = true nil end - def runCommand(cmd) - ret = [] - cmd_output = Convert.convert( - SCR.Execute(path(".target.bash_output"), cmd), - from: "any", - to: "map <string, any>" - ) - if Ops.get_integer(cmd_output, "exit", -1) == 0 - ret = Builtins.splitstring( - Ops.get_string(cmd_output, "stdout", ""), - "\n" - ) - ret = Builtins.filter(ret) do |row| - Ops.greater_than(Builtins.size(row), 0) - end - else - Popup.Error(Ops.get_string(cmd_output, "stderr", "")) - end - Builtins.y2milestone("command %1, output %2", cmd, cmd_output) - deep_copy(ret) + def command_result(output) + return output["stdout"] if output["exit"] == 0 + + Popup.Error(output["stderr"]) end def GetWWPNs(busid) - runCommand(Builtins.sformat("zfcp_san_disc -b '%1' -W", busid)) + command_result(zfcp.find_wwpns(busid)) end def GetLUNs(busid, wwpn) - runCommand( - Builtins.sformat("zfcp_san_disc -b '%1' -p '%2' -L", busid, wwpn) - ) + command_result(zfcp.find_luns(busid, wwpn)) end publish variable: :devices, type: "map <integer, map <string, any>>" @@ -692,20 +614,7 @@ private - # In production, call SCR.Read(.probe.disk). - # For testing, point YAST2_S390_PROBE_DISK to a YAML file - # with the mock value. - # Suggesstion: - # YAST2_S390_PROBE_DISK=test/data/probe_disk.yml rake run"[zfcp]" - # @return [Array<Hash>] .probe.disk output - def probe_or_mock_disks - mock_filename = ENV["YAST2_S390_PROBE_DISK"] - if mock_filename - YAML.safe_load(File.read(mock_filename)) - else - SCR.Read(path(".probe.disk")) - end - end + attr_reader :zfcp # Finds the activated controllers # @@ -715,12 +624,11 @@ def activated_controllers return @activated_controllers if @activated_controllers - ctrls = GetControllers().select do |ctrl| - io = ctrl.fetch("resource", {}).fetch("io", []) - io.any? { |i| i["active"] } - end - log.info "Already activated controllers: #{ctrls}" - @activated_controllers = ctrls.map { |c| c["sysfs_bus_id"] } + channels = GetControllers().map { |c| c["sysfs_bus_id"] } + active_channels = channels.select { |c| zfcp.activated_controller?(c) } + + log.info "Already activated controllers: #{active_channels}" + @activated_controllers = active_channels end # Mark a controller as activated @@ -745,42 +653,12 @@ # @param force_probing [Boolean] Ignore the cached values and probes again. # @return [Array<Hash>] Found zFCP disks def find_disks(force_probing: false) - return @disks if @disks && !force_probing - - disks = probe_or_mock_disks - disks = Builtins.filter(disks) do |d| - d["driver"] == "zfcp" - end - - tapes = Convert.convert( - SCR.Read(path(".probe.tape")), - from: "any", - to: "list <map <string, any>>" - ) - tapes = Builtins.filter(tapes) do |d| - Ops.get_string(d, "bus", "") == "SCSI" - end - - disks_tapes = Convert.convert( - Builtins.merge(disks, tapes), - from: "list", - to: "list <map <string, any>>" - ) - - @disks = Builtins.maplist(disks_tapes) do |d| - Builtins.filter(d) do |k, _v| - Builtins.contains(["dev_name", "detail", "vendor", "device", "io"], k) - end + if !@probed_disks || force_probing + zfcp.probe_disks + @probed_disks = true end - end - # Determines whether the disk is activated or not - # - # @param disk [Hash] - # @return [Boolean] - def active_disk?(disk) - io = disk.fetch("resource", {}).fetch("io", []).first - !!(io && io["active"]) + zfcp.disks end # Finds a disk diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-s390-4.6.1/test/y2s390/zfcp_test.rb new/yast2-s390-4.6.2/test/y2s390/zfcp_test.rb --- old/yast2-s390-4.6.1/test/y2s390/zfcp_test.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-s390-4.6.2/test/y2s390/zfcp_test.rb 2023-06-09 11:19:12.000000000 +0200 @@ -0,0 +1,244 @@ +#!/usr/bin/env rspec + +# Copyright (c) [2023] SUSE LLC +# +# All Rights Reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of version 2 of the GNU General Public License as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, contact SUSE LLC. +# +# To contact SUSE LLC about this file by physical or electronic mail, you may +# find current contact information at www.suse.com. + +require_relative "../test_helper" +require "y2s390/zfcp" + +describe Y2S390::ZFCP do + describe "#probe_controllers" do + before do + allow(Yast::SCR).to receive(:Read).with(Yast.path(".probe.storage")) + .and_return(controllers_data) + + allow(Yast::SCR).to receive(:Execute).with(anything, /\/sbin\/vmcp q v fcp/) + .and_return(vmcp_output) + + allow(Yast::SCR).to receive(:Execute).with(anything, /\/sbin\/cio_ignore -r/) + .and_return("exit" => 0, "stdout" => "") + end + + let(:controllers_data) { load_data("probe_storage.yml") } + + let(:vmcp_output) do + { + "exit" => 0, + "stdout" => "FCP F800 ON FCP F807 CHPID 1C SUBCHANNEL = 000B\n" \ + "F800 TOKEN = 0000000362A42C00" + } + end + + it "removes all FCP devices from the blacklist" do + expect(Yast::SCR).to receive(:Execute).with(anything, /\/sbin\/cio_ignore -r f800/) + + subject.probe_controllers + end + + it "reads all the zFCP controllers" do + expect(subject.controllers).to eq([]) + + subject.probe_controllers + + expect(subject.controllers).to contain_exactly( + hash_including("sysfs_bus_id" => "0.0.f800"), + hash_including("sysfs_bus_id" => "0.0.f900"), + hash_including("sysfs_bus_id" => "0.0.fa00"), + hash_including("sysfs_bus_id" => "0.0.fc00") + ) + end + end + + describe "#probe_disks" do + before do + allow(Yast::SCR).to receive(:Read).with(Yast.path(".probe.disk")) + .and_return(disks_data) + + allow(Yast::SCR).to receive(:Read).with(Yast.path(".probe.tape")).and_return([]) + end + + let(:disks_data) { load_data("probe_disk.yml") } + + it "reads all the zFCP disks" do + expect(subject.disks).to eq([]) + + subject.probe_disks + + expect(subject.disks).to contain_exactly( + hash_including("dev_name" => "/dev/sda"), + hash_including("dev_name" => "/dev/sdb") + ) + end + end + + describe "#activate_controller" do + before do + allow(Yast::SCR).to receive(:Execute).with(anything, command).and_return(output) + end + + let(:command) { /\/sbin\/zfcp_host_configure '0.0.fc00' 1/ } + + let(:output) { { "exit" => 0, "stdout" => "" } } + + it "tries to activate the given controller" do + expect(Yast::SCR).to receive(:Execute).with(anything, command) + + subject.activate_controller("0.0.fc00") + end + + it "returns the output of the command" do + result = subject.activate_controller("0.0.fc00") + + expect(result).to eq(output) + end + end + + describe "#activated_controller?" do + before do + allow(subject).to receive(:controllers).and_return(controllers) + end + + let(:controllers) do + [ + { + "sysfs_bus_id" => "0.0.fa00", + "resource" => { "io" => [{ "active" => true }] } + }, + { + "sysfs_bus_id" => "0.0.fc00", + "resource" => { "io" => [{ "active" => false }] } + } + ] + end + + context "if the given controller is activated" do + let(:channel) { "0.0.fa00" } + + it "returns true" do + expect(subject.activated_controller?(channel)).to eq(true) + end + end + + context "if the given controller is not activated" do + let(:channel) { "0.0.fc00" } + + it "returns false" do + expect(subject.activated_controller?(channel)).to eq(false) + end + end + end + + describe "#activate_disk" do + before do + allow(Yast::SCR).to receive(:Execute).with(anything, command).and_return(output) + end + + let(:command) do + /\/sbin\/zfcp_disk_configure '0.0.fc00' '0x500507630708d3b3' '0x0000000000000005' 1/ + end + + let(:output) { { "exit" => 1, "stdout" => "An error" } } + + it "tries to activate a zFCP disk" do + expect(Yast::SCR).to receive(:Execute).with(anything, command) + + subject.activate_disk("0.0.fc00", "0x500507630708d3b3", "0x0000000000000005") + end + + it "returns the output of the command" do + result = subject.activate_disk("0.0.fc00", "0x500507630708d3b3", "0x0000000000000005") + + expect(result).to eq(output) + end + end + + describe "#deactivate_disk" do + before do + allow(Yast::SCR).to receive(:Execute).with(anything, command).and_return(output) + end + + let(:command) do + /\/sbin\/zfcp_disk_configure '0.0.fc00' '0x500507630708d3b3' '0x0000000000000005' 0/ + end + + let(:output) { { "exit" => 0, "stdout" => "" } } + + it "tries to deactivate a zFCP disk" do + expect(Yast::SCR).to receive(:Execute).with(anything, command) + + subject.deactivate_disk("0.0.fc00", "0x500507630708d3b3", "0x0000000000000005") + end + + it "returns the output of the command" do + result = subject.deactivate_disk("0.0.fc00", "0x500507630708d3b3", "0x0000000000000005") + + expect(result).to eq(output) + end + end + + describe "#find_wwpns" do + before do + allow(Yast::SCR).to receive(:Execute).with(anything, command).and_return(output) + end + + let(:command) { /zfcp_san_disc -b '0.0.fc00' -W/ } + + let(:output) { { "exit" => 0, "stdout" => "0x500507630703d3b3\n0x500507630708d3b3" } } + + it "runs the command for finding WWPNs" do + expect(Yast::SCR).to receive(:Execute).with(anything, command) + + subject.find_wwpns("0.0.fc00") + end + + it "returns the output of the command" do + result = subject.find_wwpns("0.0.fc00") + + expect(result).to eq( + "exit" => 0, + "stdout" => ["0x500507630703d3b3", "0x500507630708d3b3"] + ) + end + end + + describe "#find_luns" do + before do + allow(Yast::SCR).to receive(:Execute).with(anything, command).and_return(output) + end + + let(:command) { /zfcp_san_disc -b '0.0.fc00' -p '0x500507630708d3b3' -L/ } + + let(:output) { { "exit" => 0, "stdout" => "0x0000000000000005\n0x0000000000000006" } } + + it "runs the command for finding LUNs" do + expect(Yast::SCR).to receive(:Execute).with(anything, command) + + subject.find_luns("0.0.fc00", "0x500507630708d3b3") + end + + it "returns the output of the command" do + result = subject.find_luns("0.0.fc00", "0x500507630708d3b3") + + expect(result).to eq( + "exit" => 0, + "stdout" => ["0x0000000000000005", "0x0000000000000006"] + ) + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-s390-4.6.1/test/zfcp_controller_test.rb new/yast2-s390-4.6.2/test/zfcp_controller_test.rb --- old/yast2-s390-4.6.1/test/zfcp_controller_test.rb 2023-05-10 17:09:12.000000000 +0200 +++ new/yast2-s390-4.6.2/test/zfcp_controller_test.rb 2023-06-09 11:19:12.000000000 +0200 @@ -23,7 +23,7 @@ expect(subject).to receive(:activate_controller).with("0.0.fa00") expect(Yast::SCR).to receive(:Execute) .with(anything, /\/sbin\/zfcp_disk_configure '0.0.fa00' '0x500\d+' '0x401\d+' 1/) - .and_return(0) + .and_return("exit" => "0", "stdout" => "") subject.ActivateDisk("0.0.fa00", "0x5000000000000000", "0x4010400000000000") end @@ -49,27 +49,31 @@ "exit" => 0, "stdout" => "FCP F800 ON FCP F807 CHPID 1C SUBCHANNEL = 000B\n F800 TOKEN = 0000000362A42C00" ) - allow(Yast::SCR).to receive(:Execute).with(anything, /\/sbin\/cio_ignore -r f800/).and_return(0) + allow(Yast::SCR).to receive(:Execute).with(anything, /\/sbin\/cio_ignore -r f800/) + .and_return("exit" => "0", "stdout" => "") end it "activates the given controller" do - expect(Yast::SCR).to receive(:Execute) - .with(anything, /\/sbin\/zfcp_host_configure '0.0.fc00' 1/).and_return(0) + expect(Yast::SCR) + .to receive(:Execute).with(anything, /\/sbin\/zfcp_host_configure '0.0.fc00' 1/) + .and_return("exit" => "0", "stdout" => "") expect(subject).to_not receive(:ReportControllerActivationError) subject.activate_controller(channel) end it "does not activate a controller twice" do - expect(Yast::SCR).to receive(:Execute) - .with(anything, /\/sbin\/zfcp_host_configure '0.0.fc00' 1/).once.and_return(0) + expect(Yast::SCR) + .to receive(:Execute).with(anything, /\/sbin\/zfcp_host_configure '0.0.fc00' 1/).once + .and_return("exit" => "0", "stdout" => "") subject.activate_controller(channel) subject.activate_controller(channel) end context "when the activation fails" do before do - allow(Yast::SCR).to receive(:Execute) - .with(anything, /\/sbin\/zfcp_host_configure '0.0.fc00' 1/).and_return(1) + allow(Yast::SCR) + .to receive(:Execute).with(anything, /\/sbin\/zfcp_host_configure '0.0.fc00' 1/) + .and_return("exit" => "1", "stdout" => "") end it "reports the error" do @@ -105,7 +109,9 @@ "exit" => 0, "stdout" => "FCP F800 ON FCP F807 CHPID 1C SUBCHANNEL = 000B\n F800 TOKEN = 0000000362A42C00" ) - expect(Yast::SCR).to receive(:Execute).with(anything, /\/sbin\/cio_ignore -r f800/).and_return(0) + expect(Yast::SCR) + .to receive(:Execute).with(anything, /\/sbin\/cio_ignore -r f800/) + .and_return("exit" => "0", "stdout" => "") ctrls = subject.GetControllers expect(ctrls).to contain_exactly(