ktest.pl 28 KB

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