File Coverage

consoles/ssh_screen.pm
Criterion Covered Total %
statement 64 67 95.5
total 64 67 95.5


line stmt code
1   # Copyright 2019-2021 SUSE LLC
2   # SPDX-License-Identifier: GPL-2.0-or-later
3    
4    
5   use Mojo::Base 'consoles::serial_screen', -signatures;
6 4 use Carp 'croak';
  4  
  4  
7 4 use Net::SSH2 'LIBSSH2_ERROR_EAGAIN';
  4  
  4  
8 4 use Time::Seconds;
  4  
  4  
9 4  
  4  
  4  
10   has ssh_connection => undef;
11   has ssh_channel => undef;
12    
13   use constant TYPE_STRING_TIMEOUT => ONE_MINUTE;
14 4  
  4  
  4  
15   my $self = bless @args ? @args > 1 ? {@args} : {%{$args[0]}} : {}, ref $class || $class;
16 4  
  4  
  4  
  4  
17 4 croak('Missing parameter ssh_connection') unless $self->ssh_connection;
  0  
18   croak('Missing parameter ssh_channel') unless $self->ssh_channel;
19 4  
20 4 if ($self->{logfile}) {
21   open($self->{loghandle}, ">>", $self->{logfile})
22 4 or croak('Cannot open logfile ' . $self->{logfile});
23   }
24 2  
25   return $self->SUPER::new($self->ssh_channel);
26   }
27 4  
28   my $buffer = '';
29   $args{timeout} //= undef; # wait till data is available
30 9 $args{max_size} //= 2048;
  9  
  9  
  9  
31 9  
32 9 croak('We expect to get a none blocking SSH channel') if ($self->ssh_channel->blocking());
33 9 my $stime = consoles::serial_screen::thetime();
34   while (!$args{timeout} || (consoles::serial_screen::elapsed($stime) < $args{timeout})) {
35 9 my $read = $self->ssh_channel->read($buffer, $args{max_size});
36 9 if (defined($read)) {
37 9 $_[1] = $buffer;
38 11 print {$self->{loghandle}} $buffer if $self->{loghandle};
39 11 return $read;
40 8 }
41 8  
  8  
42 8 last if ($args{timeout} == 0);
43   select(undef, undef, undef, 0.25);
44   }
45 3 return undef;
46 3 }
47    
48 1 bmwqemu::log_call(%$nargs, $nargs->{secret} ? (-masked => $nargs->{text}) : ());
49    
50   my $text = $nargs->{text};
51 3 my $terminate_with = $nargs->{terminate_with} // '';
  3  
  3  
  3  
52 3 my $written = 0;
53   my $stime = consoles::serial_screen::thetime();
54 3  
55 3 $text .= "\cC" if ($terminate_with eq 'ETX');
56 3  
57 3 while ($written < length($text)) {
58   my $elapsed = consoles::serial_screen::elapsed($stime);
59 3  
60   croak((caller(0))[3] . ": Timed out after $elapsed seconds.")
61 3 if ($elapsed > TYPE_STRING_TIMEOUT);
62 11  
63   my $chunk = $self->ssh_channel->write(substr($text, $written));
64 11  
65   if (!defined($chunk)) {
66   my ($errcode, $errname, $errstr) = $self->ssh_connection->error;
67 10  
68   croak "Lost SSH connection to SUT: $errcode $errstr"
69 10 if $errcode != LIBSSH2_ERROR_EAGAIN;
70 4 select(undef, undef, undef, 0.1);
71   } elsif ($chunk < 0) {
72 4 # Old Net::SSH2 error signaling
73   croak "Lost SSH connection to SUT: $chunk"
74 4 if $chunk != LIBSSH2_ERROR_EAGAIN;
75   select(undef, undef, undef, 0.1);
76   } else {
77 0 $written += $chunk;
78   }
79 0 }
80    
81 6 $self->ssh_channel->send_eof if ($terminate_with eq 'EOT');
82   }
83    
84   1;