aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/testing/ktest/ktest.pl257
1 files changed, 170 insertions, 87 deletions
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index 0a0b1b16fccd..ff6283a44847 100644
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -7,6 +7,8 @@
7use strict; 7use strict;
8use IPC::Open2; 8use IPC::Open2;
9use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK); 9use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
10use File::Path qw(mkpath);
11use File::Copy qw(cp);
10use FileHandle; 12use FileHandle;
11 13
12$#ARGV >= 0 || die "usage: autotest.pl config-file\n"; 14$#ARGV >= 0 || die "usage: autotest.pl config-file\n";
@@ -17,7 +19,7 @@ my %opt;
17 19
18#default opts 20#default opts
19$opt{"NUM_BUILDS"} = 5; 21$opt{"NUM_BUILDS"} = 5;
20$opt{"DEFAULT_BUILD_TYPE"} = "randconfig"; 22$opt{"BUILD_TYPE"} = "randconfig";
21$opt{"MAKE_CMD"} = "make"; 23$opt{"MAKE_CMD"} = "make";
22$opt{"TIMEOUT"} = 120; 24$opt{"TIMEOUT"} = 120;
23$opt{"TMP_DIR"} = "/tmp/autotest"; 25$opt{"TMP_DIR"} = "/tmp/autotest";
@@ -35,6 +37,7 @@ $opt{"BOOTED_TIMEOUT"} = 1;
35$opt{"DIE_ON_FAILURE"} = 1; 37$opt{"DIE_ON_FAILURE"} = 1;
36 38
37my $version; 39my $version;
40my $build_type;
38my $grub_number; 41my $grub_number;
39my $target; 42my $target;
40my $make; 43my $make;
@@ -47,6 +50,11 @@ my $reverse_bisect;
47my $in_patchcheck = 0; 50my $in_patchcheck = 0;
48my $run_test; 51my $run_test;
49my $redirect; 52my $redirect;
53my $buildlog;
54my $dmesg;
55my $monitor_fp;
56my $monitor_pid;
57my $monitor_cnt = 0;
50 58
51sub read_config { 59sub read_config {
52 my ($config) = @_; 60 my ($config) = @_;
@@ -82,12 +90,22 @@ sub doprint {
82 logit @_; 90 logit @_;
83} 91}
84 92
93sub run_command;
94
95sub reboot {
96 # try to reboot normally
97 if (!run_command "ssh $target reboot") {
98 # nope? power cycle it.
99 run_command "$opt{POWER_CYCLE}";
100 }
101}
102
85sub dodie { 103sub dodie {
86 doprint "CRITICAL FAILURE... ", @_, "\n"; 104 doprint "CRITICAL FAILURE... ", @_, "\n";
87 105
88 if ($opt{"REBOOT_ON_ERROR"}) { 106 if ($opt{"REBOOT_ON_ERROR"}) {
89 doprint "REBOOTING\n"; 107 doprint "REBOOTING\n";
90 `$opt{"POWER_CYCLE"}`; 108 reboot;
91 109
92 } elsif ($opt{"POWEROFF_ON_ERROR"} && defined($opt{"POWER_OFF"})) { 110 } elsif ($opt{"POWEROFF_ON_ERROR"} && defined($opt{"POWER_OFF"})) {
93 doprint "POWERING OFF\n"; 111 doprint "POWERING OFF\n";
@@ -97,6 +115,59 @@ sub dodie {
97 die @_; 115 die @_;
98} 116}
99 117
118sub open_console {
119 my ($fp) = @_;
120
121 my $flags;
122
123 my $pid = open($fp, "$opt{CONSOLE}|") or
124 dodie "Can't open console $opt{CONSOLE}";
125
126 $flags = fcntl($fp, F_GETFL, 0) or
127 dodie "Can't get flags for the socket: $!\n";
128 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
129 dodie "Can't set flags for the socket: $!\n";
130
131 return $pid;
132}
133
134sub close_console {
135 my ($fp, $pid) = @_;
136
137 doprint "kill child process $pid\n";
138 kill 2, $pid;
139
140 print "closing!\n";
141 close($fp);
142}
143
144sub start_monitor {
145 if ($monitor_cnt++) {
146 return;
147 }
148 $monitor_fp = \*MONFD;
149 $monitor_pid = open_console $monitor_fp;
150}
151
152sub end_monitor {
153 if (--$monitor_cnt) {
154 return;
155 }
156 close_console($monitor_fp, $monitor_pid);
157}
158
159sub wait_for_monitor {
160 my ($time) = @_;
161 my $line;
162
163 doprint "Wait for monitor to settle down.\n";
164
165 # read the monitor and wait for the system to calm down
166 do {
167 $line = wait_for_input($monitor_fp, $time);
168 } while (defined($line));
169}
170
100sub fail { 171sub fail {
101 172
102 if ($opt{"DIE_ON_FAILURE"}) { 173 if ($opt{"DIE_ON_FAILURE"}) {
@@ -104,6 +175,41 @@ sub fail {
104 } 175 }
105 176
106 doprint "Failed: ", @_, "\n"; 177 doprint "Failed: ", @_, "\n";
178
179 doprint "REBOOTING\n";
180 reboot;
181 start_monitor;
182 wait_for_monitor $opt{"SLEEP_TIME"};
183 end_monitor;
184
185 return 1 if (!defined($opt{"STORE_FAILURES"}));
186
187 my @t = localtime;
188 my $date = sprintf "%04d%02d%02d%02d%02d%02d",
189 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
190
191 my $dir = "$opt{MACHINE}-$build_type-fail-$date";
192 my $faildir = "$opt{STORE_FAILURES}/$dir";
193
194 if (!-d $faildir) {
195 mkpath($faildir) or
196 die "can't create $opt{STORE_FAILURES}";
197 }
198 if (-f "$opt{OUTPUT_DIR}/.config") {
199 cp "$opt{OUTPUT_DIR}/.config", "$faildir/config" or
200 die "failed to copy .config";
201 }
202 if (-f $buildlog) {
203 cp $buildlog, "$faildir/buildlog" or
204 die "failed to move $buildlog";
205 }
206 if (-f $dmesg) {
207 cp $dmesg, "$faildir/dmesg" or
208 die "failed to move $dmesg";
209 }
210
211 doprint "*** Saved info to $faildir ***\n";
212
107 return 1; 213 return 1;
108} 214}
109 215
@@ -211,64 +317,34 @@ sub reboot_to {
211 run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; 317 run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
212} 318}
213 319
214sub open_console {
215 my ($fp) = @_;
216
217 my $flags;
218
219 my $pid = open($fp, "$opt{CONSOLE}|") or
220 dodie "Can't open console $opt{CONSOLE}";
221
222 $flags = fcntl($fp, F_GETFL, 0) or
223 dodie "Can't get flags for the socket: $!\n";
224 $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
225 dodie "Can't set flags for the socket: $!\n";
226
227 return $pid;
228}
229
230sub close_console {
231 my ($fp, $pid) = @_;
232
233 doprint "kill child process $pid\n";
234 kill 2, $pid;
235
236 print "closing!\n";
237 close($fp);
238}
239
240sub monitor { 320sub monitor {
241 my $booted = 0; 321 my $booted = 0;
242 my $bug = 0; 322 my $bug = 0;
243 my $pid;
244 my $skip_call_trace = 0; 323 my $skip_call_trace = 0;
245 my $fp = \*IN;
246 my $loops; 324 my $loops;
247 325
248 $pid = open_console($fp); 326 wait_for_monitor 5;
249 327
250 my $line; 328 my $line;
251 my $full_line = ""; 329 my $full_line = "";
252 330
253 doprint "Wait for monitor to settle down.\n"; 331 open(DMESG, "> $dmesg") or
254 # read the monitor and wait for the system to calm down 332 die "unable to write to $dmesg";
255 do {
256 $line = wait_for_input($fp, 5);
257 } while (defined($line));
258 333
259 reboot_to; 334 reboot_to;
260 335
261 for (;;) { 336 for (;;) {
262 337
263 if ($booted) { 338 if ($booted) {
264 $line = wait_for_input($fp, $opt{"BOOTED_TIMEOUT"}); 339 $line = wait_for_input($monitor_fp, $opt{"BOOTED_TIMEOUT"});
265 } else { 340 } else {
266 $line = wait_for_input($fp); 341 $line = wait_for_input($monitor_fp);
267 } 342 }
268 343
269 last if (!defined($line)); 344 last if (!defined($line));
270 345
271 doprint $line; 346 doprint $line;
347 print DMESG $line;
272 348
273 # we are not guaranteed to get a full line 349 # we are not guaranteed to get a full line
274 $full_line .= $line; 350 $full_line .= $line;
@@ -298,7 +374,7 @@ sub monitor {
298 } 374 }
299 } 375 }
300 376
301 close_console($fp, $pid); 377 close(DMESG);
302 378
303 if (!$booted) { 379 if (!$booted) {
304 return 0 if ($in_bisect); 380 return 0 if ($in_bisect);
@@ -363,7 +439,6 @@ sub install {
363sub check_buildlog { 439sub check_buildlog {
364 my ($patch) = @_; 440 my ($patch) = @_;
365 441
366 my $buildlog = "$opt{TMP_DIR}/buildlog";
367 my @files = `git show $patch | diffstat -l`; 442 my @files = `git show $patch | diffstat -l`;
368 443
369 open(IN, "git show $patch |") or 444 open(IN, "git show $patch |") or
@@ -398,6 +473,8 @@ sub build {
398 my $defconfig = ""; 473 my $defconfig = "";
399 my $append = ""; 474 my $append = "";
400 475
476 unlink $buildlog;
477
401 if ($type =~ /^useconfig:(.*)/) { 478 if ($type =~ /^useconfig:(.*)/) {
402 run_command "cp $1 $opt{OUTPUT_DIR}/.config" or 479 run_command "cp $1 $opt{OUTPUT_DIR}/.config" or
403 dodie "could not copy $1 to .config"; 480 dodie "could not copy $1 to .config";
@@ -440,11 +517,7 @@ sub build {
440 run_command "$defconfig $append $make $type" or 517 run_command "$defconfig $append $make $type" or
441 dodie "failed make config"; 518 dodie "failed make config";
442 519
443 # patch check will examine the log 520 $redirect = "$opt{TMP_DIR}/buildlog";
444 if ($in_patchcheck) {
445 $redirect = "$opt{TMP_DIR}/buildlog";
446 }
447
448 if (!run_command "$make $opt{BUILD_OPTIONS}") { 521 if (!run_command "$make $opt{BUILD_OPTIONS}") {
449 undef $redirect; 522 undef $redirect;
450 # bisect may need this to pass 523 # bisect may need this to pass
@@ -456,14 +529,6 @@ sub build {
456 return 1; 529 return 1;
457} 530}
458 531
459sub reboot {
460 # try to reboot normally
461 if (!run_command "ssh $target reboot") {
462 # nope? power cycle it.
463 run_command "$opt{POWER_CYCLE}";
464 }
465}
466
467sub halt { 532sub halt {
468 if (!run_command "ssh $target halt" or defined($opt{"POWER_OFF"})) { 533 if (!run_command "ssh $target halt" or defined($opt{"POWER_OFF"})) {
469 # nope? the zap it! 534 # nope? the zap it!
@@ -481,9 +546,11 @@ sub success {
481 doprint "*******************************************\n"; 546 doprint "*******************************************\n";
482 547
483 if ($i != $opt{"NUM_BUILDS"}) { 548 if ($i != $opt{"NUM_BUILDS"}) {
549 doprint "Reboot and wait $opt{SLEEP_TIME} seconds\n";
484 reboot; 550 reboot;
485 doprint "Sleeping $opt{SLEEP_TIME} seconds\n"; 551 start_monitor;
486 sleep "$opt{SLEEP_TIME}"; 552 wait_for_monitor $opt{"SLEEP_TIME"};
553 end_monitor;
487 } 554 }
488} 555}
489 556
@@ -496,9 +563,14 @@ sub get_version {
496} 563}
497 564
498sub child_run_test { 565sub child_run_test {
499 my $failed; 566 my $failed = 0;
500 567
501 $failed = !run_command $run_test; 568 # child should have no power
569 $opt{"REBOOT_ON_ERROR"} = 0;
570 $opt{"POWEROFF_ON_ERROR"} = 0;
571 $opt{"DIE_ON_FAILURE"} = 1;
572
573 run_command $run_test or $failed = 1;
502 exit $failed; 574 exit $failed;
503} 575}
504 576
@@ -511,18 +583,13 @@ sub child_finished {
511sub do_run_test { 583sub do_run_test {
512 my $child_pid; 584 my $child_pid;
513 my $child_exit; 585 my $child_exit;
514 my $pid;
515 my $line; 586 my $line;
516 my $full_line; 587 my $full_line;
517 my $bug = 0; 588 my $bug = 0;
518 my $fp = \*IN;
519 589
520 $pid = open_console($fp); 590 wait_for_monitor 1;
521 591
522 # read the monitor and wait for the system to calm down 592 doprint "run test $run_test\n";
523 do {
524 $line = wait_for_input($fp, 1);
525 } while (defined($line));
526 593
527 $child_done = 0; 594 $child_done = 0;
528 595
@@ -535,7 +602,7 @@ sub do_run_test {
535 $full_line = ""; 602 $full_line = "";
536 603
537 do { 604 do {
538 $line = wait_for_input($fp, 1); 605 $line = wait_for_input($monitor_fp, 1);
539 if (defined($line)) { 606 if (defined($line)) {
540 607
541 # we are not guaranteed to get a full line 608 # we are not guaranteed to get a full line
@@ -564,8 +631,6 @@ sub do_run_test {
564 waitpid $child_pid, 0; 631 waitpid $child_pid, 0;
565 $child_exit = $?; 632 $child_exit = $?;
566 633
567 close_console($fp, $pid);
568
569 if ($bug || $child_exit) { 634 if ($bug || $child_exit) {
570 return 0 if $in_bisect; 635 return 0 if $in_bisect;
571 fail "test failed" and return 0; 636 fail "test failed" and return 0;
@@ -589,19 +654,22 @@ sub run_bisect {
589 } 654 }
590 655
591 if ($type ne "build") { 656 if ($type ne "build") {
592 fail "Failed on build" if $failed; 657 dodie "Failed on build" if $failed;
593 658
594 # Now boot the box 659 # Now boot the box
595 get_grub_index; 660 get_grub_index;
596 get_version; 661 get_version;
597 install; 662 install;
663
664 start_monitor;
598 monitor or $failed = 1; 665 monitor or $failed = 1;
599 666
600 if ($type ne "boot") { 667 if ($type ne "boot") {
601 fail "Failed on boot" if $failed; 668 dodie "Failed on boot" if $failed;
602 669
603 do_run_test or $failed = 1; 670 do_run_test or $failed = 1;
604 } 671 }
672 end_monitor;
605 } 673 }
606 674
607 if ($failed) { 675 if ($failed) {
@@ -609,9 +677,11 @@ sub run_bisect {
609 677
610 # reboot the box to a good kernel 678 # reboot the box to a good kernel
611 if ($type eq "boot") { 679 if ($type eq "boot") {
680 doprint "Reboot and sleep $opt{BISECT_SLEEP_TIME} seconds\n";
612 reboot; 681 reboot;
613 doprint "sleep a little for reboot\n"; 682 start_monitor;
614 sleep $opt{"BISECT_SLEEP_TIME"}; 683 wait_for_monitor $opt{"BISECT_SLEEP_TIME"};
684 end_monitor;
615 } 685 }
616 } else { 686 } else {
617 $result = "good"; 687 $result = "good";
@@ -782,10 +852,18 @@ sub patchcheck {
782 get_grub_index; 852 get_grub_index;
783 get_version; 853 get_version;
784 install; 854 install;
785 monitor or return 0;
786 855
787 next if ($type eq "boot"); 856 my $failed = 0;
788 do_run_test or next; 857
858 start_monitor;
859 monitor or $failed = 1;
860
861 if (!$failed && $type ne "boot"){
862 do_run_test or $failed = 1;
863 }
864 end_monitor;
865 return 0 if ($failed);
866
789 } 867 }
790 $in_patchcheck = 0; 868 $in_patchcheck = 0;
791 success $i; 869 success $i;
@@ -821,6 +899,8 @@ foreach my $option (sort keys %opt) {
821 doprint "$option = $opt{$option}\n"; 899 doprint "$option = $opt{$option}\n";
822} 900}
823 901
902$buildlog = "$opt{TMP_DIR}/buildlog";
903$dmesg = "$opt{TMP_DIR}/dmesg";
824$make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}"; 904$make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}";
825 905
826sub set_build_option { 906sub set_build_option {
@@ -841,19 +921,18 @@ sub set_build_option {
841 921
842# First we need to do is the builds 922# First we need to do is the builds
843for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { 923for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) {
844 my $type = "BUILD_TYPE[$i]";
845
846 if (!defined($opt{$type})) {
847 $opt{$type} = $opt{"DEFAULT_BUILD_TYPE"};
848 }
849 924
925 $build_type = set_build_option("BUILD_TYPE", $i);
850 $noclean = set_build_option("BUILD_NOCLEAN", $i); 926 $noclean = set_build_option("BUILD_NOCLEAN", $i);
851 $minconfig = set_build_option("MIN_CONFIG", $i); 927 $minconfig = set_build_option("MIN_CONFIG", $i);
852 $run_test = set_build_option("TEST", $i); 928 $run_test = set_build_option("TEST", $i);
853 $addconfig = set_build_option("ADD_CONFIG", $i); 929 $addconfig = set_build_option("ADD_CONFIG", $i);
854 930
855 doprint "\n\n"; 931 doprint "\n\n";
856 doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $opt{$type}\n\n"; 932 doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $build_type\n\n";
933
934 unlink $dmesg;
935 unlink $buildlog;
857 936
858 if (!defined($minconfig)) { 937 if (!defined($minconfig)) {
859 $minconfig = $addconfig; 938 $minconfig = $addconfig;
@@ -870,26 +949,30 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) {
870 die "failed to checkout $checkout"; 949 die "failed to checkout $checkout";
871 } 950 }
872 951
873 if ($opt{$type} eq "bisect") { 952 if ($build_type eq "bisect") {
874 bisect $i; 953 bisect $i;
875 next; 954 next;
876 } elsif ($opt{$type} eq "patchcheck") { 955 } elsif ($build_type eq "patchcheck") {
877 patchcheck $i; 956 patchcheck $i;
878 next; 957 next;
879 } 958 }
880 959
881 if ($opt{$type} ne "nobuild") { 960 if ($build_type ne "nobuild") {
882 build $opt{$type} or next; 961 build $build_type or next;
883 } 962 }
884 963
885 get_grub_index; 964 get_grub_index;
886 get_version; 965 get_version;
887 install; 966 install;
888 monitor or next;
889 967
890 if (defined($run_test)) { 968 my $failed = 0;
891 do_run_test or next; 969 start_monitor;
970 monitor or $failed = 1;;
971 if (!$failed && defined($run_test)) {
972 do_run_test or $failed = 1;
892 } 973 }
974 end_monitor;
975 next if ($failed);
893 976
894 success $i; 977 success $i;
895} 978}