From e1b679724935604b8b9f30828f7a1e8ff07f5478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Ferr=C3=A3o?= <2031761+viniciusferrao@users.noreply.github.com> Date: Sun, 6 Sep 2026 00:26:17 -0300 Subject: [PATCH] test(genesis): cover s390x qeth activation --- xCAT-test/unit/genesis_openembedded_qeth.t | 256 +++++++++++++++++++++ 1 file changed, 256 insertions(+) create mode 100644 xCAT-test/unit/genesis_openembedded_qeth.t diff --git a/xCAT-test/unit/genesis_openembedded_qeth.t b/xCAT-test/unit/genesis_openembedded_qeth.t new file mode 100644 index 000000000..a0203efdf --- /dev/null +++ b/xCAT-test/unit/genesis_openembedded_qeth.t @@ -0,0 +1,256 @@ +#!/usr/bin/env perl +use strict; +use warnings; + +use File::Path qw(make_path); +use File::Spec; +use File::Temp qw(tempdir); +use FindBin; +use Test::More; + +my $repo_root = File::Spec->catdir( $FindBin::Bin, '..', '..' ); +my $qeth_dir = File::Spec->catdir( + $repo_root, + qw(xCAT-genesis-builder oe meta-xcat-genesis recipes-connectivity xcat-genesis-qeth) +); +my $qeth_script = File::Spec->catfile( $qeth_dir, qw(files genesis-qeth) ); +my $qeth_service = File::Spec->catfile( $qeth_dir, qw(files xcat-genesis-qeth.service) ); +my $qeth_recipe = File::Spec->catfile( $qeth_dir, 'xcat-genesis-qeth_1.0.bb' ); +my $s390_tools_recipe = File::Spec->catfile( + $repo_root, + qw(xCAT-genesis-builder oe meta-xcat-genesis recipes-support s390-tools + s390-tools-znetconf_2.41.0.bb) +); + +sub write_file { + my ( $path, $contents, $mode ) = @_; + open( my $fh, '>', $path ) or die "Unable to write $path: $!"; + print {$fh} $contents; + close($fh); + chmod( $mode, $path ) if defined($mode); +} + +sub read_file { + my ($path) = @_; + open( my $fh, '<', $path ) or die "Unable to read $path: $!"; + my $contents = do { local $/; <$fh> }; + close($fh); + return $contents; +} + +my $root = tempdir( CLEANUP => 1 ); +my $bin = File::Spec->catdir( $root, 'bin' ); +my $cmdline = File::Spec->catfile( $root, 'cmdline' ); +my $configured = File::Spec->catfile( $root, 'configured' ); +my $unconfigured = File::Spec->catfile( $root, 'unconfigured' ); +my $command_log = File::Spec->catfile( $root, 'commands.log' ); +my $znetconf = File::Spec->catfile( $bin, 'znetconf' ); +my $status = File::Spec->catfile( $bin, 'genesis-status' ); + +make_path($bin); +write_file( + $znetconf, + <<'SH', 0755 +#!/bin/sh +printf 'znetconf %s\n' "$*" >>"$XCAT_TEST_LOG" +case "$1" in + -c) + cat "$XCAT_TEST_CONFIGURED" + exit "${XCAT_TEST_CONFIGURED_STATUS:-0}" + ;; + -u) + cat "$XCAT_TEST_UNCONFIGURED" + exit "${XCAT_TEST_UNCONFIGURED_STATUS:-0}" + ;; + -a) + [ "${XCAT_TEST_FAIL_CHANNELS:-}" != "$2" ] + ;; +esac +SH +); +write_file( + $status, + <<'SH', 0755 +#!/bin/sh +printf 'status %s\n' "$*" >>"$XCAT_TEST_LOG" +SH +); +write_file( + File::Spec->catfile( $bin, 'logger' ), + <<'SH', 0755 +#!/bin/sh +printf 'logger %s\n' "$*" >>"$XCAT_TEST_LOG" +SH +); + +my %base_environment = ( + PATH => "$bin:$ENV{PATH}", + XCAT_CMDLINE_FILE => $cmdline, + XCAT_STATUS_COMMAND => $status, + XCAT_TEST_CONFIGURED => $configured, + XCAT_TEST_LOG => $command_log, + XCAT_TEST_UNCONFIGURED => $unconfigured, + XCAT_ZNETCONF_COMMAND => $znetconf, +); + +sub run_qeth { + my ( $command_line, $environment ) = @_; + write_file( $cmdline, "$command_line\n" ); + write_file( $command_log, '' ); + write_file( $configured, $environment->{XCAT_TEST_CONFIGURED_OUTPUT} // '' ); + write_file( $unconfigured, $environment->{XCAT_TEST_UNCONFIGURED_OUTPUT} // '' ); + local %ENV = ( %ENV, %base_environment, %{$environment} ); + return system( '/bin/bash', $qeth_script ) >> 8; +} + +sub command_log { + return read_file($command_log); +} + +is( + run_qeth( 'console=ttysclp0 xcatd=192.0.2.1', + { XCAT_TEST_UNCONFIGURED_STATUS => 31 } ), + 0, + 'a system without ccwgroup devices needs no qeth setup' +); +unlike( command_log(), qr/^znetconf -a /m, 'the no-device path activates nothing' ); + +is( + run_qeth( + 'console=ttysclp0 xcatd=192.0.2.1', + { + XCAT_TEST_CONFIGURED_OUTPUT => + "0.0.0500,0.0.0501,0.0.0502 1731/01 OSA 10 qeth enc500 online\n" + } + ), + 0, + 'firmware-configured qeth devices need no activation' +); +unlike( command_log(), qr/^znetconf -a /m, 'firmware-configured devices are unchanged' ); + +is( + run_qeth( + 'rd.znet=qeth,0600,0.0.0601,0.0.0602,portno=1 xcatd=192.0.2.1', {} + ), + 0, + 'an explicit qeth triplet is accepted' +); +like( + command_log(), + qr/^znetconf -a 0\.0\.0600,0\.0\.0601,0\.0\.0602 -d qeth -o portno=1 -o layer2=1$/m, + 'explicit channels are normalized and default to layer 2' +); +like( command_log(), qr/^status network CONFIGURING_NETWORK qeth devices are ready$/m, + 'successful activation is published' ); + +is( + run_qeth( + 'rd.znet=qeth,0.0.0610,0.0.0611,0.0.0612,layer2=0,portname=test ' + . 'xcatd=192.0.2.1', + {} + ), + 0, + 'explicit qeth options are accepted' +); +like( + command_log(), + qr/^znetconf -a 0\.0\.0610,0\.0\.0611,0\.0\.0612 -d qeth -o layer2=0 -o portname=test$/m, + 'an explicit layer setting is not overridden' +); + +my $configured_channels = '0.0.0620,0.0.0621,0.0.0622'; +is( + run_qeth( + "rd.znet=qeth,$configured_channels xcatd=192.0.2.1", + { XCAT_TEST_CONFIGURED_OUTPUT => "$configured_channels 1731/01 OSA 10 qeth enc600 online\n" } + ), + 0, + 'an already configured triplet is left unchanged' +); +unlike( command_log(), qr/^znetconf -a /m, 'configured qeth channels are not regrouped' ); + +my $automatic_channels = '0.0.0700,0.0.0701,0.0.0702'; +is( + run_qeth( + 'xcatd=192.0.2.1', + { + XCAT_TEST_UNCONFIGURED_OUTPUT => + "Scanning for network devices...\n" + . "Device IDs Type Card Type CHPID Drv.\n" + . "0.0.0710,0.0.0711 3088/60 LCS OSA 20 lcs\n" + . "$automatic_channels 1731/01 OSA (QDIO) 10 qeth\n" + } + ), + 0, + 'unconfigured qeth devices are discovered' +); +like( + command_log(), + qr/^znetconf -a \Q$automatic_channels\E -d qeth -o layer2=1$/m, + 'discovered qeth devices are activated for DHCP' +); +unlike( command_log(), qr/^znetconf -a 0\.0\.0710/m, + 'other channel network types are not activated as qeth' ); + +is( + run_qeth( 'xcatd=192.0.2.1', { XCAT_TEST_UNCONFIGURED_STATUS => 9 } ), + 9, + 'a qeth discovery error is returned' +); +like( command_log(), qr/^status network DEGRADED Unable to inspect qeth devices/m, + 'a discovery error is published' ); + +is( + run_qeth( + 'rd.znet=ctc,0.0.0800,0.0.0801 xcatd=192.0.2.1', + { XCAT_TEST_UNCONFIGURED_OUTPUT => "$automatic_channels 1731/01 OSA 10 qeth\n" } + ), + 0, + 'a non-qeth rd.znet entry is not handled' +); +unlike( command_log(), qr/^znetconf -u$/m, 'explicit non-qeth setup disables qeth discovery' ); +unlike( command_log(), qr/^znetconf -a /m, 'non-qeth channels are not activated as qeth' ); + +is( + run_qeth( 'rd.znet=qeth,0.0.0900,0.0.0901 xcatd=192.0.2.1', {} ), + 1, + 'an incomplete qeth triplet fails' +); +like( command_log(), qr/^status network DEGRADED One or more qeth devices/m, + 'invalid boot parameters publish a degraded status' ); + +is( + run_qeth( + 'rd.znet=qeth,0.0.0910,0.0.0911,0.0.0912,bad?=1 xcatd=192.0.2.1', {} + ), + 1, + 'an invalid qeth option fails' +); +unlike( command_log(), qr/^znetconf -a /m, 'invalid options are rejected before activation' ); + +is( + run_qeth( + 'rd.znet=qeth,0.0.0a00,0.0.0a01,0.0.0a02 ' + . 'rd.znet=qeth,0.0.0b00,0.0.0b01,0.0.0b02 xcatd=192.0.2.1', + { XCAT_TEST_FAIL_CHANNELS => '0.0.0a00,0.0.0a01,0.0.0a02' } + ), + 1, + 'failure of one qeth triplet is reported' +); +like( command_log(), qr/^znetconf -a 0\.0\.0b00,0\.0\.0b01,0\.0\.0b02 /m, + 'remaining qeth triplets are still attempted' ); + +my $service_contents = read_file($qeth_service); +like( $service_contents, qr/^ConditionArchitecture=s390x$/m, + 'the activation service is limited to s390x' ); +like( $service_contents, qr/^ConditionKernelCommandLine=xcatd$/m, + 'the activation service requires a Genesis boot' ); +like( $service_contents, qr/^Before=.*\bNetworkManager\.service\b/m, + 'qeth activation precedes NetworkManager' ); +like( $service_contents, qr/^Before=.*\bxcat-genesis-network-state\.service\b/m, + 'qeth activation precedes management network selection' ); + +ok( -f $qeth_recipe, 'the qeth service has an OpenEmbedded recipe' ); +ok( -f $s390_tools_recipe, 'the minimal znetconf package has an OpenEmbedded recipe' ); + +done_testing();