Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package os-autoinst for openSUSE:Factory checked in at 2026-03-06 18:18:25 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/os-autoinst (Old) and /work/SRC/openSUSE:Factory/.os-autoinst.new.561 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "os-autoinst" Fri Mar 6 18:18:25 2026 rev:571 rq:1336798 version:5.1772729929.93a4b15 Changes: -------- --- /work/SRC/openSUSE:Factory/os-autoinst/os-autoinst.changes 2026-03-05 17:23:45.900110130 +0100 +++ /work/SRC/openSUSE:Factory/.os-autoinst.new.561/os-autoinst.changes 2026-03-06 18:19:05.789412375 +0100 @@ -1,0 +2,11 @@ +Thu Mar 05 17:55:20 UTC 2026 - [email protected] + +- Update to version 5.1772729929.93a4b15: + * feat: normalize gre tunnel script for NetworkManager and wicked + * refactor: use more Mojo::File operations in commands.pm + * refactor: use more Mojo::File operations in bmwqemu.pm + * refactor: use more Mojo::File operations in t/ + * refactor: move scheduling rules out of basetest::is_applicable + * feat: add EXIT_AFTER_MODULE to stop after a specified module + +------------------------------------------------------------------- Old: ---- os-autoinst-5.1772663930.9a9bd7d.obscpio New: ---- os-autoinst-5.1772729929.93a4b15.obscpio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ os-autoinst-devel-test.spec ++++++ --- /var/tmp/diff_new_pack.2r6yPk/_old 2026-03-06 18:19:07.533484244 +0100 +++ /var/tmp/diff_new_pack.2r6yPk/_new 2026-03-06 18:19:07.541484574 +0100 @@ -18,7 +18,7 @@ %define short_name os-autoinst-devel Name: %{short_name}-test -Version: 5.1772663930.9a9bd7d +Version: 5.1772729929.93a4b15 Release: 0 Summary: Test package for %{short_name} License: GPL-2.0-or-later ++++++ os-autoinst-openvswitch-test.spec ++++++ --- /var/tmp/diff_new_pack.2r6yPk/_old 2026-03-06 18:19:07.581486222 +0100 +++ /var/tmp/diff_new_pack.2r6yPk/_new 2026-03-06 18:19:07.585486387 +0100 @@ -19,7 +19,7 @@ %define name_ext -test %define short_name os-autoinst-openvswitch Name: %{short_name}%{?name_ext} -Version: 5.1772663930.9a9bd7d +Version: 5.1772729929.93a4b15 Release: 0 Summary: test package for %{short_name} License: GPL-2.0-or-later ++++++ os-autoinst-test.spec ++++++ --- /var/tmp/diff_new_pack.2r6yPk/_old 2026-03-06 18:19:07.629488200 +0100 +++ /var/tmp/diff_new_pack.2r6yPk/_new 2026-03-06 18:19:07.633488365 +0100 @@ -19,7 +19,7 @@ %define name_ext -test %define short_name os-autoinst Name: %{short_name}%{?name_ext} -Version: 5.1772663930.9a9bd7d +Version: 5.1772729929.93a4b15 Release: 0 Summary: test package for os-autoinst License: GPL-2.0-or-later ++++++ os-autoinst.spec ++++++ --- /var/tmp/diff_new_pack.2r6yPk/_old 2026-03-06 18:19:07.693490837 +0100 +++ /var/tmp/diff_new_pack.2r6yPk/_new 2026-03-06 18:19:07.693490837 +0100 @@ -17,7 +17,7 @@ Name: os-autoinst -Version: 5.1772663930.9a9bd7d +Version: 5.1772729929.93a4b15 Release: 0 Summary: OS-level test automation License: GPL-2.0-or-later ++++++ os-autoinst-5.1772663930.9a9bd7d.obscpio -> os-autoinst-5.1772729929.93a4b15.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1772663930.9a9bd7d/autotest.pm new/os-autoinst-5.1772729929.93a4b15/autotest.pm --- old/os-autoinst-5.1772663930.9a9bd7d/autotest.pm 2026-03-04 23:38:50.000000000 +0100 +++ new/os-autoinst-5.1772729929.93a4b15/autotest.pm 2026-03-05 17:58:49.000000000 +0100 @@ -17,6 +17,7 @@ use cv; use signalblocker; use Scalar::Util 'blessed'; +use List::Util 'any'; use Mojo::IOLoop::ReadWriteProcess 'process'; use Mojo::IOLoop::ReadWriteProcess::Session 'session'; use Mojo::File qw(path); @@ -246,6 +247,43 @@ return $code; } +=head2 _should_schedule + +Return false if the test should be skipped. + +It checks the test name and fullname against a comma-separated blocklist in +C<EXCLUDE_MODULES> variable and returns false if it is found there. + +If C<INCLUDE_MODULES> is set it will only return true for modules matching the +passlist specified in a comma-separated list in C<INCLUDE_MODULES> matching +either test name or fullname. + +C<EXCLUDE_MODULES> has precedence over C<INCLUDE_MODULES> and can be combined +to blocklist test modules from the passlist specified in C<INCLUDE_MODULES>. + +If C<EXIT_AFTER_MODULE> is set it will return false for all modules scheduled +after the module matching the specified name or fullname. + +Finally it calls C<is_applicable> on the test module itself which can e.g. +check C<vars{BIGTEST}> or C<vars{LIVETEST}>. + +=cut + +sub _should_schedule ($test) { + if ($bmwqemu::vars{EXCLUDE_MODULES}) { + my %excluded = map { $_ => 1 } split(/\s*,\s*/, $bmwqemu::vars{EXCLUDE_MODULES}); + return 0 if $excluded{$test->{class}} || $excluded{$test->{fullname}}; + } + if ($bmwqemu::vars{INCLUDE_MODULES}) { + my %included = map { $_ => 1 } split(/\s*,\s*/, $bmwqemu::vars{INCLUDE_MODULES}); + return 0 unless $included{$test->{class}} || $included{$test->{fullname}}; + } + if (my $exit_after = $bmwqemu::vars{EXIT_AFTER_MODULE}) { + return 0 if any { $_->{class} eq $exit_after || $_->{fullname} eq $exit_after } @testorder; + } + return $test->is_applicable; +} + sub loadtest ($script, %args) { no utf8; # Inline Python fails on utf8, so let's exclude it here my $script_path = find_script($script); @@ -293,7 +331,7 @@ $tests{$fullname . $nr} = $test; - return unless $test->is_applicable; + return unless _should_schedule($test); push @testorder, $test; # Test schedule may change at runtime. Update test_order.json to notify diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1772663930.9a9bd7d/basetest.pm new/os-autoinst-5.1772729929.93a4b15/basetest.pm --- old/os-autoinst-5.1772663930.9a9bd7d/basetest.pm 2026-03-04 23:38:50.000000000 +0100 +++ new/os-autoinst-5.1772729929.93a4b15/basetest.pm 2026-03-05 17:58:49.000000000 +0100 @@ -12,7 +12,6 @@ use ocr; use testapi (); use autotest (); -use List::Util 'any'; use MIME::Base64 'decode_base64'; use OpenQA::Exceptions; use Mojo::File 'path'; @@ -74,35 +73,11 @@ Return false if the test should be skipped. -By default it checks the test name and fullname against a comma-separated -blocklist in C<EXCLUDE_MODULES> variable and returns false if it is found there. - -If C<INCLUDE_MODULES> is set it will only return true for modules matching the -passlist specified in a comma-separated list in C<EXCLUDE_MODULES> matching -either test name or fullname. - -C<EXCLUDE_MODULES> has precedence over C<INCLUDE_MODULES> and can be combined -to blocklist test modules from the passlist specified in C<INCLUDE_MODULES>. - Can eg. check vars{BIGTEST}, vars{LIVETEST} =cut sub is_applicable ($self) { - if ($bmwqemu::vars{EXCLUDE_MODULES}) { - my %excluded = map { $_ => 1 } split(/\s*,\s*/, $bmwqemu::vars{EXCLUDE_MODULES}); - - return 0 if $excluded{$self->{class}}; - return 0 if $excluded{$self->{fullname}}; - } - if ($bmwqemu::vars{INCLUDE_MODULES}) { - my %included = map { $_ => 1 } split(/\s*,\s*/, $bmwqemu::vars{INCLUDE_MODULES}); - - return 0 unless ($included{$self->{class}} || $included{$self->{fullname}}); - } - if (my $exit_after = $bmwqemu::vars{EXIT_AFTER_MODULE}) { - return 0 if any { $_->{class} eq $exit_after || $_->{fullname} eq $exit_after } @autotest::testorder; - } return 1; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1772663930.9a9bd7d/bmwqemu.pm new/os-autoinst-5.1772729929.93a4b15/bmwqemu.pm --- old/os-autoinst-5.1772663930.9a9bd7d/bmwqemu.pm 2026-03-04 23:38:50.000000000 +0100 +++ new/os-autoinst-5.1772729929.93a4b15/bmwqemu.pm 2026-03-05 17:58:49.000000000 +0100 @@ -82,23 +82,19 @@ } sub load_vars () { - my $fn = "vars.json"; my $ret = {}; - local $/; - my $fh; - try { open($fh, '<', $fn) } + my $data; + try { $data = path('vars.json')->slurp } catch ($e) { return 0 } - try { $ret = Cpanel::JSON::XS->new->relaxed->decode(<$fh>) } + try { $ret = Cpanel::JSON::XS->new->relaxed->decode($data) } catch ($e) { die "parse error in vars.json:\n$e" } - close($fh); %vars = %{$ret}; return; } sub save_vars (%args) { - my $fn = "vars.json"; - unlink "vars.json" if -e "vars.json"; - open(my $fd, ">", $fn); + my $f = path('vars.json'); + my $fd = $f->open('>'); flock($fd, LOCK_EX) or die "cannot lock vars.json: $!\n"; truncate($fd, 0) or die "cannot truncate vars.json: $!\n"; @@ -111,7 +107,6 @@ # make sure the JSON is sorted my $json = Cpanel::JSON::XS->new->pretty->canonical; print $fd $json->encode($write_vars); - close($fd); return; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1772663930.9a9bd7d/commands.pm new/os-autoinst-5.1772729929.93a4b15/commands.pm --- old/os-autoinst-5.1772663930.9a9bd7d/commands.pm 2026-03-04 23:38:50.000000000 +0100 +++ new/os-autoinst-5.1772729929.93a4b15/commands.pm 2026-03-05 17:58:49.000000000 +0100 @@ -65,17 +65,14 @@ next; # uncoverable statement } my $fn = 'data/' . substr($file, length($base)); - local $/; # enable localized slurp mode - my $fd; - try { (open($fd, '<:raw', $file)) } + my $file_data; + try { $file_data = path($file)->slurp } catch ($e) { $self->app->log->error("Error reading test distribution file '$file': $!"); # uncoverable statement next; # uncoverable statement } my ($header, $pad) = _makecpiohead($fn, \@s); - $data .= $header; - $data .= <$fd>; - close $fd; + $data .= $header . $file_data; $data .= $pad if $pad; } $data .= _makecpiohead(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1772663930.9a9bd7d/script/os-autoinst-setup-multi-machine new/os-autoinst-5.1772729929.93a4b15/script/os-autoinst-setup-multi-machine --- old/os-autoinst-5.1772663930.9a9bd7d/script/os-autoinst-setup-multi-machine 2026-03-04 23:38:50.000000000 +0100 +++ new/os-autoinst-5.1772729929.93a4b15/script/os-autoinst-setup-multi-machine 2026-03-05 17:58:49.000000000 +0100 @@ -123,16 +123,34 @@ #!/bin/sh OVS_CMD=\$(command -v ovs-vsctl) if [ -z "\$OVS_CMD" ]; then - logger "Error: ovs-vsctl not found. Skipping script \$0" + logger -- "Error: ovs-vsctl not found. Skipping script \$0" exit 0 # Exit 0 to avoid breaking NetworkManager's flow fi TARGET_BRIDGE=\$("\$OVS_CMD" list-br) -action="\$1" -bridge="\$2" -if [ "\$bridge" = "\$TARGET_BRIDGE" ] && ([ "\$action" = "pre-up" ] || [ "\$action" = "up" ]); then - ovs-vsctl set bridge \$bridge rstp_enable=true - # TODO add entries according to your network topology - #ovs-vsctl --may-exist add-port \$bridge gre1 -- set interface gre1 type=gre options:remote_ip=<IP address of other host> +# NM_DISPATCHER_ACTION env var is set when NM calls scripts via dispatcher service +# Ref: https://networkmanager.dev/docs/api/1.44.4/NetworkManager-dispatcher.html +# 2. Argument Normalization (NetworkManager vs. wicked) +# NetworkManager: \$1 = interface name, \$2 = action +# wicked: \$1 = action, \$2 = interface name +if [ -n "\$NM_DISPATCHER_ACTION" ]; then + # Environment detected as NetworkManager + bridge="\$1" + action="\$2" +else + # Environment detected as wicked (or manual call) + action="\$1" + bridge="\$2" +fi + +# use grep -qx to ensure the bridge exists in the OVS database if more than one ovs bridge are in db +if "\$OVS_CMD" list-br | grep -qx "\$bridge"; then + if [ "\$action" = "pre-up" ] || [ "\$action" = "up" ]; then + ovs-vsctl set bridge \$bridge rstp_enable=true + # TODO add entries according to your network topology + #ovs-vsctl --may-exist add-port \$bridge gre1 -- set interface gre1 type=gre options:remote_ip=<IP address of other host> + fi +else + logger -- "\$0: ovs bridge \$bridge doesn't exists" fi EOF chmod +x "$location" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1772663930.9a9bd7d/t/08-autotest.t new/os-autoinst-5.1772729929.93a4b15/t/08-autotest.t --- old/os-autoinst-5.1772663930.9a9bd7d/t/08-autotest.t 2026-03-04 23:38:50.000000000 +0100 +++ new/os-autoinst-5.1772729929.93a4b15/t/08-autotest.t 2026-03-05 17:58:49.000000000 +0100 @@ -307,6 +307,37 @@ && is(@{$autotest::tests{'tests-fatal' . $_}}{name}, 'fatal#' . $_) for 1 .. 10; +subtest 'scheduling rules' => sub { + %autotest::tests = (); + @autotest::testorder = (); + + $bmwqemu::vars{EXCLUDE_MODULES} = 'start'; + autotest::loadtest('tests/start.pm'); + is scalar @autotest::testorder, 0, 'exclude by name works'; + + $bmwqemu::vars{EXCLUDE_MODULES} = 'tests-next'; + autotest::loadtest('tests/next.pm'); + is scalar @autotest::testorder, 0, 'exclude by fullname works'; + + $bmwqemu::vars{EXCLUDE_MODULES} = ''; + $bmwqemu::vars{INCLUDE_MODULES} = 'start'; + loadtest 'start'; + is scalar @autotest::testorder, 1, 'include by name works'; + autotest::loadtest('tests/next.pm'); + is scalar @autotest::testorder, 1, 'include excludes others'; + + $bmwqemu::vars{INCLUDE_MODULES} = ''; + $bmwqemu::vars{EXIT_AFTER_MODULE} = 'next'; + loadtest 'next'; + is scalar @autotest::testorder, 2, 'exit_after_module does not exclude itself'; + autotest::loadtest('tests/fatal.pm'); + is scalar @autotest::testorder, 2, 'exit_after_module excludes subsequent modules'; + + $bmwqemu::vars{EXIT_AFTER_MODULE} = ''; + @autotest::testorder = (); +}; + + subtest 'test scheduling test modules at test runtime' => sub { $autotest::tests_running = 0; @autotest::testorder = (); @@ -530,7 +561,6 @@ like $out, qr{foo = bar}, 'hashes work'; }; - done_testing(); END { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1772663930.9a9bd7d/t/10-terminal.t new/os-autoinst-5.1772729929.93a4b15/t/10-terminal.t --- old/os-autoinst-5.1772663930.9a9bd7d/t/10-terminal.t 2026-03-04 23:38:50.000000000 +0100 +++ new/os-autoinst-5.1772729929.93a4b15/t/10-terminal.t 2026-03-05 17:58:49.000000000 +0100 @@ -5,6 +5,7 @@ use Test::Most; use Mojo::Base -strict, -signatures; use Feature::Compat::Try; +use Mojo::File qw(path); use FindBin '$Bin'; use lib "$Bin/../external/os-autoinst-common/lib"; use OpenQA::Test::TimeLimit '5'; @@ -148,12 +149,8 @@ }; alarm $timeout; - - open(my $fd_r, "<", $pipe_in) - or die "Can't open in pipe for writing $!"; - open(my $fd_w, ">", $pipe_out) - or die "Can't open out pipe for reading $!"; - + my $fd_r = path($pipe_in)->open('<'); + my $fd_w = path($pipe_out)->open('>'); $SIG{ALRM} = sub { report_child_test(fail => 'fake_terminal timed out while performing IO'); # uncoverable statement exit(1); # uncoverable statement @@ -360,9 +357,7 @@ for my $test (@$tests) { my ($method, @args) = @$test; if (my $sub = Test::Most->can($method)) { - if ($method eq 'like') { - $args[1] = qr{$args[1]}; - } + $args[1] = qr{$args[1]} if $method eq 'like'; $args[-1] = "[Child $pid] " . $args[-1]; $sub->(@args); } @@ -383,30 +378,29 @@ # but it doesn't work with this test sub report_child_test ($method, @args) { my $json = encode_json([$$, [$method => @args]]); - open my $fh, '>>', $sharefile or die $!; - flock $fh, LOCK_EX; - seek $fh, 0, SEEK_END; - print $fh "$json\n"; - close $fh; + my $fd = path($sharefile)->open('>>'); + flock $fd, LOCK_EX; + seek $fd, 0, SEEK_END; + print $fd "$json\n"; + close $fd; } sub retrieve_child_tests () { return unless -e $sharefile; - open my $fh, '<', $sharefile or die $!; - flock $fh, LOCK_SH; + my $fd = path($sharefile)->open('<'); + flock $fd, LOCK_SH; my %tests; - while (my $json = <$fh>) { + while (my $line = <$fd>) { my $data; - try { $data = decode_json($json) } + try { $data = decode_json($line) } catch ($e) { - diag("Error decoding '$json': $e"); # uncoverable statement + diag("Error decoding '$line': $e"); # uncoverable statement ok(0, "Valid JSON"); # uncoverable statement next; # uncoverable statement } my ($pid, $test) = @$data; push @{$tests{$pid}}, $test; } - close $fh; return \%tests; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1772663930.9a9bd7d/t/12-bmwqemu.t new/os-autoinst-5.1772729929.93a4b15/t/12-bmwqemu.t --- old/os-autoinst-5.1772663930.9a9bd7d/t/12-bmwqemu.t 2026-03-04 23:38:50.000000000 +0100 +++ new/os-autoinst-5.1772729929.93a4b15/t/12-bmwqemu.t 2026-03-05 17:58:49.000000000 +0100 @@ -23,21 +23,11 @@ my $toplevel_dir = abs_path(dirname(__FILE__) . '/..'); my $data_dir = "$toplevel_dir/t/data"; -sub create_vars ($data) { - open(my $varsfh, '>', 'vars.json') || BAIL_OUT('can not create vars.json'); - my $json = Cpanel::JSON::XS->new->pretty->canonical; - print $varsfh $json->encode($data); - close($varsfh); -} +sub create_vars ($data) { path('vars.json')->spew(Cpanel::JSON::XS->new->pretty->canonical->encode($data)) } sub read_vars () { - local $/; - open(my $varsfh, '<', 'vars.json') || BAIL_OUT('can not open vars.json for reading'); - my $ret; - try { $ret = Cpanel::JSON::XS->new->relaxed->decode(<$varsfh>) } + try { return Cpanel::JSON::XS->new->relaxed->decode(path('vars.json')->slurp) } catch ($e) { die "parse error in vars.json:\n$e" } # uncoverable statement - close($varsfh); - return $ret; } subtest 'log_call' => sub { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/os-autoinst-5.1772663930.9a9bd7d/t/17-basetest.t new/os-autoinst-5.1772729929.93a4b15/t/17-basetest.t --- old/os-autoinst-5.1772663930.9a9bd7d/t/17-basetest.t 2026-03-04 23:38:50.000000000 +0100 +++ new/os-autoinst-5.1772729929.93a4b15/t/17-basetest.t 2026-03-05 17:58:49.000000000 +0100 @@ -115,30 +115,6 @@ $basetest->{class} = 'foo'; $basetest->{fullname} = 'installation-foo'; ok($basetest->is_applicable, 'module is applicable by default'); - $bmwqemu::vars{EXCLUDE_MODULES} = 'foo,bar'; - ok(!$basetest->is_applicable, 'module can be excluded'); - $bmwqemu::vars{EXCLUDE_MODULES} = 'installation-foo'; - ok(!$basetest->is_applicable, 'model can be excluded by fullname'); - $bmwqemu::vars{EXCLUDE_MODULES} = ''; - $bmwqemu::vars{INCLUDE_MODULES} = 'bar,baz'; - ok(!$basetest->is_applicable, 'modules can be excluded based on a passlist'); - $bmwqemu::vars{INCLUDE_MODULES} = 'bar,baz,foo'; - ok($basetest->is_applicable, 'a passlisted module shows up'); - $bmwqemu::vars{EXCLUDE_MODULES} = 'foo'; - ok(!$basetest->is_applicable, 'passlisted modules are overridden by blocklist'); - $bmwqemu::vars{EXCLUDE_MODULES} = ''; - $bmwqemu::vars{EXIT_AFTER_MODULE} = 'foo'; - ok($basetest->is_applicable, 'matching module itself is still applicable'); - @autotest::testorder = ($basetest); - ok(!$basetest->is_applicable, 'after matching module, it is not applicable anymore'); - my $other = basetest->new('installation'); - $other->{class} = 'bar'; - $other->{fullname} = 'installation-bar'; - ok(!$other->is_applicable, 'any other module after matching module is not applicable'); - $bmwqemu::vars{EXIT_AFTER_MODULE} = 'installation-foo'; - ok(!$other->is_applicable, 'matches fullname too'); - $bmwqemu::vars{EXIT_AFTER_MODULE} = ''; - @autotest::testorder = (); }; subtest parse_serial_output => sub { ++++++ os-autoinst.obsinfo ++++++ --- /var/tmp/diff_new_pack.2r6yPk/_old 2026-03-06 18:19:10.669613477 +0100 +++ /var/tmp/diff_new_pack.2r6yPk/_new 2026-03-06 18:19:10.673613642 +0100 @@ -1,5 +1,5 @@ name: os-autoinst -version: 5.1772663930.9a9bd7d -mtime: 1772663930 -commit: 9a9bd7de7a66abee35e6b6023dbab76616c81c5a +version: 5.1772729929.93a4b15 +mtime: 1772729929 +commit: 93a4b15c9d316aad5d9945a8dc22d6ddcec30c9f
