ktest.pl 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207
  1. #!/usr/bin/perl -w
  2. #
  3. # Copywrite 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
  4. # Licensed under the terms of the GNU GPL License version 2
  5. #
  6. use strict;
  7. use IPC::Open2;
  8. use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
  9. use File::Path qw(mkpath);
  10. use File::Copy qw(cp);
  11. use FileHandle;
  12. $#ARGV >= 0 || die "usage: autotest.pl config-file\n";
  13. $| = 1;
  14. my %opt;
  15. my %default;
  16. #default opts
  17. $default{"NUM_TESTS"} = 5;
  18. $default{"REBOOT_TYPE"} = "grub";
  19. $default{"TEST_TYPE"} = "test";
  20. $default{"BUILD_TYPE"} = "randconfig";
  21. $default{"MAKE_CMD"} = "make";
  22. $default{"TIMEOUT"} = 120;
  23. $default{"TMP_DIR"} = "/tmp/autotest";
  24. $default{"SLEEP_TIME"} = 60; # sleep time between tests
  25. $default{"BUILD_NOCLEAN"} = 0;
  26. $default{"REBOOT_ON_ERROR"} = 0;
  27. $default{"POWEROFF_ON_ERROR"} = 0;
  28. $default{"REBOOT_ON_SUCCESS"} = 1;
  29. $default{"POWEROFF_ON_SUCCESS"} = 0;
  30. $default{"BUILD_OPTIONS"} = "";
  31. $default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects
  32. $default{"CLEAR_LOG"} = 0;
  33. $default{"SUCCESS_LINE"} = "login:";
  34. $default{"BOOTED_TIMEOUT"} = 1;
  35. $default{"DIE_ON_FAILURE"} = 1;
  36. my $version;
  37. my $machine;
  38. my $tmpdir;
  39. my $builddir;
  40. my $outputdir;
  41. my $test_type;
  42. my $build_type;
  43. my $build_options;
  44. my $reboot_type;
  45. my $reboot_script;
  46. my $power_cycle;
  47. my $reboot_on_error;
  48. my $poweroff_on_error;
  49. my $die_on_failure;
  50. my $powercycle_after_reboot;
  51. my $poweroff_after_halt;
  52. my $power_off;
  53. my $grub_menu;
  54. my $grub_number;
  55. my $target;
  56. my $make;
  57. my $post_install;
  58. my $noclean;
  59. my $minconfig;
  60. my $addconfig;
  61. my $in_bisect = 0;
  62. my $bisect_bad = "";
  63. my $reverse_bisect;
  64. my $in_patchcheck = 0;
  65. my $run_test;
  66. my $redirect;
  67. my $buildlog;
  68. my $dmesg;
  69. my $monitor_fp;
  70. my $monitor_pid;
  71. my $monitor_cnt = 0;
  72. my $sleep_time;
  73. my $bisect_sleep_time;
  74. my $store_failures;
  75. my $timeout;
  76. my $booted_timeout;
  77. my $console;
  78. my $success_line;
  79. my $build_target;
  80. my $target_image;
  81. my $localversion;
  82. my $iteration = 0;
  83. sub read_config {
  84. my ($config) = @_;
  85. open(IN, $config) || die "can't read file $config";
  86. while (<IN>) {
  87. # ignore blank lines and comments
  88. next if (/^\s*$/ || /\s*\#/);
  89. if (/^\s*(\S+)\s*=\s*(.*?)\s*$/) {
  90. my $lvalue = $1;
  91. my $rvalue = $2;
  92. if (defined($opt{$lvalue})) {
  93. die "Error: Option $lvalue defined more than once!\n";
  94. }
  95. $opt{$lvalue} = $rvalue;
  96. }
  97. }
  98. close(IN);
  99. # set any defaults
  100. foreach my $default (keys %default) {
  101. if (!defined($opt{$default})) {
  102. $opt{$default} = $default{$default};
  103. }
  104. }
  105. }
  106. sub logit {
  107. if (defined($opt{"LOG_FILE"})) {
  108. open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
  109. print OUT @_;
  110. close(OUT);
  111. }
  112. }
  113. sub doprint {
  114. print @_;
  115. logit @_;
  116. }
  117. sub run_command;
  118. sub reboot {
  119. # try to reboot normally
  120. if (run_command "ssh $target reboot") {
  121. if (defined($powercycle_after_reboot)) {
  122. sleep $powercycle_after_reboot;
  123. run_command "$power_cycle";
  124. }
  125. } else {
  126. # nope? power cycle it.
  127. run_command "$power_cycle";
  128. }
  129. }
  130. sub do_not_reboot {
  131. my $i = $iteration;
  132. return $test_type eq "build" ||
  133. ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") ||
  134. ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build");
  135. }
  136. sub dodie {
  137. doprint "CRITICAL FAILURE... ", @_, "\n";
  138. my $i = $iteration;
  139. if ($reboot_on_error && !do_not_reboot) {
  140. doprint "REBOOTING\n";
  141. reboot;
  142. } elsif ($poweroff_on_error && defined($power_off)) {
  143. doprint "POWERING OFF\n";
  144. `$power_off`;
  145. }
  146. die @_, "\n";
  147. }
  148. sub open_console {
  149. my ($fp) = @_;
  150. my $flags;
  151. my $pid = open($fp, "$console|") or
  152. dodie "Can't open console $console";
  153. $flags = fcntl($fp, F_GETFL, 0) or
  154. dodie "Can't get flags for the socket: $!";
  155. $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
  156. dodie "Can't set flags for the socket: $!";
  157. return $pid;
  158. }
  159. sub close_console {
  160. my ($fp, $pid) = @_;
  161. doprint "kill child process $pid\n";
  162. kill 2, $pid;
  163. print "closing!\n";
  164. close($fp);
  165. }
  166. sub start_monitor {
  167. if ($monitor_cnt++) {
  168. return;
  169. }
  170. $monitor_fp = \*MONFD;
  171. $monitor_pid = open_console $monitor_fp;
  172. return;
  173. open(MONFD, "Stop perl from warning about single use of MONFD");
  174. }
  175. sub end_monitor {
  176. if (--$monitor_cnt) {
  177. return;
  178. }
  179. close_console($monitor_fp, $monitor_pid);
  180. }
  181. sub wait_for_monitor {
  182. my ($time) = @_;
  183. my $line;
  184. doprint "** Wait for monitor to settle down **\n";
  185. # read the monitor and wait for the system to calm down
  186. do {
  187. $line = wait_for_input($monitor_fp, $time);
  188. print "$line" if (defined($line));
  189. } while (defined($line));
  190. print "** Monitor flushed **\n";
  191. }
  192. sub fail {
  193. if ($die_on_failure) {
  194. dodie @_;
  195. }
  196. doprint "FAILED\n";
  197. my $i = $iteration;
  198. # no need to reboot for just building.
  199. if (!do_not_reboot) {
  200. doprint "REBOOTING\n";
  201. reboot;
  202. start_monitor;
  203. wait_for_monitor $sleep_time;
  204. end_monitor;
  205. }
  206. doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
  207. doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
  208. doprint "**** Failed: ", @_, " ****\n";
  209. doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
  210. doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
  211. return 1 if (!defined($store_failures));
  212. my @t = localtime;
  213. my $date = sprintf "%04d%02d%02d%02d%02d%02d",
  214. 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0];
  215. my $dir = "$machine-$test_type-$build_type-fail-$date";
  216. my $faildir = "$store_failures/$dir";
  217. if (!-d $faildir) {
  218. mkpath($faildir) or
  219. die "can't create $faildir";
  220. }
  221. if (-f "$outputdir/.config") {
  222. cp "$outputdir/.config", "$faildir/config" or
  223. die "failed to copy .config";
  224. }
  225. if (-f $buildlog) {
  226. cp $buildlog, "$faildir/buildlog" or
  227. die "failed to move $buildlog";
  228. }
  229. if (-f $dmesg) {
  230. cp $dmesg, "$faildir/dmesg" or
  231. die "failed to move $dmesg";
  232. }
  233. doprint "*** Saved info to $faildir ***\n";
  234. return 1;
  235. }
  236. sub run_command {
  237. my ($command) = @_;
  238. my $dolog = 0;
  239. my $dord = 0;
  240. my $pid;
  241. doprint("$command ... ");
  242. $pid = open(CMD, "$command 2>&1 |") or
  243. (fail "unable to exec $command" and return 0);
  244. if (defined($opt{"LOG_FILE"})) {
  245. open(LOG, ">>$opt{LOG_FILE}") or
  246. dodie "failed to write to log";
  247. $dolog = 1;
  248. }
  249. if (defined($redirect)) {
  250. open (RD, ">$redirect") or
  251. dodie "failed to write to redirect $redirect";
  252. $dord = 1;
  253. }
  254. while (<CMD>) {
  255. print LOG if ($dolog);
  256. print RD if ($dord);
  257. }
  258. waitpid($pid, 0);
  259. my $failed = $?;
  260. close(CMD);
  261. close(LOG) if ($dolog);
  262. close(RD) if ($dord);
  263. if ($failed) {
  264. doprint "FAILED!\n";
  265. } else {
  266. doprint "SUCCESS\n";
  267. }
  268. return !$failed;
  269. }
  270. sub get_grub_index {
  271. if ($reboot_type ne "grub") {
  272. return;
  273. }
  274. return if (defined($grub_number));
  275. doprint "Find grub menu ... ";
  276. $grub_number = -1;
  277. open(IN, "ssh $target cat /boot/grub/menu.lst |")
  278. or die "unable to get menu.lst";
  279. while (<IN>) {
  280. if (/^\s*title\s+$grub_menu\s*$/) {
  281. $grub_number++;
  282. last;
  283. } elsif (/^\s*title\s/) {
  284. $grub_number++;
  285. }
  286. }
  287. close(IN);
  288. die "Could not find '$grub_menu' in /boot/grub/menu on $machine"
  289. if ($grub_number < 0);
  290. doprint "$grub_number\n";
  291. }
  292. sub wait_for_input
  293. {
  294. my ($fp, $time) = @_;
  295. my $rin;
  296. my $ready;
  297. my $line;
  298. my $ch;
  299. if (!defined($time)) {
  300. $time = $timeout;
  301. }
  302. $rin = '';
  303. vec($rin, fileno($fp), 1) = 1;
  304. $ready = select($rin, undef, undef, $time);
  305. $line = "";
  306. # try to read one char at a time
  307. while (sysread $fp, $ch, 1) {
  308. $line .= $ch;
  309. last if ($ch eq "\n");
  310. }
  311. if (!length($line)) {
  312. return undef;
  313. }
  314. return $line;
  315. }
  316. sub reboot_to {
  317. if ($reboot_type eq "grub") {
  318. run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
  319. return;
  320. }
  321. run_command "$reboot_script";
  322. }
  323. sub monitor {
  324. my $booted = 0;
  325. my $bug = 0;
  326. my $skip_call_trace = 0;
  327. my $loops;
  328. wait_for_monitor 5;
  329. my $line;
  330. my $full_line = "";
  331. open(DMESG, "> $dmesg") or
  332. die "unable to write to $dmesg";
  333. reboot_to;
  334. for (;;) {
  335. if ($booted) {
  336. $line = wait_for_input($monitor_fp, $booted_timeout);
  337. } else {
  338. $line = wait_for_input($monitor_fp);
  339. }
  340. last if (!defined($line));
  341. doprint $line;
  342. print DMESG $line;
  343. # we are not guaranteed to get a full line
  344. $full_line .= $line;
  345. if ($full_line =~ /$success_line/) {
  346. $booted = 1;
  347. }
  348. if ($full_line =~ /\[ backtrace testing \]/) {
  349. $skip_call_trace = 1;
  350. }
  351. if ($full_line =~ /call trace:/i) {
  352. $bug = 1 if (!$skip_call_trace);
  353. }
  354. if ($full_line =~ /\[ end of backtrace testing \]/) {
  355. $skip_call_trace = 0;
  356. }
  357. if ($full_line =~ /Kernel panic -/) {
  358. $bug = 1;
  359. }
  360. if ($line =~ /\n/) {
  361. $full_line = "";
  362. }
  363. }
  364. close(DMESG);
  365. if ($bug) {
  366. return 0 if ($in_bisect);
  367. fail "failed - got a bug report" and return 0;
  368. }
  369. if (!$booted) {
  370. return 0 if ($in_bisect);
  371. fail "failed - never got a boot prompt." and return 0;
  372. }
  373. return 1;
  374. }
  375. sub install {
  376. run_command "scp $outputdir/$build_target $target:$target_image" or
  377. dodie "failed to copy image";
  378. my $install_mods = 0;
  379. # should we process modules?
  380. $install_mods = 0;
  381. open(IN, "$outputdir/.config") or dodie("Can't read config file");
  382. while (<IN>) {
  383. if (/CONFIG_MODULES(=y)?/) {
  384. $install_mods = 1 if (defined($1));
  385. last;
  386. }
  387. }
  388. close(IN);
  389. if (!$install_mods) {
  390. doprint "No modules needed\n";
  391. return;
  392. }
  393. run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or
  394. dodie "Failed to install modules";
  395. my $modlib = "/lib/modules/$version";
  396. my $modtar = "autotest-mods.tar.bz2";
  397. run_command "ssh $target rm -rf $modlib" or
  398. dodie "failed to remove old mods: $modlib";
  399. # would be nice if scp -r did not follow symbolic links
  400. run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
  401. dodie "making tarball";
  402. run_command "scp $tmpdir/$modtar $target:/tmp" or
  403. dodie "failed to copy modules";
  404. unlink "$tmpdir/$modtar";
  405. run_command "ssh $target '(cd / && tar xf /tmp/$modtar)'" or
  406. dodie "failed to tar modules";
  407. run_command "ssh $target rm -f /tmp/$modtar";
  408. return if (!defined($post_install));
  409. my $save_env = $ENV{KERNEL_VERSION};
  410. $ENV{KERNEL_VERSION} = $version;
  411. run_command "$post_install" or
  412. dodie "Failed to run post install";
  413. $ENV{KERNEL_VERSION} = $save_env;
  414. }
  415. sub check_buildlog {
  416. my ($patch) = @_;
  417. my @files = `git show $patch | diffstat -l`;
  418. open(IN, "git show $patch |") or
  419. dodie "failed to show $patch";
  420. while (<IN>) {
  421. if (m,^--- a/(.*),) {
  422. chomp $1;
  423. $files[$#files] = $1;
  424. }
  425. }
  426. close(IN);
  427. open(IN, $buildlog) or dodie "Can't open $buildlog";
  428. while (<IN>) {
  429. if (/^\s*(.*?):.*(warning|error)/) {
  430. my $err = $1;
  431. foreach my $file (@files) {
  432. my $fullpath = "$builddir/$file";
  433. if ($file eq $err || $fullpath eq $err) {
  434. fail "$file built with warnings" and return 0;
  435. }
  436. }
  437. }
  438. }
  439. close(IN);
  440. return 1;
  441. }
  442. sub build {
  443. my ($type) = @_;
  444. my $defconfig = "";
  445. my $append = "";
  446. unlink $buildlog;
  447. if ($type =~ /^useconfig:(.*)/) {
  448. run_command "cp $1 $outputdir/.config" or
  449. dodie "could not copy $1 to .config";
  450. $type = "oldconfig";
  451. }
  452. # old config can ask questions
  453. if ($type eq "oldconfig") {
  454. $append = "yes ''|";
  455. # allow for empty configs
  456. run_command "touch $outputdir/.config";
  457. run_command "mv $outputdir/.config $outputdir/config_temp" or
  458. dodie "moving .config";
  459. if (!$noclean && !run_command "$make mrproper") {
  460. dodie "make mrproper";
  461. }
  462. run_command "mv $outputdir/config_temp $outputdir/.config" or
  463. dodie "moving config_temp";
  464. } elsif (!$noclean) {
  465. unlink "$outputdir/.config";
  466. run_command "$make mrproper" or
  467. dodie "make mrproper";
  468. }
  469. # add something to distinguish this build
  470. open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file");
  471. print OUT "$localversion\n";
  472. close(OUT);
  473. if (defined($minconfig)) {
  474. $defconfig = "KCONFIG_ALLCONFIG=$minconfig";
  475. }
  476. run_command "$append $defconfig $make $type" or
  477. dodie "failed make config";
  478. $redirect = "$buildlog";
  479. if (!run_command "$make $build_options") {
  480. undef $redirect;
  481. # bisect may need this to pass
  482. return 0 if ($in_bisect);
  483. fail "failed build" and return 0;
  484. }
  485. undef $redirect;
  486. return 1;
  487. }
  488. sub halt {
  489. if (!run_command "ssh $target halt" or defined($power_off)) {
  490. if (defined($poweroff_after_halt)) {
  491. sleep $poweroff_after_halt;
  492. run_command "$power_off";
  493. }
  494. } else {
  495. # nope? the zap it!
  496. run_command "$power_off";
  497. }
  498. }
  499. sub success {
  500. my ($i) = @_;
  501. doprint "\n\n*******************************************\n";
  502. doprint "*******************************************\n";
  503. doprint "** TEST $i SUCCESS!!!! **\n";
  504. doprint "*******************************************\n";
  505. doprint "*******************************************\n";
  506. if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) {
  507. doprint "Reboot and wait $sleep_time seconds\n";
  508. reboot;
  509. start_monitor;
  510. wait_for_monitor $sleep_time;
  511. end_monitor;
  512. }
  513. }
  514. sub get_version {
  515. # get the release name
  516. doprint "$make kernelrelease ... ";
  517. $version = `$make kernelrelease | tail -1`;
  518. chomp($version);
  519. doprint "$version\n";
  520. }
  521. sub child_run_test {
  522. my $failed = 0;
  523. # child should have no power
  524. $reboot_on_error = 0;
  525. $poweroff_on_error = 0;
  526. $die_on_failure = 1;
  527. run_command $run_test or $failed = 1;
  528. exit $failed;
  529. }
  530. my $child_done;
  531. sub child_finished {
  532. $child_done = 1;
  533. }
  534. sub do_run_test {
  535. my $child_pid;
  536. my $child_exit;
  537. my $line;
  538. my $full_line;
  539. my $bug = 0;
  540. wait_for_monitor 1;
  541. doprint "run test $run_test\n";
  542. $child_done = 0;
  543. $SIG{CHLD} = qw(child_finished);
  544. $child_pid = fork;
  545. child_run_test if (!$child_pid);
  546. $full_line = "";
  547. do {
  548. $line = wait_for_input($monitor_fp, 1);
  549. if (defined($line)) {
  550. # we are not guaranteed to get a full line
  551. $full_line .= $line;
  552. if ($full_line =~ /call trace:/i) {
  553. $bug = 1;
  554. }
  555. if ($full_line =~ /Kernel panic -/) {
  556. $bug = 1;
  557. }
  558. if ($line =~ /\n/) {
  559. $full_line = "";
  560. }
  561. }
  562. } while (!$child_done && !$bug);
  563. if ($bug) {
  564. doprint "Detected kernel crash!\n";
  565. # kill the child with extreme prejudice
  566. kill 9, $child_pid;
  567. }
  568. waitpid $child_pid, 0;
  569. $child_exit = $?;
  570. if ($bug || $child_exit) {
  571. return 0 if $in_bisect;
  572. fail "test failed" and return 0;
  573. }
  574. return 1;
  575. }
  576. sub run_git_bisect {
  577. my ($command) = @_;
  578. doprint "$command ... ";
  579. my $output = `$command 2>&1`;
  580. my $ret = $?;
  581. logit $output;
  582. if ($ret) {
  583. doprint "FAILED\n";
  584. dodie "Failed to git bisect";
  585. }
  586. doprint "SUCCESS\n";
  587. if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
  588. doprint "$1 [$2]\n";
  589. } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
  590. $bisect_bad = $1;
  591. doprint "Found bad commit... $1\n";
  592. return 0;
  593. } else {
  594. # we already logged it, just print it now.
  595. print $output;
  596. }
  597. return 1;
  598. }
  599. sub run_bisect {
  600. my ($type) = @_;
  601. my $failed = 0;
  602. my $result;
  603. my $output;
  604. my $ret;
  605. if (defined($minconfig)) {
  606. build "useconfig:$minconfig" or $failed = 1;
  607. } else {
  608. # ?? no config to use?
  609. build "oldconfig" or $failed = 1;
  610. }
  611. if ($type ne "build") {
  612. dodie "Failed on build" if $failed;
  613. # Now boot the box
  614. get_grub_index;
  615. get_version;
  616. install;
  617. start_monitor;
  618. monitor or $failed = 1;
  619. if ($type ne "boot") {
  620. dodie "Failed on boot" if $failed;
  621. do_run_test or $failed = 1;
  622. }
  623. end_monitor;
  624. }
  625. if ($failed) {
  626. $result = "bad";
  627. # reboot the box to a good kernel
  628. if ($type ne "build") {
  629. doprint "Reboot and sleep $bisect_sleep_time seconds\n";
  630. reboot;
  631. start_monitor;
  632. wait_for_monitor $bisect_sleep_time;
  633. end_monitor;
  634. }
  635. } else {
  636. $result = "good";
  637. }
  638. # Are we looking for where it worked, not failed?
  639. if ($reverse_bisect) {
  640. if ($failed) {
  641. $result = "good";
  642. } else {
  643. $result = "bad";
  644. }
  645. }
  646. return $result;
  647. }
  648. sub bisect {
  649. my ($i) = @_;
  650. my $result;
  651. die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"}));
  652. die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"}));
  653. die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"}));
  654. my $good = $opt{"BISECT_GOOD[$i]"};
  655. my $bad = $opt{"BISECT_BAD[$i]"};
  656. my $type = $opt{"BISECT_TYPE[$i]"};
  657. my $start = $opt{"BISECT_START[$i]"};
  658. my $replay = $opt{"BISECT_REPLAY[$i]"};
  659. if (defined($opt{"BISECT_REVERSE[$i]"}) &&
  660. $opt{"BISECT_REVERSE[$i]"} == 1) {
  661. doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
  662. $reverse_bisect = 1;
  663. } else {
  664. $reverse_bisect = 0;
  665. }
  666. $in_bisect = 1;
  667. # Can't have a test without having a test to run
  668. if ($type eq "test" && !defined($run_test)) {
  669. $type = "boot";
  670. }
  671. my $check = $opt{"BISECT_CHECK[$i]"};
  672. if (defined($check) && $check ne "0") {
  673. # get current HEAD
  674. doprint "git rev-list HEAD --max-count=1 ... ";
  675. my $head = `git rev-list HEAD --max-count=1`;
  676. my $ret = $?;
  677. logit $head;
  678. if ($ret) {
  679. doprint "FAILED\n";
  680. dodie "Failed to get git HEAD";
  681. }
  682. print "SUCCESS\n";
  683. chomp $head;
  684. if ($check ne "good") {
  685. doprint "TESTING BISECT BAD [$bad]\n";
  686. run_command "git checkout $bad" or
  687. die "Failed to checkout $bad";
  688. $result = run_bisect $type;
  689. if ($result ne "bad") {
  690. fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0;
  691. }
  692. }
  693. if ($check ne "bad") {
  694. doprint "TESTING BISECT GOOD [$good]\n";
  695. run_command "git checkout $good" or
  696. die "Failed to checkout $good";
  697. $result = run_bisect $type;
  698. if ($result ne "good") {
  699. fail "Tested BISECT_GOOD [$good] and it failed" and return 0;
  700. }
  701. }
  702. # checkout where we started
  703. run_command "git checkout $head" or
  704. die "Failed to checkout $head";
  705. }
  706. run_command "git bisect start" or
  707. dodie "could not start bisect";
  708. run_command "git bisect good $good" or
  709. dodie "could not set bisect good to $good";
  710. run_git_bisect "git bisect bad $bad" or
  711. dodie "could not set bisect bad to $bad";
  712. if (defined($replay)) {
  713. run_command "git bisect replay $replay" or
  714. dodie "failed to run replay";
  715. }
  716. if (defined($start)) {
  717. run_command "git checkout $start" or
  718. dodie "failed to checkout $start";
  719. }
  720. my $test;
  721. do {
  722. $result = run_bisect $type;
  723. $test = run_git_bisect "git bisect $result";
  724. } while ($test);
  725. run_command "git bisect log" or
  726. dodie "could not capture git bisect log";
  727. run_command "git bisect reset" or
  728. dodie "could not reset git bisect";
  729. doprint "Bad commit was [$bisect_bad]\n";
  730. $in_bisect = 0;
  731. success $i;
  732. }
  733. sub patchcheck {
  734. my ($i) = @_;
  735. die "PATCHCHECK_START[$i] not defined\n"
  736. if (!defined($opt{"PATCHCHECK_START[$i]"}));
  737. die "PATCHCHECK_TYPE[$i] not defined\n"
  738. if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
  739. my $start = $opt{"PATCHCHECK_START[$i]"};
  740. my $end = "HEAD";
  741. if (defined($opt{"PATCHCHECK_END[$i]"})) {
  742. $end = $opt{"PATCHCHECK_END[$i]"};
  743. }
  744. my $type = $opt{"PATCHCHECK_TYPE[$i]"};
  745. # Can't have a test without having a test to run
  746. if ($type eq "test" && !defined($run_test)) {
  747. $type = "boot";
  748. }
  749. open (IN, "git log --pretty=oneline $end|") or
  750. dodie "could not get git list";
  751. my @list;
  752. while (<IN>) {
  753. chomp;
  754. $list[$#list+1] = $_;
  755. last if (/^$start/);
  756. }
  757. close(IN);
  758. if ($list[$#list] !~ /^$start/) {
  759. fail "SHA1 $start not found";
  760. }
  761. # go backwards in the list
  762. @list = reverse @list;
  763. my $save_clean = $noclean;
  764. $in_patchcheck = 1;
  765. foreach my $item (@list) {
  766. my $sha1 = $item;
  767. $sha1 =~ s/^([[:xdigit:]]+).*/$1/;
  768. doprint "\nProcessing commit $item\n\n";
  769. run_command "git checkout $sha1" or
  770. die "Failed to checkout $sha1";
  771. # only clean on the first and last patch
  772. if ($item eq $list[0] ||
  773. $item eq $list[$#list]) {
  774. $noclean = $save_clean;
  775. } else {
  776. $noclean = 1;
  777. }
  778. if (defined($minconfig)) {
  779. build "useconfig:$minconfig" or return 0;
  780. } else {
  781. # ?? no config to use?
  782. build "oldconfig" or return 0;
  783. }
  784. check_buildlog $sha1 or return 0;
  785. next if ($type eq "build");
  786. get_grub_index;
  787. get_version;
  788. install;
  789. my $failed = 0;
  790. start_monitor;
  791. monitor or $failed = 1;
  792. if (!$failed && $type ne "boot"){
  793. do_run_test or $failed = 1;
  794. }
  795. end_monitor;
  796. return 0 if ($failed);
  797. }
  798. $in_patchcheck = 0;
  799. success $i;
  800. return 1;
  801. }
  802. read_config $ARGV[0];
  803. # mandatory configs
  804. die "MACHINE not defined\n" if (!defined($opt{"MACHINE"}));
  805. die "SSH_USER not defined\n" if (!defined($opt{"SSH_USER"}));
  806. die "BUILD_DIR not defined\n" if (!defined($opt{"BUILD_DIR"}));
  807. die "OUTPUT_DIR not defined\n" if (!defined($opt{"OUTPUT_DIR"}));
  808. die "BUILD_TARGET not defined\n" if (!defined($opt{"BUILD_TARGET"}));
  809. die "TARGET_IMAGE not defined\n" if (!defined($opt{"TARGET_IMAGE"}));
  810. die "POWER_CYCLE not defined\n" if (!defined($opt{"POWER_CYCLE"}));
  811. die "CONSOLE not defined\n" if (!defined($opt{"CONSOLE"}));
  812. die "LOCALVERSION not defined\n" if (!defined($opt{"LOCALVERSION"}));
  813. if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) {
  814. unlink $opt{"LOG_FILE"};
  815. }
  816. doprint "\n\nSTARTING AUTOMATED TESTS\n\n";
  817. foreach my $option (sort keys %opt) {
  818. doprint "$option = $opt{$option}\n";
  819. }
  820. sub set_test_option {
  821. my ($name, $i) = @_;
  822. my $option = "$name\[$i\]";
  823. if (defined($opt{$option})) {
  824. return $opt{$option};
  825. }
  826. if (defined($opt{$name})) {
  827. return $opt{$name};
  828. }
  829. return undef;
  830. }
  831. # First we need to do is the builds
  832. for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
  833. $iteration = $i;
  834. my $ssh_user = set_test_option("SSH_USER", $i);
  835. my $makecmd = set_test_option("MAKE_CMD", $i);
  836. $machine = set_test_option("MACHINE", $i);
  837. $tmpdir = set_test_option("TMP_DIR", $i);
  838. $outputdir = set_test_option("OUTPUT_DIR", $i);
  839. $builddir = set_test_option("BUILD_DIR", $i);
  840. $test_type = set_test_option("TEST_TYPE", $i);
  841. $build_type = set_test_option("BUILD_TYPE", $i);
  842. $build_options = set_test_option("BUILD_OPTIONS", $i);
  843. $power_cycle = set_test_option("POWER_CYCLE", $i);
  844. $noclean = set_test_option("BUILD_NOCLEAN", $i);
  845. $minconfig = set_test_option("MIN_CONFIG", $i);
  846. $run_test = set_test_option("TEST", $i);
  847. $addconfig = set_test_option("ADD_CONFIG", $i);
  848. $reboot_type = set_test_option("REBOOT_TYPE", $i);
  849. $grub_menu = set_test_option("GRUB_MENU", $i);
  850. $post_install = set_test_option("POST_INSTALL", $i);
  851. $reboot_script = set_test_option("REBOOT_SCRIPT", $i);
  852. $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i);
  853. $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i);
  854. $die_on_failure = set_test_option("DIE_ON_FAILURE", $i);
  855. $power_off = set_test_option("POWER_OFF", $i);
  856. $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i);
  857. $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i);
  858. $sleep_time = set_test_option("SLEEP_TIME", $i);
  859. $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i);
  860. $store_failures = set_test_option("STORE_FAILURES", $i);
  861. $timeout = set_test_option("TIMEOUT", $i);
  862. $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i);
  863. $console = set_test_option("CONSOLE", $i);
  864. $success_line = set_test_option("SUCCESS_LINE", $i);
  865. $build_target = set_test_option("BUILD_TARGET", $i);
  866. $target_image = set_test_option("TARGET_IMAGE", $i);
  867. $localversion = set_test_option("LOCALVERSION", $i);
  868. chdir $builddir || die "can't change directory to $builddir";
  869. if (!-d $tmpdir) {
  870. mkpath($tmpdir) or
  871. die "can't create $tmpdir";
  872. }
  873. $target = "$ssh_user\@$machine";
  874. $buildlog = "$tmpdir/buildlog-$machine";
  875. $dmesg = "$tmpdir/dmesg-$machine";
  876. $make = "$makecmd O=$outputdir";
  877. if ($reboot_type eq "grub") {
  878. dodie "GRUB_MENU not defined" if (!defined($grub_menu));
  879. } elsif (!defined($reboot_script)) {
  880. dodie "REBOOT_SCRIPT not defined"
  881. }
  882. my $run_type = $build_type;
  883. if ($test_type eq "patchcheck") {
  884. $run_type = $opt{"PATCHCHECK_TYPE[$i]"};
  885. } elsif ($test_type eq "bisect") {
  886. $run_type = $opt{"BISECT_TYPE[$i]"};
  887. }
  888. # mistake in config file?
  889. if (!defined($run_type)) {
  890. $run_type = "ERROR";
  891. }
  892. doprint "\n\n";
  893. doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n";
  894. unlink $dmesg;
  895. unlink $buildlog;
  896. if (!defined($minconfig)) {
  897. $minconfig = $addconfig;
  898. } elsif (defined($addconfig)) {
  899. run_command "cat $addconfig $minconfig > $tmpdir/use_config" or
  900. dodie "Failed to create temp config";
  901. $minconfig = "$tmpdir/use_config";
  902. }
  903. my $checkout = $opt{"CHECKOUT[$i]"};
  904. if (defined($checkout)) {
  905. run_command "git checkout $checkout" or
  906. die "failed to checkout $checkout";
  907. }
  908. if ($test_type eq "bisect") {
  909. bisect $i;
  910. next;
  911. } elsif ($test_type eq "patchcheck") {
  912. patchcheck $i;
  913. next;
  914. }
  915. if ($build_type ne "nobuild") {
  916. build $build_type or next;
  917. }
  918. if ($test_type ne "build") {
  919. get_grub_index;
  920. get_version;
  921. install;
  922. my $failed = 0;
  923. start_monitor;
  924. monitor or $failed = 1;;
  925. if (!$failed && $test_type ne "boot" && defined($run_test)) {
  926. do_run_test or $failed = 1;
  927. }
  928. end_monitor;
  929. next if ($failed);
  930. }
  931. success $i;
  932. }
  933. if ($opt{"POWEROFF_ON_SUCCESS"}) {
  934. halt;
  935. } elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
  936. reboot;
  937. }
  938. exit 0;