From 2542836a31af7aeb95f8e35bda8f61ec103075e5 Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Tue, 9 Jan 2024 14:31:43 -0800 Subject: [PATCH] script_run: base serial buffer size on command length If you use script_run at a serial console to run a command more than 4096 characters long, the wait_serial that waits until the whole command has made it across the serial connection will fail, because it uses the default buffer size (4096), so it will never see the full command. This means there'll be a 90 second timeout before the command is actually run, and a red frame in the results. This solves the problem by always sizing the buffer to the length of the command, plus 128 extra bytes (for the marker string, and some more for safety). Issue: https://progress.opensuse.org/issues/153304 Signed-off-by: Adam Williamson --- distribution.pm | 2 +- t/05-distribution.t | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/distribution.pm b/distribution.pm index c5b810086c6..ba8ed8a52d8 100644 --- a/distribution.pm +++ b/distribution.pm @@ -127,7 +127,7 @@ sub script_run ($self, $cmd, @args) { my $marker = "; echo $str-\$?-" . ($args{output} ? "Comment: $args{output}" : ''); if (testapi::is_serial_terminal) { testapi::type_string($marker); - testapi::wait_serial($cmd . $marker, no_regex => 1, quiet => $args{quiet}); + testapi::wait_serial($cmd . $marker, no_regex => 1, quiet => $args{quiet}, buffer_size => length($cmd) + 128); testapi::type_string("\n"); } else { diff --git a/t/05-distribution.t b/t/05-distribution.t index 0cb84b9a84a..1a802fbc50e 100755 --- a/t/05-distribution.t +++ b/t/05-distribution.t @@ -12,6 +12,8 @@ use Test::Warnings qw(:all :report_warnings); use Test::Fatal; use Test::MockModule; +my @wait_serial_calls; + subtest 'script_run' => sub { require distribution; my $d = distribution->new; @@ -33,6 +35,30 @@ subtest 'script_run' => sub { lives_ok sub { $d->script_run('foo\&') }, 'escaped terminator is accepted'; lives_ok sub { $d->script_run('foo && bar') }, 'AND operator is accepted'; lives_ok sub { $d->script_run('foo "x&"') }, 'quoted & is accepted'; + $mock_testapi->redefine(wait_serial => sub { + my $regexp = shift; + push @wait_serial_calls, { + regexp => $regexp, + timeout => 90, + expect_not_found => 0, + quiet => undef, + no_regex => 0, + buffer_size => undef, + record_output => undef, + @_ + }; + }); + $mock_testapi->redefine(is_serial_terminal => 1); + $d->script_run('short_command'); + # script_run calls wait_serial three times when on a serial + # console, the call we want to check - which actually types the + # command - is the second + my $cmdcall = $wait_serial_calls[1]; + is $cmdcall->{buffer_size}, 141, 'appropriate buffer size used for short command'; + @wait_serial_calls = (); + $d->script_run('long_command' x 512); + $cmdcall = $wait_serial_calls[1]; + is $cmdcall->{buffer_size}, 6272, 'appropriate buffer size used for long command'; }; done_testing;