File Coverage

backend/generalhw.pm
Criterion Covered Total %
statement 118 156 75.6
total 118 156 75.6


line stmt code
1   # Copyright 2016-2020 SUSE LLC
2   # SPDX-License-Identifier: GPL-2.0-or-later
3    
4   # this backend uses a KVM connector speaking VNC and external tools
5   # for serial line and power cycling
6    
7    
8   use Mojo::Base 'backend::baseclass', -signatures;
9 1 use autodie ':all';
  1  
  1  
10 1 use bmwqemu;
  1  
  1  
11 1 use IPC::Run ();
  1  
  1  
12 1 require IPC::System::Simple;
  1  
  1  
13   use File::Basename 'basename';
14 1 use Mojo::IOLoop::ReadWriteProcess::Session 'session';
  1  
  1  
15 1  
  1  
  1  
16   # required for the tests to access our HTTP port
17 2 defined $bmwqemu::vars{WORKER_HOSTNAME} or die 'Need variable WORKER_HOSTNAME';
  2  
  2  
18   return $class->SUPER::new;
19 2 }
20 1  
21   my $dir = $bmwqemu::vars{GENERAL_HW_CMD_DIR} or die 'Need variable GENERAL_HW_CMD_DIR';
22   die 'GENERAL_HW_CMD_DIR is not pointing to a directory' unless -d $dir;
23 12  
  12  
  12  
  12  
24 12 my %GENERAL_HW_ARG_VARIABLES_BY_CMD = (
25 12 'GENERAL_HW_FLASH_CMD' => 'GENERAL_HW_FLASH_ARGS',
26   'GENERAL_HW_SOL_CMD' => 'GENERAL_HW_SOL_ARGS',
27 11 'GENERAL_HW_INPUT_CMD' => 'GENERAL_HW_INPUT_ARGS',
28   'GENERAL_HW_POWERON_CMD' => 'GENERAL_HW_POWERON_ARGS',
29   'GENERAL_HW_POWEROFF_CMD' => 'GENERAL_HW_POWEROFF_ARGS',
30   'GENERAL_HW_IMAGE_CMD' => 'GENERAL_HW_IMAGE_ARGS',
31   );
32   my $args = $bmwqemu::vars{$GENERAL_HW_ARG_VARIABLES_BY_CMD{$cmd}} if $bmwqemu::vars{$GENERAL_HW_ARG_VARIABLES_BY_CMD{$cmd}};
33    
34   $cmd = $bmwqemu::vars{$cmd} or die "Need test variable '$cmd'";
35 11 $cmd = "$dir/" . basename($cmd);
36   $cmd .= " $args" if $args;
37 11 return $cmd;
38 11 }
39 11  
40 11 my @full_cmd = split / /, $self->get_cmd($cmd);
41    
42   push @full_cmd, @extra_args;
43 11  
  11  
  11  
  11  
  11  
44 11 my ($stdin, $stdout, $stderr, $ret);
45    
46 10 {
47   # Do not let the SIGCHLD handler of Mojo::IOLoop::ReadWriteProcess::Session steal the exit code from IPC::Run
48 10 local $SIG{CHLD};
49   eval { $ret = IPC::Run::run(\@full_cmd, \$stdin, \$stdout, \$stderr) };
50   die "Unable to run command '@full_cmd' (deduced from test variable $cmd): $@\n" if $@;
51   }
52 10 chomp $stdout;
  10  
53 10 chomp $stderr;
  10  
54 10  
55   die "$cmd: stdout: $stdout, stderr: $stderr" unless $ret;
56 9 bmwqemu::diag("IPMI: stdout: $stdout, stderr: $stderr");
57 9 return $stdout;
58   }
59 9  
60 9 $self->run_cmd('GENERAL_HW_POWEROFF_CMD');
61 9 return;
62   }
63    
64 5 $self->poweroff_host;
  5  
  5  
65 5 sleep(3);
66 5 $self->run_cmd('GENERAL_HW_POWERON_CMD');
67   return;
68   }
69 2  
  2  
  2  
70 2 if ($args->{action} eq 'on') {
71 2 $self->run_cmd('GENERAL_HW_POWERON_CMD');
72 2 } elsif ($args->{action} eq 'off') {
73 2 $self->run_cmd('GENERAL_HW_POWEROFF_CMD');
74   } else {
75   $self->notimplemented;
76 0 }
  0  
  0  
  0  
77 0 }
78 0  
79   if ($self->{vnc}) {
80 0 close($self->{vnc}->socket);
81   sleep(1);
82 0 }
83    
84   my $vnc = $testapi::distri->add_console(
85   'sut',
86 1 'vnc-base',
  1  
  1  
87 1 {
88 0 hostname => $bmwqemu::vars{GENERAL_HW_VNC_IP} || die('Need variable GENERAL_HW_VNC_IP'),
89 0 port => $bmwqemu::vars{GENERAL_HW_VNC_PORT} // 5900,
90   password => $bmwqemu::vars{GENERAL_HW_VNC_PASSWORD},
91   depth => 16,
92   connect_timeout => 50
93   });
94   $vnc->backend($self);
95   $self->select_console({testapi_console => 'sut'});
96    
97   return 1;
98   }
99 1  
100   my @hdd_args;
101    
102 1 if ($bmwqemu::vars{HDD_1}) {
103 1 my $numdisks = $bmwqemu::vars{NUMDISKS} // 1;
104   for my $i (1 .. $numdisks) {
105 1 # Pass path of HDD
106   push @hdd_args, $bmwqemu::vars{"HDD_$i"} or die 'Need variable HDD_$i';
107   # Pass size of HDD
108 3 my $size = $bmwqemu::vars{"HDDSIZEGB_$i"};
  3  
  3  
109 3 $size //= $bmwqemu::vars{HDDSIZEGB} // 10;
110   push @hdd_args, $size . 'G';
111 3 }
112 3 }
113 3 return \@hdd_args;
114   }
115 4  
116    
117 4 my $input_cmd;
118 4 $input_cmd = $self->get_cmd('GENERAL_HW_INPUT_CMD') if ($bmwqemu::vars{GENERAL_HW_INPUT_CMD});
119 4 my $vnc = $testapi::distri->add_console(
120   'sut',
121   'video-stream',
122 3 {
123   url => $bmwqemu::vars{GENERAL_HW_VIDEO_STREAM_URL},
124   connect_timeout => 50,
125 1 input_cmd => $input_cmd,
  1  
  1  
126   edid => $bmwqemu::vars{GENERAL_HW_EDID},
127 1 });
128 1 $vnc->backend($self);
129   $self->select_console({testapi_console => 'sut'});
130    
131   return 1;
132   }
133    
134   $self->truncate_serial_file;
135   if ($bmwqemu::vars{GENERAL_HW_FLASH_CMD}) {
136   # Append HDD infos to flash script
137 1 my $hdd_args = $self->compute_hdd_args;
138 1  
139 1 $self->poweroff_host; # Ensure system is off, before flashing
140   $self->run_cmd('GENERAL_HW_FLASH_CMD', @$hdd_args);
141 1 }
142   $self->restart_host;
143   $self->relogin_vnc if ($bmwqemu::vars{GENERAL_HW_VNC_IP});
144 2 $self->reconnect_video_stream if ($bmwqemu::vars{GENERAL_HW_VIDEO_STREAM_URL});
  2  
  2  
145 2 $self->start_serial_grab if (($bmwqemu::vars{GENERAL_HW_VNC_IP} || $bmwqemu::vars{GENERAL_HW_SOL_CMD}) && !$bmwqemu::vars{GENERAL_HW_NO_SERIAL});
146 2 return {};
147   }
148 2  
149   $self->poweroff_host;
150 2 $self->stop_serial_grab() if (($bmwqemu::vars{GENERAL_HW_VNC_IP} || $bmwqemu::vars{GENERAL_HW_SOL_CMD}) && !$bmwqemu::vars{GENERAL_HW_NO_SERIAL});
151 2 $self->disable_consoles;
152   return {};
153 2 }
154 2  
155 2 return $self->check_ssh_serial($fh) || $self->SUPER::check_socket($fh, $write);
156 2 }
157 2  
158   # serial grab
159    
160 1 $self->{serialpid} = fork();
  1  
  1  
161 1 return unless $self->{serialpid} == 0;
162 1 setpgrp 0, 0;
163 1 open(my $serial, '>', $self->{serialfile});
164 1 open(STDOUT, ">&", $serial);
165   open(STDERR, ">&", $serial);
166   exec($self->get_cmd('GENERAL_HW_SOL_CMD'));
167 0 die "exec failed $!";
  0  
  0  
  0  
  0  
168 0 }
169    
170   return unless $self->{serialpid};
171   kill("-TERM", $self->{serialpid});
172   return waitpid($self->{serialpid}, 0);
173 0 }
  0  
  0  
174 0  
175 0 # serial grab end
176 0  
177 0 my $name = $args->{name};
178 0 my $img_dir = $args->{dir};
179 0 my $hdd_num = $args->{hdd_num} - 1;
180 0 die "extracting pflash vars not supported" if $args->{pflash_vars};
181 0  
182   $self->run_cmd('GENERAL_HW_IMAGE_CMD', ($hdd_num, "$img_dir/$name"));
183   }
184 1  
  1  
  1  
185 1 1;