ktest.pl (5f9b6ced04a4e9c3ee6b4d4042ac5935ef5a8dbd) ktest.pl (5a391fbff8755592eb080784ef32ff818d2daa44)
1#!/usr/bin/perl -w
2
3use strict;
4use IPC::Open2;
5use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
6use FileHandle;
7
8$#ARGV >= 0 || die "usage: autotest.pl config-file\n";

--- 9 unchanged lines hidden (view full) ---

18$opt{"TIMEOUT"} = 50;
19$opt{"TMP_DIR"} = "/tmp/autotest";
20$opt{"SLEEP_TIME"} = 60; # sleep time between tests
21$opt{"BUILD_NOCLEAN"} = 0;
22$opt{"REBOOT_ON_ERROR"} = 0;
23$opt{"POWEROFF_ON_ERROR"} = 0;
24$opt{"POWEROFF_ON_SUCCESS"} = 0;
25$opt{"BUILD_OPTIONS"} = "";
1#!/usr/bin/perl -w
2
3use strict;
4use IPC::Open2;
5use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
6use FileHandle;
7
8$#ARGV >= 0 || die "usage: autotest.pl config-file\n";

--- 9 unchanged lines hidden (view full) ---

18$opt{"TIMEOUT"} = 50;
19$opt{"TMP_DIR"} = "/tmp/autotest";
20$opt{"SLEEP_TIME"} = 60; # sleep time between tests
21$opt{"BUILD_NOCLEAN"} = 0;
22$opt{"REBOOT_ON_ERROR"} = 0;
23$opt{"POWEROFF_ON_ERROR"} = 0;
24$opt{"POWEROFF_ON_SUCCESS"} = 0;
25$opt{"BUILD_OPTIONS"} = "";
26$opt{"BISECT_SLEEP_TIME"} = 10; # sleep time between bisects
26
27my $version;
28my $grub_number;
29my $target;
30my $make;
31my $noclean;
32my $minconfig;
33my $in_bisect = 0;
34my $bisect_bad = "";
27
28my $version;
29my $grub_number;
30my $target;
31my $make;
32my $noclean;
33my $minconfig;
34my $in_bisect = 0;
35my $bisect_bad = "";
36my $run_test;
35
36sub read_config {
37 my ($config) = @_;
38
39 open(IN, $config) || die "can't read file $config";
40
41 while (<IN>) {
42

--- 20 unchanged lines hidden (view full) ---

63}
64
65sub doprint {
66 print @_;
67 logit @_;
68}
69
70sub dodie {
37
38sub read_config {
39 my ($config) = @_;
40
41 open(IN, $config) || die "can't read file $config";
42
43 while (<IN>) {
44

--- 20 unchanged lines hidden (view full) ---

65}
66
67sub doprint {
68 print @_;
69 logit @_;
70}
71
72sub dodie {
71 doprint "CRITICAL FAILURE... ", @_;
73 doprint "CRITICAL FAILURE... ", @_, "\n";
72
73 if ($opt{"REBOOT_ON_ERROR"}) {
74 doprint "REBOOTING\n";
75 `$opt{"POWER_CYCLE"}`;
76
77 } elsif ($opt{"POWEROFF_ON_ERROR"} && defined($opt{"POWER_OFF"})) {
78 doprint "POWERING OFF\n";
79 `$opt{"POWER_OFF"}`;
80 }
81
82 die @_;
83}
84
85sub run_command {
86 my ($command) = @_;
74
75 if ($opt{"REBOOT_ON_ERROR"}) {
76 doprint "REBOOTING\n";
77 `$opt{"POWER_CYCLE"}`;
78
79 } elsif ($opt{"POWEROFF_ON_ERROR"} && defined($opt{"POWER_OFF"})) {
80 doprint "POWERING OFF\n";
81 `$opt{"POWER_OFF"}`;
82 }
83
84 die @_;
85}
86
87sub run_command {
88 my ($command) = @_;
87 my $redirect = "";
89 my $redirect_log = "";
88
89 if (defined($opt{"LOG_FILE"})) {
90
91 if (defined($opt{"LOG_FILE"})) {
90 $redirect = " >> $opt{LOG_FILE} 2>&1";
92 $redirect_log = " >> $opt{LOG_FILE} 2>&1";
91 }
92
93 doprint "$command ... ";
93 }
94
95 doprint "$command ... ";
94 `$command $redirect`;
96 `$command $redirect_log`;
95
96 my $failed = $?;
97
98 if ($failed) {
99 doprint "FAILED!\n";
100 } else {
101 doprint "SUCCESS\n";
102 }
103
104 return !$failed;
105}
106
107sub get_grub_index {
108
97
98 my $failed = $?;
99
100 if ($failed) {
101 doprint "FAILED!\n";
102 } else {
103 doprint "SUCCESS\n";
104 }
105
106 return !$failed;
107}
108
109sub get_grub_index {
110
109 return if ($grub_number >= 0);
111 return if (defined($grub_number));
110
111 doprint "Find grub menu ... ";
112 $grub_number = -1;
113 open(IN, "ssh $target cat /boot/grub/menu.lst |")
114 or die "unable to get menu.lst";
115 while (<IN>) {
116 if (/^\s*title\s+$opt{GRUB_MENU}\s*$/) {
117 $grub_number++;

--- 41 unchanged lines hidden (view full) ---

159
160 return $line;
161}
162
163sub reboot_to {
164 run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
165}
166
112
113 doprint "Find grub menu ... ";
114 $grub_number = -1;
115 open(IN, "ssh $target cat /boot/grub/menu.lst |")
116 or die "unable to get menu.lst";
117 while (<IN>) {
118 if (/^\s*title\s+$opt{GRUB_MENU}\s*$/) {
119 $grub_number++;

--- 41 unchanged lines hidden (view full) ---

161
162 return $line;
163}
164
165sub reboot_to {
166 run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
167}
168
167sub monitor {
169sub open_console {
170 my ($fp) = @_;
171
168 my $flags;
172 my $flags;
173
174 my $pid = open($fp, "$opt{CONSOLE}|") or
175 dodie "Can't open console $opt{CONSOLE}";
176
177 $flags = fcntl($fp, F_GETFL, 0) or
178 dodie "Can't get flags for the socket: $!\n";
179 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
180 dodie "Can't set flags for the socket: $!\n";
181
182 return $pid;
183}
184
185sub close_console {
186 my ($fp, $pid) = @_;
187
188 doprint "kill child process $pid\n";
189 kill 2, $pid;
190
191 print "closing!\n";
192 close($fp);
193}
194
195sub monitor {
169 my $booted = 0;
170 my $bug = 0;
171 my $pid;
196 my $booted = 0;
197 my $bug = 0;
198 my $pid;
172 my $doopen2 = 0;
173 my $skip_call_trace = 0;
199 my $skip_call_trace = 0;
200 my $fp = \*IN;
174
201
175 if ($doopen2) {
176 $pid = open2(\*IN, \*OUT, $opt{"CONSOLE"});
177 if ($pid < 0) {
178 dodie "Failed to connect to the console";
179 }
180 } else {
181 $pid = open(IN, "$opt{CONSOLE} |");
182 }
202 $pid = open_console($fp);
183
203
184 $flags = fcntl(IN, F_GETFL, 0) or
185 dodie "Can't get flags for the socket: $!\n";
186
187 $flags = fcntl(IN, F_SETFL, $flags | O_NONBLOCK) or
188 dodie "Can't set flags for the socket: $!\n";
189
190 my $line;
191 my $full_line = "";
192
193 doprint "Wait for monitor to settle down.\n";
194 # read the monitor and wait for the system to calm down
195 do {
204 my $line;
205 my $full_line = "";
206
207 doprint "Wait for monitor to settle down.\n";
208 # read the monitor and wait for the system to calm down
209 do {
196 $line = wait_for_input(\*IN, 5);
210 $line = wait_for_input($fp, 5);
197 } while (defined($line));
198
199 reboot_to;
200
201 for (;;) {
202
211 } while (defined($line));
212
213 reboot_to;
214
215 for (;;) {
216
203 $line = wait_for_input(\*IN);
217 $line = wait_for_input($fp);
204
205 last if (!defined($line));
206
207 doprint $line;
208
209 # we are not guaranteed to get a full line
210 $full_line .= $line;
211

--- 17 unchanged lines hidden (view full) ---

229 $bug = 1;
230 }
231
232 if ($line =~ /\n/) {
233 $full_line = "";
234 }
235 }
236
218
219 last if (!defined($line));
220
221 doprint $line;
222
223 # we are not guaranteed to get a full line
224 $full_line .= $line;
225

--- 17 unchanged lines hidden (view full) ---

243 $bug = 1;
244 }
245
246 if ($line =~ /\n/) {
247 $full_line = "";
248 }
249 }
250
237 doprint "kill child process $pid\n";
238 kill 2, $pid;
251 close_console($fp, $pid);
239
252
240 print "closing!\n";
241 close(IN);
242
243 if (!$booted) {
253 if (!$booted) {
244 return 1 if (!$in_bisect);
254 return 1 if ($in_bisect);
245 dodie "failed - never got a boot prompt.\n";
246 }
247
248 if ($bug) {
255 dodie "failed - never got a boot prompt.\n";
256 }
257
258 if ($bug) {
249 return 1 if (!$in_bisect);
259 return 1 if ($in_bisect);
250 dodie "failed - got a bug report\n";
251 }
252
253 return 0;
254}
255
256sub install {
257

--- 132 unchanged lines hidden (view full) ---

390sub get_version {
391 # get the release name
392 doprint "$make kernelrelease ... ";
393 $version = `$make kernelrelease | tail -1`;
394 chomp($version);
395 doprint "$version\n";
396}
397
260 dodie "failed - got a bug report\n";
261 }
262
263 return 0;
264}
265
266sub install {
267

--- 132 unchanged lines hidden (view full) ---

400sub get_version {
401 # get the release name
402 doprint "$make kernelrelease ... ";
403 $version = `$make kernelrelease | tail -1`;
404 chomp($version);
405 doprint "$version\n";
406}
407
408sub child_run_test {
409 my $failed;
410
411 $failed = !run_command $run_test;
412 exit $failed;
413}
414
415my $child_done;
416
417sub child_finished {
418 $child_done = 1;
419}
420
421sub do_run_test {
422 my $child_pid;
423 my $child_exit;
424 my $pid;
425 my $line;
426 my $full_line;
427 my $bug = 0;
428 my $fp = \*IN;
429
430 $pid = open_console($fp);
431
432 # read the monitor and wait for the system to calm down
433 do {
434 $line = wait_for_input($fp, 1);
435 } while (defined($line));
436
437 $child_done = 0;
438
439 $SIG{CHLD} = qw(child_finished);
440
441 $child_pid = fork;
442
443 child_run_test if (!$child_pid);
444
445 $full_line = "";
446
447 do {
448 $line = wait_for_input($fp, 1);
449 if (defined($line)) {
450
451 # we are not guaranteed to get a full line
452 $full_line .= $line;
453
454 if ($full_line =~ /call trace:/i) {
455 $bug = 1;
456 }
457
458 if ($full_line =~ /Kernel panic -/) {
459 $bug = 1;
460 }
461
462 if ($line =~ /\n/) {
463 $full_line = "";
464 }
465 }
466 } while (!$child_done && !$bug);
467
468 if ($bug) {
469 doprint "Detected kernel crash!\n";
470 # kill the child with extreme prejudice
471 kill 9, $child_pid;
472 }
473
474 waitpid $child_pid, 0;
475 $child_exit = $?;
476
477 close_console($fp, $pid);
478
479 if ($bug || $child_exit) {
480 return 1 if $in_bisect;
481 dodie "test failed";
482 }
483 return 0;
484}
485
398sub run_bisect {
399 my ($type) = @_;
400
401 my $failed;
402 my $result;
403 my $output;
404 my $ret;
405

--- 11 unchanged lines hidden (view full) ---

417 # Now boot the box
418 get_grub_index;
419 get_version;
420 install;
421 $failed = monitor;
422
423 if ($type ne "boot") {
424 dodie "Failed on boot" if $failed;
486sub run_bisect {
487 my ($type) = @_;
488
489 my $failed;
490 my $result;
491 my $output;
492 my $ret;
493

--- 11 unchanged lines hidden (view full) ---

505 # Now boot the box
506 get_grub_index;
507 get_version;
508 install;
509 $failed = monitor;
510
511 if ($type ne "boot") {
512 dodie "Failed on boot" if $failed;
513
514 $failed = do_run_test;
425 }
426 }
427
428 if ($failed) {
429 $result = "bad";
515 }
516 }
517
518 if ($failed) {
519 $result = "bad";
520
521 # reboot the box to a good kernel
522 if ($type eq "boot") {
523 reboot;
524 doprint "sleep a little for reboot\n";
525 sleep $opt{"BISECT_SLEEP_TIME"};
526 }
430 } else {
431 $result = "good";
432 }
433
434 doprint "git bisect $result ... ";
435 $output = `git bisect $result 2>&1`;
436 $ret = $?;
437
438 logit $output;
439
440 if ($ret) {
441 doprint "FAILED\n";
442 dodie "Failed to git bisect";
443 }
444
445 doprint "SUCCESS\n";
527 } else {
528 $result = "good";
529 }
530
531 doprint "git bisect $result ... ";
532 $output = `git bisect $result 2>&1`;
533 $ret = $?;
534
535 logit $output;
536
537 if ($ret) {
538 doprint "FAILED\n";
539 dodie "Failed to git bisect";
540 }
541
542 doprint "SUCCESS\n";
446 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\)) \[([[:xdigit:]]+)\]/) {
543 if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
447 doprint "$1 [$2]\n";
448 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
449 $bisect_bad = $1;
450 doprint "Found bad commit... $1\n";
451 return 0;
544 doprint "$1 [$2]\n";
545 } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
546 $bisect_bad = $1;
547 doprint "Found bad commit... $1\n";
548 return 0;
549 } else {
550 # we already logged it, just print it now.
551 print $output;
452 }
453
454
455 return 1;
456}
457
458sub bisect {
459 my ($i) = @_;

--- 14 unchanged lines hidden (view full) ---

474 dodie "could not start bisect";
475
476 run_command "git bisect good $good" or
477 dodie "could not set bisect good to $good";
478
479 run_command "git bisect bad $bad" or
480 dodie "could not set bisect good to $bad";
481
552 }
553
554
555 return 1;
556}
557
558sub bisect {
559 my ($i) = @_;

--- 14 unchanged lines hidden (view full) ---

574 dodie "could not start bisect";
575
576 run_command "git bisect good $good" or
577 dodie "could not set bisect good to $good";
578
579 run_command "git bisect bad $bad" or
580 dodie "could not set bisect good to $bad";
581
582 # Can't have a test without having a test to run
583 if ($type eq "test" && !defined($run_test)) {
584 $type = "boot";
585 }
586
482 do {
483 $result = run_bisect $type;
484 } while ($result);
485
486 run_command "git bisect log" or
487 dodie "could not capture git bisect log";
488
489 run_command "git bisect reset" or

--- 24 unchanged lines hidden (view full) ---

514
515$target = "$opt{SSH_USER}\@$opt{MACHINE}";
516
517doprint "\n\nSTARTING AUTOMATED TESTS\n";
518
519
520$make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}";
521
587 do {
588 $result = run_bisect $type;
589 } while ($result);
590
591 run_command "git bisect log" or
592 dodie "could not capture git bisect log";
593
594 run_command "git bisect reset" or

--- 24 unchanged lines hidden (view full) ---

619
620$target = "$opt{SSH_USER}\@$opt{MACHINE}";
621
622doprint "\n\nSTARTING AUTOMATED TESTS\n";
623
624
625$make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}";
626
522# First we need to do is the builds
523for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) {
524 my $type = "BUILD_TYPE[$i]";
627sub set_build_option {
628 my ($name, $i) = @_;
525
629
526 if (defined($opt{"BUILD_NOCLEAN[$i]"}) &&
527 $opt{"BUILD_NOCLEAN[$i]"} != 0) {
528 $noclean = 1;
529 } else {
530 $noclean = $opt{"BUILD_NOCLEAN"};
531 }
630 my $option = "$name\[$i\]";
532
631
533 if (defined($opt{"MIN_CONFIG[$i]"})) {
534 $minconfig = $opt{"MIN_CONFIG[$i]"};
535 } elsif (defined($opt{"MIN_CONFIG"})) {
536 $minconfig = $opt{"MIN_CONFIG"};
537 } else {
538 undef $minconfig;
632 if (defined($opt{$option})) {
633 return $opt{$option};
539 }
540
634 }
635
541 if (!defined($opt{$type})) {
542 $opt{$type} = $opt{"DEFAULT_BUILD_TYPE"};
636 if (defined($opt{$name})) {
637 return $opt{$name};
543 }
544
638 }
639
640 return undef;
641}
642
643# First we need to do is the builds
644for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) {
645 my $type = "BUILD_TYPE[$i]";
646
647 $noclean = set_build_option("BUILD_NOCLEAN", $i);
648 $minconfig = set_build_option("MIN_CONFIG", $i);
649 $run_test = set_build_option("TEST", $i);
650
545 doprint "\n\n";
546 doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $opt{$type}\n\n";
547
548 if ($opt{$type} eq "bisect") {
549 bisect $i;
550 next;
551 }
552
553 if ($opt{$type} ne "nobuild") {
554 build $opt{$type};
555 }
556
557 get_grub_index;
558 get_version;
559 install;
560 monitor;
651 doprint "\n\n";
652 doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $opt{$type}\n\n";
653
654 if ($opt{$type} eq "bisect") {
655 bisect $i;
656 next;
657 }
658
659 if ($opt{$type} ne "nobuild") {
660 build $opt{$type};
661 }
662
663 get_grub_index;
664 get_version;
665 install;
666 monitor;
667
668 if (defined($run_test)) {
669 do_run_test;
670 }
671
561 success $i;
562}
563
564if ($opt{"POWEROFF_ON_SUCCESS"}) {
565 halt;
566} else {
567 reboot;
568}
569
570exit 0;
672 success $i;
673}
674
675if ($opt{"POWEROFF_ON_SUCCESS"}) {
676 halt;
677} else {
678 reboot;
679}
680
681exit 0;