From f4be85471d4b9a555233f3cfc6ddaa9eb4b49a13 Mon Sep 17 00:00:00 2001 From: Tina Mueller Date: Wed, 14 Aug 2019 18:58:22 +0200 Subject: [PATCH] Improve result display of validate_script_output See also https://progress.opensuse.org/issues/54548 Before the output showed: # wait_serial expected: (whatever the output was) # Result: (whatever the output was) "wait_serial" is wrong here, and it showed the actual output twice. Now it shows: validate_script_output got: (whatever the output was) Check function (deparsed code): { package your::test::package; /some.*regex/; } * Also validate_script_output() can now take a simple regular expression qr/foo/ instead of a coderef. * Add explicit return statement to make current behaviour transparent --- cpanfile | 1 + dist/rpm/os-autoinst.spec | 2 +- t/03-testapi.t | 7 +++++ testapi.pm | 55 ++++++++++++++++++++++++++++++--------- 4 files changed, 52 insertions(+), 13 deletions(-) diff --git a/cpanfile b/cpanfile index 4b8e68592..da23f89d4 100644 --- a/cpanfile +++ b/cpanfile @@ -1,3 +1,4 @@ +requires 'B::Deparse'; requires 'Carp'; requires 'Carp::Always'; requires 'Class::Accessor::Fast'; diff --git a/t/03-testapi.t b/t/03-testapi.t index e893c1ddc..63aab9aca 100755 --- a/t/03-testapi.t +++ b/t/03-testapi.t @@ -489,6 +489,7 @@ subtest 'validate_script_output' => sub { my $mock_testapi = Test::MockModule->new('testapi'); $mock_testapi->mock(script_output => sub { return 'output'; }); ok(!validate_script_output('script', sub { m/output/ }), 'validating output with default timeout'); + ok(!validate_script_output('script', qr/output/), 'validating output with regex and default timeout'); ok(!validate_script_output('script', sub { m/output/ }, 30), 'specifying timeout'); like( exception { @@ -496,6 +497,12 @@ subtest 'validate_script_output' => sub { }, qr/output not validating/ ); + like( + exception { + validate_script_output('script', ['Invalid parameter']); + }, + qr/coderef or regexp/ + ); }; subtest 'wait_still_screen' => sub { diff --git a/testapi.pm b/testapi.pm index 1b36c73cc..b5bdb4abc 100755 --- a/testapi.pm +++ b/testapi.pm @@ -33,7 +33,8 @@ use OpenQA::Isotovideo::NeedleDownloader; use Digest::MD5 'md5_base64'; use Carp qw(cluck croak); use MIME::Base64 'decode_base64'; -use Scalar::Util 'looks_like_number'; +use Scalar::Util qw(looks_like_number reftype); +use B::Deparse; require bmwqemu; use constant OPENQA_LIBPATH => '/usr/share/openqa/lib'; @@ -1117,20 +1118,23 @@ sub get_test_data { =head2 validate_script_output - validate_script_output($script, $code [, timeout => $timeout] [,quiet => $quiet]) + validate_script_output($script, $code | $regexp [, timeout => $timeout] [,quiet => $quiet]) Deprecated mode validate_script_output($script, $code, [$wait]) -Wrapper around script_output, that runs a callback on the output. Use it as +Wrapper around script_output, that runs a callback on the output, or +alternatively matches a regular expression. Use it as - validate_script_output "cat /etc/hosts", sub { m/127.*localhost/ } + validate_script_output "cat /etc/hosts", sub { m/127.*localhost/ }; + validate_script_output "cat /etc/hosts", qr/127.*localhost/; + validate_script_output "cat /etc/hosts", sub { $_ !~ m/987.*somehost/ }; =cut sub validate_script_output { - my ($script, $code) = splice(@_, 0, 2); + my ($script, $check) = splice(@_, 0, 2); my %args = compat_args( { timeout => 30, @@ -1140,17 +1144,44 @@ sub validate_script_output { my $output = script_output($script, %args); my $res = 'ok'; - # set $_ so the callbacks can be simpler code - $_ = $output; - if (!$code->()) { - $res = 'fail'; - bmwqemu::diag("output does not pass the code block:\n$output"); + my $message = ''; + if (reftype $check eq 'CODE') { + # set $_ so the callbacks can be simpler code + $_ = $output; + if (!$check->()) { + $res = 'fail'; + bmwqemu::diag("output does not pass the code block:\n$output"); + } + my $deparse = B::Deparse->new("-p"); + # avoid "use strict; use warnings" in the output to make it shorter + $deparse->ambient_pragmas(warnings => [], strict => "all"); + + my $body = $deparse->coderef2text($check); + + $message = sprintf + "validate_script_output got:\n%s\n\nCheck function (deparsed code):\n%s", + $output, $body; + } + elsif (reftype $check eq 'REGEXP') { + if ($output !~ $check) { + $res = 'fail'; + bmwqemu::diag("output does not match the regex:\n$output"); + } + $message = sprintf + "validate_script_output got:\n%s\n\nRegular expression:\n%s", + $output, $check; + } + else { + croak "Invalid use of validate_script_output(), second arg must be a coderef or regexp"; } - # abusing the function - $autotest::current_test->record_serialresult($output, $res, $output) unless ($args{quiet}); + $autotest::current_test->record_resultfile( + 'validate_script_output', $message, + result => $res, + ); if ($res eq 'fail') { croak "output not validating"; } + return 0; } =head2 become_root