From 3123dd2b83203ddfebde820a16f002165d50474e Mon Sep 17 00:00:00 2001 From: Adam Williamson Date: Tue, 9 Jan 2024 14:31:43 -0800 Subject: [PATCH] script_run: use bigger buffer for very long serial commands 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 specifying a larger buffer size when the command is long. Issue: https://progress.opensuse.org/issues/153304 Signed-off-by: Adam Williamson --- distribution.pm | 3 ++- t/05-distribution.t | 26 ++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/distribution.pm b/distribution.pm index c5b810086c6..b2905efdd2f 100644 --- a/distribution.pm +++ b/distribution.pm @@ -127,7 +127,8 @@ 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}); + my $buffer = length($cmd) > 3584 ? length($cmd) + 512 : 4096; + testapi::wait_serial($cmd . $marker, no_regex => 1, quiet => $args{quiet}, buffer_size => $buffer); testapi::type_string("\n"); } else { diff --git a/t/05-distribution.t b/t/05-distribution.t index 0cb84b9a84a..a72a9534dc1 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}, 4096, 'buffer size 4096 used for short commands'; + @wait_serial_calls = (); + $d->script_run('long_command' x 512); + $cmdcall = $wait_serial_calls[1]; + is $cmdcall->{buffer_size}, 6656, 'bigger buffer used for long commands'; }; done_testing;