5 use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
8 $#ARGV >= 0 || die "usage: autotest.pl config-file\n";
15 $opt{"NUM_BUILDS"} = 5;
16 $opt{"DEFAULT_BUILD_TYPE"} = "randconfig";
17 $opt{"MAKE_CMD"} = "make";
19 $opt{"TMP_DIR"} = "/tmp/autotest";
20 $opt{"SLEEP_TIME"} = 60; # sleep time between tests
31 open(IN, $config) || die "can't read file $config";
35 # ignore blank lines and comments
36 next if (/^\s*$/ || /\s*\#/);
38 if (/^\s*(\S+)\s*=\s*(.*?)\s*$/) {
42 $opt{$lvalue} = $rvalue;
52 if (defined($opt{"LOG_FILE"})) {
53 open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
63 if (defined($opt{"LOG_FILE"})) {
64 $redirect = " >> $opt{LOG_FILE} 2>&1";
67 doprint "$command ... ";
81 my $timeout = $opt{"TIMEOUT"};
91 if (!defined($time)) {
96 vec($rin, fileno($fp), 1) = 1;
97 $ready = select($rin, undef, undef, $time);
101 # try to read one char at a time
102 while (sysread $fp, $ch, 1) {
104 last if ($ch eq "\n");
107 if (!length($line)) {
115 run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
126 $pid = open2(\*IN, \*OUT, $opt{CONSOLE});
128 die "Failed to connect to the console";
131 $pid = open(IN, "$opt{CONSOLE} |");
134 $flags = fcntl(IN, F_GETFL, 0) or
135 die "Can't get flags for the socket: $!\n";
137 $flags = fcntl(IN, F_SETFL, $flags | O_NONBLOCK) or
138 die "Can't set flags for the socket: $!\n";
143 doprint "Wait for monitor to settle down.\n";
144 # read the monitor and wait for the system to calm down
146 $line = wait_for_input(\*IN, 5);
147 } while (defined($line));
153 $line = wait_for_input(\*IN);
155 last if (!defined($line));
159 # we are not guaranteed to get a full line
162 if ($full_line =~ /login:/) {
166 if ($full_line =~ /call trace:/i) {
175 doprint "kill child process $pid\n";
182 die "failed - never got a boot prompt.\n";
186 die "failed - got a bug report\n";
192 if (run_command "scp $opt{OUTPUT_DIR}/$opt{BUILD_TARGET} $target:$opt{TARGET_IMAGE}") {
193 die "failed to copy image";
197 my $modlib = "/lib/modules/$version";
199 if (run_command "ssh $target rm -rf $modlib") {
200 die "failed to remove old mods: $modlib";
203 if (run_command "scp -r $opt{TMP_DIR}/lib $target:/lib/modules/$version") {
204 die "failed to copy modules";
213 unlink "$opt{OUTPUT_DIR}/.config";
215 run_command "$make mrproper";
217 # add something to distinguish this build
218 open(OUT, "> $opt{OUTPUT_DIR}/localversion") or die("Can't make localversion file");
219 print OUT "$opt{LOCALVERSION}\n";
222 if (run_command "$make $opt{$type}") {
223 die "failed make config";
226 if (defined($opt{"MIN_CONFIG"})) {
227 run_command "cat $opt{MIN_CONFIG} >> $opt{OUTPUT_DIR}/.config";
228 run_command "yes '' | $make oldconfig";
231 if (run_command "$make $opt{BUILD_OPTIONS}") {
236 read_config $ARGV[0];
239 die "MACHINE not defined\n" if (!defined($opt{"MACHINE"}));
240 die "SSH_USER not defined\n" if (!defined($opt{"SSH_USER"}));
241 die "BUILD_DIR not defined\n" if (!defined($opt{"BUILD_DIR"}));
242 die "OUTPUT_DIR not defined\n" if (!defined($opt{"OUTPUT_DIR"}));
243 die "BUILD_TARGET not defined\n" if (!defined($opt{"BUILD_TARGET"}));
244 die "POWER_CYCLE not defined\n" if (!defined($opt{"POWER_CYCLE"}));
245 die "CONSOLE not defined\n" if (!defined($opt{"CONSOLE"}));
246 die "LOCALVERSION not defined\n" if (!defined($opt{"LOCALVERSION"}));
247 die "GRUB_MENU not defined\n" if (!defined($opt{"GRUB_MENU"}));
249 chdir $opt{"BUILD_DIR"} || die "can't change directory to $opt{BUILD_DIR}";
251 $target = "$opt{SSH_USER}\@$opt{MACHINE}";
253 doprint "\n\nSTARTING AUTOMATED TESTS\n";
255 doprint "Find grub menu ... ";
257 open(IN, "ssh $target cat /boot/grub/menu.lst |")
258 or die "unable to get menu.lst";
260 if (/^\s*title\s+$opt{GRUB_MENU}\s*$/) {
263 } elsif (/^\s*title\s/) {
268 die "Could not find '$opt{GRUB_MENU}' in /boot/grub/menu on $opt{MACHINE}"
269 if ($grub_number < 0);
270 doprint "$grub_number\n";
272 $make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}";
274 # First we need to do is the builds
275 for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) {
276 my $type = "BUILD_TYPE[$i]";
278 if (!defined($opt{$type})) {
279 $opt{$type} = $opt{"DEFAULT_BUILD_TYPE"};
283 doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $opt{$type}\n\n";
285 if ($opt{$type} ne "nobuild") {
289 # get the release name
290 doprint "$make kernelrelease ... ";
291 $version = `$make kernelrelease | tail -1`;
293 doprint "$version\n";
295 # should we process modules?
297 open(IN, "$opt{OUTPUT_DIR}/.config") or die("Can't read config file");
299 if (/CONFIG_MODULES(=y)?/) {
300 $install_mods = 1 if (defined($1));
307 if (run_command "$make INSTALL_MOD_PATH=$opt{TMP_DIR} modules_install") {
308 die "Failed to install modules";
311 doprint "No modules needed\n";
318 doprint "\n\n*******************************************\n";
319 doprint "*******************************************\n";
320 doprint "** SUCCESS!!!! **\n";
321 doprint "*******************************************\n";
322 doprint "*******************************************\n";
324 # try to reboot normally
326 if (run_command "ssh $target reboot") {
327 # nope? power cycle it.
328 run_command "$opt{POWER_CYCLE}";
331 sleep "$opt{SLEEP_TIME}";