ktest.pl 28 KB

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