mirror of
https://github.com/xcat2/xcat-core.git
synced 2026-09-21 16:39:30 +00:00
test(xcat-core): the machine-type test is written as a Perl program
diskless_flat_vmothersetting_machine.t measures shell. It lifts two commands out of reg_linux_diskless_installation_flat, renders the xcattest placeholders, writes a wrapper that shadows lsdef and chdef, and shells out. The Perl adds nothing the shell cannot state, and the case file it reads is shell itself. The test moves to xCAT-test/bats, which the xcat_test workflow already runs. It keeps what it proved: on ppc64le, x86_64 and riscv64 the restore writes a machine type rather than an empty vmothersetting, the check that follows it passes, and the remove path compares two defined strings. A command that stops matching fails the test instead of covering nothing. Signed-off-by: Daniel Hilst <392820+dhilst@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env bats
|
||||
#
|
||||
# reg_linux_diskless_installation_flat corrupts the KVM machine type of the compute node, checks
|
||||
# that the node fails to boot, and then restores it. The restore reads a machine type from a
|
||||
# ladder that names ppc64 and x86_64 only, so on any other architecture it writes an empty
|
||||
# vmothersetting and the check after it fails.
|
||||
#
|
||||
# The two commands are lifted out of the case file and RUN, with lsdef and chdef shadowed, so
|
||||
# the assertions read the value the case would write. The extraction fails the test when it
|
||||
# stops matching, so a rewrite fails loudly instead of covering nothing.
|
||||
|
||||
load 'helpers/shell_source'
|
||||
|
||||
setup()
|
||||
{
|
||||
CASE="$(repo_path 'xCAT-test/autotest/testcase/installation/reg_linux_diskless_installation_flat')"
|
||||
[ -r "$CASE" ] || skip "$CASE is required"
|
||||
export CASE
|
||||
}
|
||||
|
||||
# The command that restores the machine type, and the one that removes it again afterwards.
|
||||
restore_command()
|
||||
{
|
||||
extract_first_matching_line "$CASE" \
|
||||
'^cmd:.*str2="machine:invalid".*chdef [$][$]CN vmothersetting=[$]str5'
|
||||
}
|
||||
|
||||
remove_command()
|
||||
{
|
||||
extract_first_matching_line "$CASE" \
|
||||
'^cmd:.*str2=";".*~ "ppc64".*chdef [$][$]CN vmothersetting='
|
||||
}
|
||||
|
||||
# Render one command the way xcattest does, then run it with lsdef and chdef shadowed. bash
|
||||
# resolves a function ahead of PATH, so the case's own backticks read the stub.
|
||||
#
|
||||
# Sets OUT to everything the command printed and WRITTEN to the value it gave chdef.
|
||||
run_case_command()
|
||||
{
|
||||
local cmd="$1" arch="$2" lsdef_value="$3"
|
||||
|
||||
cmd="${cmd#cmd:}"
|
||||
cmd="${cmd//__GETNODEATTR(\$\$CN,arch)__/$arch}"
|
||||
cmd="${cmd//__GETNODEATTR(\$\$CN,mgt)__/kvm}"
|
||||
cmd="${cmd//\$\$CN/cn1}"
|
||||
|
||||
OUT="$(bash -c "lsdef() { echo ' vmothersetting=$lsdef_value'; }
|
||||
chdef() { echo \"CHDEF:\$*\"; }
|
||||
$cmd" 2>&1)" || true
|
||||
WRITTEN="$(sed -n 's/^CHDEF:cn1 vmothersetting=//p' <<<"$OUT")"
|
||||
}
|
||||
|
||||
# The machine type each architecture must end up with. riscv64 guests run the qemu "virt"
|
||||
# machine; kvm.pm sets it in guest_arch_profile.
|
||||
assert_arch()
|
||||
{
|
||||
local arch="$1" machine="$2" restore remove
|
||||
|
||||
restore="$(restore_command)"
|
||||
remove="$(remove_command)"
|
||||
|
||||
run_case_command "$restore" "$arch" 'machine:invalid'
|
||||
[ -n "$WRITTEN" ]
|
||||
[[ "$WRITTEN" == *machine:* ]]
|
||||
[[ "$WRITTEN" == *"$machine"* ]]
|
||||
|
||||
# The check the case runs straight after the restore.
|
||||
[[ "$WRITTEN" == *machine* ]]
|
||||
|
||||
# The remove path reads the same ladder; it must not die on an empty str3.
|
||||
run_case_command "$remove" "$arch" "machine:$machine"
|
||||
[ "$(grep -c 'unary operator expected' <<<"$OUT")" -eq 0 ]
|
||||
}
|
||||
|
||||
@test "ppc64le: the restore writes the machine type, and the remove path compares two strings" {
|
||||
assert_arch ppc64le pseries
|
||||
}
|
||||
|
||||
@test "x86_64: the restore writes the machine type, and the remove path compares two strings" {
|
||||
assert_arch x86_64 pc
|
||||
}
|
||||
|
||||
@test "riscv64: the restore writes the machine type, and the remove path compares two strings" {
|
||||
assert_arch riscv64 virt
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
#!/usr/bin/perl
|
||||
# reg_linux_diskless_installation_flat corrupts the KVM machine type of the compute node, checks
|
||||
# that the node fails to boot, and then restores it. The restore reads a machine type from a ladder
|
||||
# that names ppc64 and x86_64 only, so on any other architecture it writes an empty vmothersetting
|
||||
# and the check after it fails.
|
||||
#
|
||||
# The two commands are lifted out of the case file and RUN, with lsdef and chdef shadowed, so the
|
||||
# assertions read the value the case would write. die when an extraction stops matching, so a
|
||||
# rewrite fails loudly instead of covering nothing.
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More;
|
||||
use File::Basename qw(dirname);
|
||||
|
||||
my $case = dirname(__FILE__)
|
||||
. '/../autotest/testcase/installation/reg_linux_diskless_installation_flat';
|
||||
open my $fh, '<', $case or die("cannot read $case: $!");
|
||||
my @lines = <$fh>;
|
||||
close $fh;
|
||||
|
||||
# The command that restores the machine type, and the one that removes it again afterwards.
|
||||
my ($restore) = grep { /^cmd:.*str2="machine:invalid".*chdef \$\$CN vmothersetting=\$str5/ } @lines;
|
||||
my ($remove) = grep { /^cmd:.*str2=";".*=~ "ppc64".*chdef \$\$CN vmothersetting=/ } @lines;
|
||||
die('cannot find the command that restores the machine type') unless $restore;
|
||||
die('cannot find the command that removes the machine type') unless $remove;
|
||||
|
||||
# Render one command the way xcattest does, then run it with lsdef and chdef shadowed. bash
|
||||
# resolves a function ahead of PATH, so the case's own backticks read the stub.
|
||||
my $run = sub {
|
||||
my ($cmd, $arch, $lsdef_value) = @_;
|
||||
$cmd =~ s/^cmd://;
|
||||
$cmd =~ s/__GETNODEATTR\(\$\$CN,arch\)__/$arch/g;
|
||||
$cmd =~ s/__GETNODEATTR\(\$\$CN,mgt\)__/kvm/g;
|
||||
$cmd =~ s/\$\$CN/cn1/g;
|
||||
my $prelude = "lsdef() { echo ' vmothersetting=$lsdef_value'; }\n"
|
||||
. "chdef() { echo \"CHDEF:\$*\"; }\n";
|
||||
my $out = qx{bash -c @{[ quotemeta_cmd($prelude . $cmd) ]} 2>&1};
|
||||
my ($written) = $out =~ /^CHDEF:cn1 vmothersetting=(.*)$/m;
|
||||
return { out => $out, written => $written, rc => $? >> 8 };
|
||||
};
|
||||
|
||||
sub quotemeta_cmd { my ($s) = @_; $s =~ s/'/'\\''/g; return "'$s'" }
|
||||
|
||||
# The machine type each architecture must end up with. riscv64 guests run the qemu "virt" machine;
|
||||
# kvm.pm sets it in guest_arch_profile.
|
||||
my %machine = (
|
||||
ppc64le => 'pseries',
|
||||
x86_64 => 'pc',
|
||||
riscv64 => 'virt',
|
||||
);
|
||||
|
||||
for my $arch (sort keys %machine) {
|
||||
my $r = $run->($restore, $arch, 'machine:invalid');
|
||||
ok( defined $r->{written} && length $r->{written},
|
||||
"$arch: the restore writes a vmothersetting rather than an empty one" );
|
||||
like( $r->{written} // '', qr/\bmachine:/,
|
||||
"$arch: the restored vmothersetting names a machine type" );
|
||||
like( $r->{written} // '', qr/\Q$machine{$arch}\E/,
|
||||
"$arch: the restored machine type is $machine{$arch}" );
|
||||
|
||||
# The check the case runs straight after the restore.
|
||||
my $keeps_machine = ( $r->{written} // '' ) =~ /machine/ ? 0 : 1;
|
||||
is( $keeps_machine, 0,
|
||||
"$arch: the check after the restore, 'vmothersetting contains machine', passes" );
|
||||
|
||||
# The remove path reads the same ladder; it must not die on an empty str3.
|
||||
my $d = $run->($remove, $arch, "machine:$machine{$arch}");
|
||||
unlike( $d->{out}, qr/unary operator expected/,
|
||||
"$arch: the remove path compares two defined strings" );
|
||||
}
|
||||
|
||||
done_testing();
|
||||
Reference in New Issue
Block a user