12545eb61SSteven Rostedt#!/usr/bin/perl -w 2d6ce2a0bSSteven Rostedt# 3d6ce2a0bSSteven Rostedt# Copywrite 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc. 4d6ce2a0bSSteven Rostedt# Licensed under the terms of the GNU GPL License version 2 5d6ce2a0bSSteven Rostedt# 62545eb61SSteven Rostedt 72545eb61SSteven Rostedtuse strict; 82545eb61SSteven Rostedtuse IPC::Open2; 92545eb61SSteven Rostedtuse Fcntl qw(F_GETFL F_SETFL O_NONBLOCK); 102545eb61SSteven Rostedtuse FileHandle; 112545eb61SSteven Rostedt 122545eb61SSteven Rostedt$#ARGV >= 0 || die "usage: autotest.pl config-file\n"; 132545eb61SSteven Rostedt 142545eb61SSteven Rostedt$| = 1; 152545eb61SSteven Rostedt 162545eb61SSteven Rostedtmy %opt; 172545eb61SSteven Rostedt 182545eb61SSteven Rostedt#default opts 192545eb61SSteven Rostedt$opt{"NUM_BUILDS"} = 5; 202545eb61SSteven Rostedt$opt{"DEFAULT_BUILD_TYPE"} = "randconfig"; 212545eb61SSteven Rostedt$opt{"MAKE_CMD"} = "make"; 22*2b7d9b21SSteven Rostedt$opt{"TIMEOUT"} = 120; 232545eb61SSteven Rostedt$opt{"TMP_DIR"} = "/tmp/autotest"; 242545eb61SSteven Rostedt$opt{"SLEEP_TIME"} = 60; # sleep time between tests 255c42fc5bSSteven Rostedt$opt{"BUILD_NOCLEAN"} = 0; 2675c3fda7SSteven Rostedt$opt{"REBOOT_ON_ERROR"} = 0; 275c42fc5bSSteven Rostedt$opt{"POWEROFF_ON_ERROR"} = 0; 281a5cfce3SSteven Rostedt$opt{"REBOOT_ON_SUCCESS"} = 1; 295c42fc5bSSteven Rostedt$opt{"POWEROFF_ON_SUCCESS"} = 0; 3075c3fda7SSteven Rostedt$opt{"BUILD_OPTIONS"} = ""; 315a391fbfSSteven Rostedt$opt{"BISECT_SLEEP_TIME"} = 10; # sleep time between bisects 32*2b7d9b21SSteven Rostedt$opt{"CLEAR_LOG"} = 0; 33*2b7d9b21SSteven Rostedt$opt{"SUCCESS_LINE"} = "login:"; 34*2b7d9b21SSteven Rostedt$opt{"BOOTED_TIMEOUT"} = 1; 35*2b7d9b21SSteven Rostedt$opt{"DIE_ON_FAILURE"} = 1; 362545eb61SSteven Rostedt 372545eb61SSteven Rostedtmy $version; 382545eb61SSteven Rostedtmy $grub_number; 392545eb61SSteven Rostedtmy $target; 402545eb61SSteven Rostedtmy $make; 415c42fc5bSSteven Rostedtmy $noclean; 425f9b6cedSSteven Rostedtmy $minconfig; 43*2b7d9b21SSteven Rostedtmy $addconfig; 445f9b6cedSSteven Rostedtmy $in_bisect = 0; 455f9b6cedSSteven Rostedtmy $bisect_bad = ""; 46d6ce2a0bSSteven Rostedtmy $reverse_bisect; 476c5ee0beSSteven Rostedtmy $in_patchcheck = 0; 485a391fbfSSteven Rostedtmy $run_test; 496c5ee0beSSteven Rostedtmy $redirect; 502545eb61SSteven Rostedt 512545eb61SSteven Rostedtsub read_config { 522545eb61SSteven Rostedt my ($config) = @_; 532545eb61SSteven Rostedt 542545eb61SSteven Rostedt open(IN, $config) || die "can't read file $config"; 552545eb61SSteven Rostedt 562545eb61SSteven Rostedt while (<IN>) { 572545eb61SSteven Rostedt 582545eb61SSteven Rostedt # ignore blank lines and comments 592545eb61SSteven Rostedt next if (/^\s*$/ || /\s*\#/); 602545eb61SSteven Rostedt 612545eb61SSteven Rostedt if (/^\s*(\S+)\s*=\s*(.*?)\s*$/) { 622545eb61SSteven Rostedt my $lvalue = $1; 632545eb61SSteven Rostedt my $rvalue = $2; 642545eb61SSteven Rostedt 652545eb61SSteven Rostedt $opt{$lvalue} = $rvalue; 662545eb61SSteven Rostedt } 672545eb61SSteven Rostedt } 682545eb61SSteven Rostedt 692545eb61SSteven Rostedt close(IN); 702545eb61SSteven Rostedt} 712545eb61SSteven Rostedt 725f9b6cedSSteven Rostedtsub logit { 732545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 742545eb61SSteven Rostedt open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; 752545eb61SSteven Rostedt print OUT @_; 762545eb61SSteven Rostedt close(OUT); 772545eb61SSteven Rostedt } 782545eb61SSteven Rostedt} 792545eb61SSteven Rostedt 805f9b6cedSSteven Rostedtsub doprint { 815f9b6cedSSteven Rostedt print @_; 825f9b6cedSSteven Rostedt logit @_; 835f9b6cedSSteven Rostedt} 845f9b6cedSSteven Rostedt 855c42fc5bSSteven Rostedtsub dodie { 865a391fbfSSteven Rostedt doprint "CRITICAL FAILURE... ", @_, "\n"; 875c42fc5bSSteven Rostedt 8875c3fda7SSteven Rostedt if ($opt{"REBOOT_ON_ERROR"}) { 8975c3fda7SSteven Rostedt doprint "REBOOTING\n"; 9075c3fda7SSteven Rostedt `$opt{"POWER_CYCLE"}`; 9175c3fda7SSteven Rostedt 9275c3fda7SSteven Rostedt } elsif ($opt{"POWEROFF_ON_ERROR"} && defined($opt{"POWER_OFF"})) { 935c42fc5bSSteven Rostedt doprint "POWERING OFF\n"; 945c42fc5bSSteven Rostedt `$opt{"POWER_OFF"}`; 955c42fc5bSSteven Rostedt } 9675c3fda7SSteven Rostedt 975c42fc5bSSteven Rostedt die @_; 985c42fc5bSSteven Rostedt} 995c42fc5bSSteven Rostedt 100*2b7d9b21SSteven Rostedtsub fail { 101*2b7d9b21SSteven Rostedt 102*2b7d9b21SSteven Rostedt if ($opt{"DIE_ON_FAILURE"}) { 103*2b7d9b21SSteven Rostedt dodie @_; 104*2b7d9b21SSteven Rostedt } 105*2b7d9b21SSteven Rostedt 106*2b7d9b21SSteven Rostedt doprint "Failed: ", @_, "\n"; 107*2b7d9b21SSteven Rostedt return 1; 108*2b7d9b21SSteven Rostedt} 109*2b7d9b21SSteven Rostedt 1102545eb61SSteven Rostedtsub run_command { 1112545eb61SSteven Rostedt my ($command) = @_; 112d6ce2a0bSSteven Rostedt my $dolog = 0; 113d6ce2a0bSSteven Rostedt my $dord = 0; 114d6ce2a0bSSteven Rostedt my $pid; 115d6ce2a0bSSteven Rostedt 116d6ce2a0bSSteven Rostedt doprint("$command ... "); 117d6ce2a0bSSteven Rostedt 118d6ce2a0bSSteven Rostedt $pid = open(CMD, "$command 2>&1 |") or 119*2b7d9b21SSteven Rostedt (fail "unable to exec $command" and return 0); 1202545eb61SSteven Rostedt 1212545eb61SSteven Rostedt if (defined($opt{"LOG_FILE"})) { 122d6ce2a0bSSteven Rostedt open(LOG, ">>$opt{LOG_FILE}") or 123d6ce2a0bSSteven Rostedt dodie "failed to write to log"; 124d6ce2a0bSSteven Rostedt $dolog = 1; 1256c5ee0beSSteven Rostedt } 1266c5ee0beSSteven Rostedt 1276c5ee0beSSteven Rostedt if (defined($redirect)) { 128d6ce2a0bSSteven Rostedt open (RD, ">$redirect") or 129d6ce2a0bSSteven Rostedt dodie "failed to write to redirect $redirect"; 130d6ce2a0bSSteven Rostedt $dord = 1; 1312545eb61SSteven Rostedt } 1322545eb61SSteven Rostedt 133d6ce2a0bSSteven Rostedt while (<CMD>) { 134d6ce2a0bSSteven Rostedt print LOG if ($dolog); 135d6ce2a0bSSteven Rostedt print RD if ($dord); 136d6ce2a0bSSteven Rostedt } 1372545eb61SSteven Rostedt 138d6ce2a0bSSteven Rostedt waitpid($pid, 0); 1392545eb61SSteven Rostedt my $failed = $?; 1402545eb61SSteven Rostedt 141d6ce2a0bSSteven Rostedt close(CMD); 142d6ce2a0bSSteven Rostedt close(LOG) if ($dolog); 143d6ce2a0bSSteven Rostedt close(RD) if ($dord); 144d6ce2a0bSSteven Rostedt 1452545eb61SSteven Rostedt if ($failed) { 1462545eb61SSteven Rostedt doprint "FAILED!\n"; 1472545eb61SSteven Rostedt } else { 1482545eb61SSteven Rostedt doprint "SUCCESS\n"; 1492545eb61SSteven Rostedt } 1502545eb61SSteven Rostedt 1515f9b6cedSSteven Rostedt return !$failed; 1525f9b6cedSSteven Rostedt} 1535f9b6cedSSteven Rostedt 1545f9b6cedSSteven Rostedtsub get_grub_index { 1555f9b6cedSSteven Rostedt 1565a391fbfSSteven Rostedt return if (defined($grub_number)); 1575f9b6cedSSteven Rostedt 1585f9b6cedSSteven Rostedt doprint "Find grub menu ... "; 1595f9b6cedSSteven Rostedt $grub_number = -1; 1605f9b6cedSSteven Rostedt open(IN, "ssh $target cat /boot/grub/menu.lst |") 1615f9b6cedSSteven Rostedt or die "unable to get menu.lst"; 1625f9b6cedSSteven Rostedt while (<IN>) { 1635f9b6cedSSteven Rostedt if (/^\s*title\s+$opt{GRUB_MENU}\s*$/) { 1645f9b6cedSSteven Rostedt $grub_number++; 1655f9b6cedSSteven Rostedt last; 1665f9b6cedSSteven Rostedt } elsif (/^\s*title\s/) { 1675f9b6cedSSteven Rostedt $grub_number++; 1685f9b6cedSSteven Rostedt } 1695f9b6cedSSteven Rostedt } 1705f9b6cedSSteven Rostedt close(IN); 1715f9b6cedSSteven Rostedt 1725f9b6cedSSteven Rostedt die "Could not find '$opt{GRUB_MENU}' in /boot/grub/menu on $opt{MACHINE}" 1735f9b6cedSSteven Rostedt if ($grub_number < 0); 1745f9b6cedSSteven Rostedt doprint "$grub_number\n"; 1752545eb61SSteven Rostedt} 1762545eb61SSteven Rostedt 1772545eb61SSteven Rostedtmy $timeout = $opt{"TIMEOUT"}; 1782545eb61SSteven Rostedt 1792545eb61SSteven Rostedtsub wait_for_input 1802545eb61SSteven Rostedt{ 1812545eb61SSteven Rostedt my ($fp, $time) = @_; 1822545eb61SSteven Rostedt my $rin; 1832545eb61SSteven Rostedt my $ready; 1842545eb61SSteven Rostedt my $line; 1852545eb61SSteven Rostedt my $ch; 1862545eb61SSteven Rostedt 1872545eb61SSteven Rostedt if (!defined($time)) { 1882545eb61SSteven Rostedt $time = $timeout; 1892545eb61SSteven Rostedt } 1902545eb61SSteven Rostedt 1912545eb61SSteven Rostedt $rin = ''; 1922545eb61SSteven Rostedt vec($rin, fileno($fp), 1) = 1; 1932545eb61SSteven Rostedt $ready = select($rin, undef, undef, $time); 1942545eb61SSteven Rostedt 1952545eb61SSteven Rostedt $line = ""; 1962545eb61SSteven Rostedt 1972545eb61SSteven Rostedt # try to read one char at a time 1982545eb61SSteven Rostedt while (sysread $fp, $ch, 1) { 1992545eb61SSteven Rostedt $line .= $ch; 2002545eb61SSteven Rostedt last if ($ch eq "\n"); 2012545eb61SSteven Rostedt } 2022545eb61SSteven Rostedt 2032545eb61SSteven Rostedt if (!length($line)) { 2042545eb61SSteven Rostedt return undef; 2052545eb61SSteven Rostedt } 2062545eb61SSteven Rostedt 2072545eb61SSteven Rostedt return $line; 2082545eb61SSteven Rostedt} 2092545eb61SSteven Rostedt 21075c3fda7SSteven Rostedtsub reboot_to { 2112545eb61SSteven Rostedt run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; 2122545eb61SSteven Rostedt} 2132545eb61SSteven Rostedt 2145a391fbfSSteven Rostedtsub open_console { 2155a391fbfSSteven Rostedt my ($fp) = @_; 2165a391fbfSSteven Rostedt 2172545eb61SSteven Rostedt my $flags; 2185a391fbfSSteven Rostedt 2195a391fbfSSteven Rostedt my $pid = open($fp, "$opt{CONSOLE}|") or 2205a391fbfSSteven Rostedt dodie "Can't open console $opt{CONSOLE}"; 2215a391fbfSSteven Rostedt 2225a391fbfSSteven Rostedt $flags = fcntl($fp, F_GETFL, 0) or 2235a391fbfSSteven Rostedt dodie "Can't get flags for the socket: $!\n"; 2245a391fbfSSteven Rostedt $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or 2255a391fbfSSteven Rostedt dodie "Can't set flags for the socket: $!\n"; 2265a391fbfSSteven Rostedt 2275a391fbfSSteven Rostedt return $pid; 2285a391fbfSSteven Rostedt} 2295a391fbfSSteven Rostedt 2305a391fbfSSteven Rostedtsub close_console { 2315a391fbfSSteven Rostedt my ($fp, $pid) = @_; 2325a391fbfSSteven Rostedt 2335a391fbfSSteven Rostedt doprint "kill child process $pid\n"; 2345a391fbfSSteven Rostedt kill 2, $pid; 2355a391fbfSSteven Rostedt 2365a391fbfSSteven Rostedt print "closing!\n"; 2375a391fbfSSteven Rostedt close($fp); 2385a391fbfSSteven Rostedt} 2395a391fbfSSteven Rostedt 2405a391fbfSSteven Rostedtsub monitor { 2412545eb61SSteven Rostedt my $booted = 0; 2422545eb61SSteven Rostedt my $bug = 0; 2432545eb61SSteven Rostedt my $pid; 2445c42fc5bSSteven Rostedt my $skip_call_trace = 0; 2455a391fbfSSteven Rostedt my $fp = \*IN; 246*2b7d9b21SSteven Rostedt my $loops; 2472545eb61SSteven Rostedt 2485a391fbfSSteven Rostedt $pid = open_console($fp); 2492545eb61SSteven Rostedt 2502545eb61SSteven Rostedt my $line; 2512545eb61SSteven Rostedt my $full_line = ""; 2522545eb61SSteven Rostedt 2532545eb61SSteven Rostedt doprint "Wait for monitor to settle down.\n"; 2542545eb61SSteven Rostedt # read the monitor and wait for the system to calm down 2552545eb61SSteven Rostedt do { 2565a391fbfSSteven Rostedt $line = wait_for_input($fp, 5); 2572545eb61SSteven Rostedt } while (defined($line)); 2582545eb61SSteven Rostedt 25975c3fda7SSteven Rostedt reboot_to; 2602545eb61SSteven Rostedt 2612545eb61SSteven Rostedt for (;;) { 2622545eb61SSteven Rostedt 263*2b7d9b21SSteven Rostedt if ($booted) { 264*2b7d9b21SSteven Rostedt $line = wait_for_input($fp, $opt{"BOOTED_TIMEOUT"}); 265*2b7d9b21SSteven Rostedt } else { 2665a391fbfSSteven Rostedt $line = wait_for_input($fp); 267*2b7d9b21SSteven Rostedt } 2682545eb61SSteven Rostedt 2692545eb61SSteven Rostedt last if (!defined($line)); 2702545eb61SSteven Rostedt 2712545eb61SSteven Rostedt doprint $line; 2722545eb61SSteven Rostedt 2732545eb61SSteven Rostedt # we are not guaranteed to get a full line 2742545eb61SSteven Rostedt $full_line .= $line; 2752545eb61SSteven Rostedt 276*2b7d9b21SSteven Rostedt if ($full_line =~ /$opt{"SUCCESS_LINE"}/) { 2772545eb61SSteven Rostedt $booted = 1; 2782545eb61SSteven Rostedt } 2792545eb61SSteven Rostedt 2805c42fc5bSSteven Rostedt if ($full_line =~ /\[ backtrace testing \]/) { 2815c42fc5bSSteven Rostedt $skip_call_trace = 1; 2825c42fc5bSSteven Rostedt } 2835c42fc5bSSteven Rostedt 2842545eb61SSteven Rostedt if ($full_line =~ /call trace:/i) { 2855c42fc5bSSteven Rostedt $bug = 1 if (!$skip_call_trace); 2865c42fc5bSSteven Rostedt } 2875c42fc5bSSteven Rostedt 2885c42fc5bSSteven Rostedt if ($full_line =~ /\[ end of backtrace testing \]/) { 2895c42fc5bSSteven Rostedt $skip_call_trace = 0; 2905c42fc5bSSteven Rostedt } 2915c42fc5bSSteven Rostedt 2925c42fc5bSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 2932545eb61SSteven Rostedt $bug = 1; 2942545eb61SSteven Rostedt } 2952545eb61SSteven Rostedt 2962545eb61SSteven Rostedt if ($line =~ /\n/) { 2972545eb61SSteven Rostedt $full_line = ""; 2982545eb61SSteven Rostedt } 2992545eb61SSteven Rostedt } 3002545eb61SSteven Rostedt 3015a391fbfSSteven Rostedt close_console($fp, $pid); 3022545eb61SSteven Rostedt 3032545eb61SSteven Rostedt if (!$booted) { 304*2b7d9b21SSteven Rostedt return 0 if ($in_bisect); 305*2b7d9b21SSteven Rostedt fail "failed - never got a boot prompt.\n" and return 0; 3062545eb61SSteven Rostedt } 3072545eb61SSteven Rostedt 3082545eb61SSteven Rostedt if ($bug) { 309*2b7d9b21SSteven Rostedt return 0 if ($in_bisect); 310*2b7d9b21SSteven Rostedt fail "failed - got a bug report\n" and return 0; 3112545eb61SSteven Rostedt } 3125f9b6cedSSteven Rostedt 313*2b7d9b21SSteven Rostedt return 1; 3142545eb61SSteven Rostedt} 3152545eb61SSteven Rostedt 3162545eb61SSteven Rostedtsub install { 3172545eb61SSteven Rostedt 3185f9b6cedSSteven Rostedt run_command "scp $opt{OUTPUT_DIR}/$opt{BUILD_TARGET} $target:$opt{TARGET_IMAGE}" or 3195c42fc5bSSteven Rostedt dodie "failed to copy image"; 3205f9b6cedSSteven Rostedt 3215f9b6cedSSteven Rostedt my $install_mods = 0; 3225f9b6cedSSteven Rostedt 3235f9b6cedSSteven Rostedt # should we process modules? 3245f9b6cedSSteven Rostedt $install_mods = 0; 3255f9b6cedSSteven Rostedt open(IN, "$opt{OUTPUT_DIR}/.config") or dodie("Can't read config file"); 3265f9b6cedSSteven Rostedt while (<IN>) { 3275f9b6cedSSteven Rostedt if (/CONFIG_MODULES(=y)?/) { 3285f9b6cedSSteven Rostedt $install_mods = 1 if (defined($1)); 3295f9b6cedSSteven Rostedt last; 3305f9b6cedSSteven Rostedt } 3315f9b6cedSSteven Rostedt } 3325f9b6cedSSteven Rostedt close(IN); 3335f9b6cedSSteven Rostedt 3345f9b6cedSSteven Rostedt if (!$install_mods) { 3355f9b6cedSSteven Rostedt doprint "No modules needed\n"; 3365f9b6cedSSteven Rostedt return; 3372545eb61SSteven Rostedt } 3382545eb61SSteven Rostedt 3395f9b6cedSSteven Rostedt run_command "$make INSTALL_MOD_PATH=$opt{TMP_DIR} modules_install" or 3405f9b6cedSSteven Rostedt dodie "Failed to install modules"; 3415f9b6cedSSteven Rostedt 3422545eb61SSteven Rostedt my $modlib = "/lib/modules/$version"; 3435c42fc5bSSteven Rostedt my $modtar = "autotest-mods.tar.bz2"; 3442545eb61SSteven Rostedt 3455f9b6cedSSteven Rostedt run_command "ssh $target rm -rf $modlib" or 3465c42fc5bSSteven Rostedt dodie "failed to remove old mods: $modlib"; 3472545eb61SSteven Rostedt 3485c42fc5bSSteven Rostedt # would be nice if scp -r did not follow symbolic links 3495f9b6cedSSteven Rostedt run_command "cd $opt{TMP_DIR} && tar -cjf $modtar lib/modules/$version" or 3505c42fc5bSSteven Rostedt dodie "making tarball"; 3515c42fc5bSSteven Rostedt 3525f9b6cedSSteven Rostedt run_command "scp $opt{TMP_DIR}/$modtar $target:/tmp" or 3535c42fc5bSSteven Rostedt dodie "failed to copy modules"; 3545c42fc5bSSteven Rostedt 3555c42fc5bSSteven Rostedt unlink "$opt{TMP_DIR}/$modtar"; 3565c42fc5bSSteven Rostedt 3575f9b6cedSSteven Rostedt run_command "ssh $target '(cd / && tar xf /tmp/$modtar)'" or 3585c42fc5bSSteven Rostedt dodie "failed to tar modules"; 3595c42fc5bSSteven Rostedt 3605c42fc5bSSteven Rostedt run_command "ssh $target rm -f /tmp/$modtar"; 3612545eb61SSteven Rostedt} 3622545eb61SSteven Rostedt 3636c5ee0beSSteven Rostedtsub check_buildlog { 3646c5ee0beSSteven Rostedt my ($patch) = @_; 3656c5ee0beSSteven Rostedt 3666c5ee0beSSteven Rostedt my $buildlog = "$opt{TMP_DIR}/buildlog"; 3676c5ee0beSSteven Rostedt my @files = `git show $patch | diffstat -l`; 3686c5ee0beSSteven Rostedt 3696c5ee0beSSteven Rostedt open(IN, "git show $patch |") or 3706c5ee0beSSteven Rostedt dodie "failed to show $patch"; 3716c5ee0beSSteven Rostedt while (<IN>) { 3726c5ee0beSSteven Rostedt if (m,^--- a/(.*),) { 3736c5ee0beSSteven Rostedt chomp $1; 3746c5ee0beSSteven Rostedt $files[$#files] = $1; 3756c5ee0beSSteven Rostedt } 3766c5ee0beSSteven Rostedt } 3776c5ee0beSSteven Rostedt close(IN); 3786c5ee0beSSteven Rostedt 3796c5ee0beSSteven Rostedt open(IN, $buildlog) or dodie "Can't open $buildlog"; 3806c5ee0beSSteven Rostedt while (<IN>) { 3816c5ee0beSSteven Rostedt if (/^\s*(.*?):.*(warning|error)/) { 3826c5ee0beSSteven Rostedt my $err = $1; 3836c5ee0beSSteven Rostedt foreach my $file (@files) { 3846c5ee0beSSteven Rostedt my $fullpath = "$opt{BUILD_DIR}/$file"; 3856c5ee0beSSteven Rostedt if ($file eq $err || $fullpath eq $err) { 386*2b7d9b21SSteven Rostedt fail "$file built with warnings" and return 0; 3876c5ee0beSSteven Rostedt } 3886c5ee0beSSteven Rostedt } 3896c5ee0beSSteven Rostedt } 3906c5ee0beSSteven Rostedt } 3916c5ee0beSSteven Rostedt close(IN); 392*2b7d9b21SSteven Rostedt 393*2b7d9b21SSteven Rostedt return 1; 3946c5ee0beSSteven Rostedt} 3956c5ee0beSSteven Rostedt 3962545eb61SSteven Rostedtsub build { 3972545eb61SSteven Rostedt my ($type) = @_; 3985c42fc5bSSteven Rostedt my $defconfig = ""; 3995c42fc5bSSteven Rostedt my $append = ""; 4002545eb61SSteven Rostedt 40175c3fda7SSteven Rostedt if ($type =~ /^useconfig:(.*)/) { 4025f9b6cedSSteven Rostedt run_command "cp $1 $opt{OUTPUT_DIR}/.config" or 40375c3fda7SSteven Rostedt dodie "could not copy $1 to .config"; 4045f9b6cedSSteven Rostedt 40575c3fda7SSteven Rostedt $type = "oldconfig"; 40675c3fda7SSteven Rostedt } 40775c3fda7SSteven Rostedt 4085c42fc5bSSteven Rostedt # old config can ask questions 4095c42fc5bSSteven Rostedt if ($type eq "oldconfig") { 4105c42fc5bSSteven Rostedt $append = "yes ''|"; 41175c3fda7SSteven Rostedt 41275c3fda7SSteven Rostedt # allow for empty configs 41375c3fda7SSteven Rostedt run_command "touch $opt{OUTPUT_DIR}/.config"; 41475c3fda7SSteven Rostedt 4155f9b6cedSSteven Rostedt run_command "mv $opt{OUTPUT_DIR}/.config $opt{OUTPUT_DIR}/config_temp" or 4165c42fc5bSSteven Rostedt dodie "moving .config"; 4175c42fc5bSSteven Rostedt 4185f9b6cedSSteven Rostedt if (!$noclean && !run_command "$make mrproper") { 4195c42fc5bSSteven Rostedt dodie "make mrproper"; 4205c42fc5bSSteven Rostedt } 4215c42fc5bSSteven Rostedt 4225f9b6cedSSteven Rostedt run_command "mv $opt{OUTPUT_DIR}/config_temp $opt{OUTPUT_DIR}/.config" or 4235c42fc5bSSteven Rostedt dodie "moving config_temp"; 4245c42fc5bSSteven Rostedt 4255c42fc5bSSteven Rostedt } elsif (!$noclean) { 4262545eb61SSteven Rostedt unlink "$opt{OUTPUT_DIR}/.config"; 4275f9b6cedSSteven Rostedt run_command "$make mrproper" or 4285c42fc5bSSteven Rostedt dodie "make mrproper"; 4295c42fc5bSSteven Rostedt } 4302545eb61SSteven Rostedt 4312545eb61SSteven Rostedt # add something to distinguish this build 4325c42fc5bSSteven Rostedt open(OUT, "> $opt{OUTPUT_DIR}/localversion") or dodie("Can't make localversion file"); 4332545eb61SSteven Rostedt print OUT "$opt{LOCALVERSION}\n"; 4342545eb61SSteven Rostedt close(OUT); 4352545eb61SSteven Rostedt 4365f9b6cedSSteven Rostedt if (defined($minconfig)) { 4375f9b6cedSSteven Rostedt $defconfig = "KCONFIG_ALLCONFIG=$minconfig"; 4382545eb61SSteven Rostedt } 4392545eb61SSteven Rostedt 4405f9b6cedSSteven Rostedt run_command "$defconfig $append $make $type" or 4415c42fc5bSSteven Rostedt dodie "failed make config"; 4422545eb61SSteven Rostedt 4436c5ee0beSSteven Rostedt # patch check will examine the log 4446c5ee0beSSteven Rostedt if ($in_patchcheck) { 4456c5ee0beSSteven Rostedt $redirect = "$opt{TMP_DIR}/buildlog"; 4466c5ee0beSSteven Rostedt } 4476c5ee0beSSteven Rostedt 4485f9b6cedSSteven Rostedt if (!run_command "$make $opt{BUILD_OPTIONS}") { 4496c5ee0beSSteven Rostedt undef $redirect; 4505f9b6cedSSteven Rostedt # bisect may need this to pass 451*2b7d9b21SSteven Rostedt return 0 if ($in_bisect); 452*2b7d9b21SSteven Rostedt fail "failed build" and return 0; 4532545eb61SSteven Rostedt } 4546c5ee0beSSteven Rostedt undef $redirect; 4555f9b6cedSSteven Rostedt 456*2b7d9b21SSteven Rostedt return 1; 4572545eb61SSteven Rostedt} 4582545eb61SSteven Rostedt 45975c3fda7SSteven Rostedtsub reboot { 46075c3fda7SSteven Rostedt # try to reboot normally 4615f9b6cedSSteven Rostedt if (!run_command "ssh $target reboot") { 46275c3fda7SSteven Rostedt # nope? power cycle it. 46375c3fda7SSteven Rostedt run_command "$opt{POWER_CYCLE}"; 46475c3fda7SSteven Rostedt } 46575c3fda7SSteven Rostedt} 46675c3fda7SSteven Rostedt 46775c3fda7SSteven Rostedtsub halt { 4685f9b6cedSSteven Rostedt if (!run_command "ssh $target halt" or defined($opt{"POWER_OFF"})) { 46975c3fda7SSteven Rostedt # nope? the zap it! 47075c3fda7SSteven Rostedt run_command "$opt{POWER_OFF}"; 47175c3fda7SSteven Rostedt } 47275c3fda7SSteven Rostedt} 47375c3fda7SSteven Rostedt 4745f9b6cedSSteven Rostedtsub success { 4755f9b6cedSSteven Rostedt my ($i) = @_; 4765f9b6cedSSteven Rostedt 4775f9b6cedSSteven Rostedt doprint "\n\n*******************************************\n"; 4785f9b6cedSSteven Rostedt doprint "*******************************************\n"; 4795f9b6cedSSteven Rostedt doprint "** SUCCESS!!!! **\n"; 4805f9b6cedSSteven Rostedt doprint "*******************************************\n"; 4815f9b6cedSSteven Rostedt doprint "*******************************************\n"; 4825f9b6cedSSteven Rostedt 4835f9b6cedSSteven Rostedt if ($i != $opt{"NUM_BUILDS"}) { 4845f9b6cedSSteven Rostedt reboot; 4855f9b6cedSSteven Rostedt doprint "Sleeping $opt{SLEEP_TIME} seconds\n"; 4865f9b6cedSSteven Rostedt sleep "$opt{SLEEP_TIME}"; 4875f9b6cedSSteven Rostedt } 4885f9b6cedSSteven Rostedt} 4895f9b6cedSSteven Rostedt 4905f9b6cedSSteven Rostedtsub get_version { 4915f9b6cedSSteven Rostedt # get the release name 4925f9b6cedSSteven Rostedt doprint "$make kernelrelease ... "; 4935f9b6cedSSteven Rostedt $version = `$make kernelrelease | tail -1`; 4945f9b6cedSSteven Rostedt chomp($version); 4955f9b6cedSSteven Rostedt doprint "$version\n"; 4965f9b6cedSSteven Rostedt} 4975f9b6cedSSteven Rostedt 4985a391fbfSSteven Rostedtsub child_run_test { 4995a391fbfSSteven Rostedt my $failed; 5005a391fbfSSteven Rostedt 5015a391fbfSSteven Rostedt $failed = !run_command $run_test; 5025a391fbfSSteven Rostedt exit $failed; 5035a391fbfSSteven Rostedt} 5045a391fbfSSteven Rostedt 5055a391fbfSSteven Rostedtmy $child_done; 5065a391fbfSSteven Rostedt 5075a391fbfSSteven Rostedtsub child_finished { 5085a391fbfSSteven Rostedt $child_done = 1; 5095a391fbfSSteven Rostedt} 5105a391fbfSSteven Rostedt 5115a391fbfSSteven Rostedtsub do_run_test { 5125a391fbfSSteven Rostedt my $child_pid; 5135a391fbfSSteven Rostedt my $child_exit; 5145a391fbfSSteven Rostedt my $pid; 5155a391fbfSSteven Rostedt my $line; 5165a391fbfSSteven Rostedt my $full_line; 5175a391fbfSSteven Rostedt my $bug = 0; 5185a391fbfSSteven Rostedt my $fp = \*IN; 5195a391fbfSSteven Rostedt 5205a391fbfSSteven Rostedt $pid = open_console($fp); 5215a391fbfSSteven Rostedt 5225a391fbfSSteven Rostedt # read the monitor and wait for the system to calm down 5235a391fbfSSteven Rostedt do { 5245a391fbfSSteven Rostedt $line = wait_for_input($fp, 1); 5255a391fbfSSteven Rostedt } while (defined($line)); 5265a391fbfSSteven Rostedt 5275a391fbfSSteven Rostedt $child_done = 0; 5285a391fbfSSteven Rostedt 5295a391fbfSSteven Rostedt $SIG{CHLD} = qw(child_finished); 5305a391fbfSSteven Rostedt 5315a391fbfSSteven Rostedt $child_pid = fork; 5325a391fbfSSteven Rostedt 5335a391fbfSSteven Rostedt child_run_test if (!$child_pid); 5345a391fbfSSteven Rostedt 5355a391fbfSSteven Rostedt $full_line = ""; 5365a391fbfSSteven Rostedt 5375a391fbfSSteven Rostedt do { 5385a391fbfSSteven Rostedt $line = wait_for_input($fp, 1); 5395a391fbfSSteven Rostedt if (defined($line)) { 5405a391fbfSSteven Rostedt 5415a391fbfSSteven Rostedt # we are not guaranteed to get a full line 5425a391fbfSSteven Rostedt $full_line .= $line; 5435a391fbfSSteven Rostedt 5445a391fbfSSteven Rostedt if ($full_line =~ /call trace:/i) { 5455a391fbfSSteven Rostedt $bug = 1; 5465a391fbfSSteven Rostedt } 5475a391fbfSSteven Rostedt 5485a391fbfSSteven Rostedt if ($full_line =~ /Kernel panic -/) { 5495a391fbfSSteven Rostedt $bug = 1; 5505a391fbfSSteven Rostedt } 5515a391fbfSSteven Rostedt 5525a391fbfSSteven Rostedt if ($line =~ /\n/) { 5535a391fbfSSteven Rostedt $full_line = ""; 5545a391fbfSSteven Rostedt } 5555a391fbfSSteven Rostedt } 5565a391fbfSSteven Rostedt } while (!$child_done && !$bug); 5575a391fbfSSteven Rostedt 5585a391fbfSSteven Rostedt if ($bug) { 5595a391fbfSSteven Rostedt doprint "Detected kernel crash!\n"; 5605a391fbfSSteven Rostedt # kill the child with extreme prejudice 5615a391fbfSSteven Rostedt kill 9, $child_pid; 5625a391fbfSSteven Rostedt } 5635a391fbfSSteven Rostedt 5645a391fbfSSteven Rostedt waitpid $child_pid, 0; 5655a391fbfSSteven Rostedt $child_exit = $?; 5665a391fbfSSteven Rostedt 5675a391fbfSSteven Rostedt close_console($fp, $pid); 5685a391fbfSSteven Rostedt 5695a391fbfSSteven Rostedt if ($bug || $child_exit) { 570*2b7d9b21SSteven Rostedt return 0 if $in_bisect; 571*2b7d9b21SSteven Rostedt fail "test failed" and return 0; 5725a391fbfSSteven Rostedt } 573*2b7d9b21SSteven Rostedt return 1; 5745a391fbfSSteven Rostedt} 5755a391fbfSSteven Rostedt 5765f9b6cedSSteven Rostedtsub run_bisect { 5775f9b6cedSSteven Rostedt my ($type) = @_; 5785f9b6cedSSteven Rostedt 579*2b7d9b21SSteven Rostedt my $failed = 0; 5805f9b6cedSSteven Rostedt my $result; 5815f9b6cedSSteven Rostedt my $output; 5825f9b6cedSSteven Rostedt my $ret; 5835f9b6cedSSteven Rostedt 5845f9b6cedSSteven Rostedt if (defined($minconfig)) { 585*2b7d9b21SSteven Rostedt build "useconfig:$minconfig" or $failed = 1; 5865f9b6cedSSteven Rostedt } else { 5875f9b6cedSSteven Rostedt # ?? no config to use? 588*2b7d9b21SSteven Rostedt build "oldconfig" or $failed = 1; 5895f9b6cedSSteven Rostedt } 5905f9b6cedSSteven Rostedt 5915f9b6cedSSteven Rostedt if ($type ne "build") { 592*2b7d9b21SSteven Rostedt fail "Failed on build" if $failed; 5935f9b6cedSSteven Rostedt 5945f9b6cedSSteven Rostedt # Now boot the box 5955f9b6cedSSteven Rostedt get_grub_index; 5965f9b6cedSSteven Rostedt get_version; 5975f9b6cedSSteven Rostedt install; 598*2b7d9b21SSteven Rostedt monitor or $failed = 1; 5995f9b6cedSSteven Rostedt 6005f9b6cedSSteven Rostedt if ($type ne "boot") { 601*2b7d9b21SSteven Rostedt fail "Failed on boot" if $failed; 6025a391fbfSSteven Rostedt 603*2b7d9b21SSteven Rostedt do_run_test or $failed = 1; 6045f9b6cedSSteven Rostedt } 6055f9b6cedSSteven Rostedt } 6065f9b6cedSSteven Rostedt 6075f9b6cedSSteven Rostedt if ($failed) { 6085f9b6cedSSteven Rostedt $result = "bad"; 6095a391fbfSSteven Rostedt 6105a391fbfSSteven Rostedt # reboot the box to a good kernel 6115a391fbfSSteven Rostedt if ($type eq "boot") { 6125a391fbfSSteven Rostedt reboot; 6135a391fbfSSteven Rostedt doprint "sleep a little for reboot\n"; 6145a391fbfSSteven Rostedt sleep $opt{"BISECT_SLEEP_TIME"}; 6155a391fbfSSteven Rostedt } 6165f9b6cedSSteven Rostedt } else { 6175f9b6cedSSteven Rostedt $result = "good"; 6185f9b6cedSSteven Rostedt } 6195f9b6cedSSteven Rostedt 620d6ce2a0bSSteven Rostedt # Are we looking for where it worked, not failed? 621d6ce2a0bSSteven Rostedt if ($reverse_bisect) { 622d6ce2a0bSSteven Rostedt if ($failed) { 623d6ce2a0bSSteven Rostedt $result = "good"; 624d6ce2a0bSSteven Rostedt } else { 625d6ce2a0bSSteven Rostedt $result = "bad"; 626d6ce2a0bSSteven Rostedt } 627d6ce2a0bSSteven Rostedt } 628d6ce2a0bSSteven Rostedt 6295f9b6cedSSteven Rostedt doprint "git bisect $result ... "; 6305f9b6cedSSteven Rostedt $output = `git bisect $result 2>&1`; 6315f9b6cedSSteven Rostedt $ret = $?; 6325f9b6cedSSteven Rostedt 6335f9b6cedSSteven Rostedt logit $output; 6345f9b6cedSSteven Rostedt 6355f9b6cedSSteven Rostedt if ($ret) { 6365f9b6cedSSteven Rostedt doprint "FAILED\n"; 637*2b7d9b21SSteven Rostedt fail "Failed to git bisect"; 6385f9b6cedSSteven Rostedt } 6395f9b6cedSSteven Rostedt 6405f9b6cedSSteven Rostedt doprint "SUCCESS\n"; 6415a391fbfSSteven Rostedt if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { 6425f9b6cedSSteven Rostedt doprint "$1 [$2]\n"; 6435f9b6cedSSteven Rostedt } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { 6445f9b6cedSSteven Rostedt $bisect_bad = $1; 6455f9b6cedSSteven Rostedt doprint "Found bad commit... $1\n"; 6465f9b6cedSSteven Rostedt return 0; 6475a391fbfSSteven Rostedt } else { 6485a391fbfSSteven Rostedt # we already logged it, just print it now. 6495a391fbfSSteven Rostedt print $output; 6505f9b6cedSSteven Rostedt } 6515f9b6cedSSteven Rostedt 6525f9b6cedSSteven Rostedt 6535f9b6cedSSteven Rostedt return 1; 6545f9b6cedSSteven Rostedt} 6555f9b6cedSSteven Rostedt 6565f9b6cedSSteven Rostedtsub bisect { 6575f9b6cedSSteven Rostedt my ($i) = @_; 6585f9b6cedSSteven Rostedt 6595f9b6cedSSteven Rostedt my $result; 6605f9b6cedSSteven Rostedt 6615f9b6cedSSteven Rostedt die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"})); 6625f9b6cedSSteven Rostedt die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"})); 6635f9b6cedSSteven Rostedt die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"})); 6645f9b6cedSSteven Rostedt 6655f9b6cedSSteven Rostedt my $good = $opt{"BISECT_GOOD[$i]"}; 6665f9b6cedSSteven Rostedt my $bad = $opt{"BISECT_BAD[$i]"}; 6675f9b6cedSSteven Rostedt my $type = $opt{"BISECT_TYPE[$i]"}; 6685f9b6cedSSteven Rostedt 669d6ce2a0bSSteven Rostedt if (defined($opt{"BISECT_REVERSE[$i]"}) && 670d6ce2a0bSSteven Rostedt $opt{"BISECT_REVERSE[$i]"} == 1) { 671d6ce2a0bSSteven Rostedt doprint "Performing a reverse bisect (bad is good, good is bad!)\n"; 672d6ce2a0bSSteven Rostedt $reverse_bisect = 1; 673d6ce2a0bSSteven Rostedt } else { 674d6ce2a0bSSteven Rostedt $reverse_bisect = 0; 675d6ce2a0bSSteven Rostedt } 676d6ce2a0bSSteven Rostedt 6775f9b6cedSSteven Rostedt $in_bisect = 1; 6785f9b6cedSSteven Rostedt 6795f9b6cedSSteven Rostedt run_command "git bisect start" or 680*2b7d9b21SSteven Rostedt fail "could not start bisect"; 6815f9b6cedSSteven Rostedt 6825f9b6cedSSteven Rostedt run_command "git bisect good $good" or 683*2b7d9b21SSteven Rostedt fail "could not set bisect good to $good"; 6845f9b6cedSSteven Rostedt 6855f9b6cedSSteven Rostedt run_command "git bisect bad $bad" or 686*2b7d9b21SSteven Rostedt fail "could not set bisect good to $bad"; 6875f9b6cedSSteven Rostedt 6885a391fbfSSteven Rostedt # Can't have a test without having a test to run 6895a391fbfSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 6905a391fbfSSteven Rostedt $type = "boot"; 6915a391fbfSSteven Rostedt } 6925a391fbfSSteven Rostedt 6935f9b6cedSSteven Rostedt do { 6945f9b6cedSSteven Rostedt $result = run_bisect $type; 6955f9b6cedSSteven Rostedt } while ($result); 6965f9b6cedSSteven Rostedt 6975f9b6cedSSteven Rostedt run_command "git bisect log" or 6985f9b6cedSSteven Rostedt dodie "could not capture git bisect log"; 6995f9b6cedSSteven Rostedt 7005f9b6cedSSteven Rostedt run_command "git bisect reset" or 7015f9b6cedSSteven Rostedt dodie "could not reset git bisect"; 7025f9b6cedSSteven Rostedt 7035f9b6cedSSteven Rostedt doprint "Bad commit was [$bisect_bad]\n"; 7045f9b6cedSSteven Rostedt 7055f9b6cedSSteven Rostedt $in_bisect = 0; 7065f9b6cedSSteven Rostedt 7075f9b6cedSSteven Rostedt success $i; 7085f9b6cedSSteven Rostedt} 7095f9b6cedSSteven Rostedt 7106c5ee0beSSteven Rostedtsub patchcheck { 7116c5ee0beSSteven Rostedt my ($i) = @_; 7126c5ee0beSSteven Rostedt 7136c5ee0beSSteven Rostedt die "PATCHCHECK_START[$i] not defined\n" 7146c5ee0beSSteven Rostedt if (!defined($opt{"PATCHCHECK_START[$i]"})); 7156c5ee0beSSteven Rostedt die "PATCHCHECK_TYPE[$i] not defined\n" 7166c5ee0beSSteven Rostedt if (!defined($opt{"PATCHCHECK_TYPE[$i]"})); 7176c5ee0beSSteven Rostedt 7186c5ee0beSSteven Rostedt my $start = $opt{"PATCHCHECK_START[$i]"}; 7196c5ee0beSSteven Rostedt 7206c5ee0beSSteven Rostedt my $end = "HEAD"; 7216c5ee0beSSteven Rostedt if (defined($opt{"PATCHCHECK_END[$i]"})) { 7226c5ee0beSSteven Rostedt $end = $opt{"PATCHCHECK_END[$i]"}; 7236c5ee0beSSteven Rostedt } 7246c5ee0beSSteven Rostedt 7256c5ee0beSSteven Rostedt my $type = $opt{"PATCHCHECK_TYPE[$i]"}; 7266c5ee0beSSteven Rostedt 7276c5ee0beSSteven Rostedt # Can't have a test without having a test to run 7286c5ee0beSSteven Rostedt if ($type eq "test" && !defined($run_test)) { 7296c5ee0beSSteven Rostedt $type = "boot"; 7306c5ee0beSSteven Rostedt } 7316c5ee0beSSteven Rostedt 7326c5ee0beSSteven Rostedt open (IN, "git log --pretty=oneline $end|") or 7336c5ee0beSSteven Rostedt dodie "could not get git list"; 7346c5ee0beSSteven Rostedt 7356c5ee0beSSteven Rostedt my @list; 7366c5ee0beSSteven Rostedt 7376c5ee0beSSteven Rostedt while (<IN>) { 7386c5ee0beSSteven Rostedt chomp; 7396c5ee0beSSteven Rostedt $list[$#list+1] = $_; 7406c5ee0beSSteven Rostedt last if (/^$start/); 7416c5ee0beSSteven Rostedt } 7426c5ee0beSSteven Rostedt close(IN); 7436c5ee0beSSteven Rostedt 7446c5ee0beSSteven Rostedt if ($list[$#list] !~ /^$start/) { 745*2b7d9b21SSteven Rostedt fail "SHA1 $start not found"; 7466c5ee0beSSteven Rostedt } 7476c5ee0beSSteven Rostedt 7486c5ee0beSSteven Rostedt # go backwards in the list 7496c5ee0beSSteven Rostedt @list = reverse @list; 7506c5ee0beSSteven Rostedt 7516c5ee0beSSteven Rostedt my $save_clean = $noclean; 7526c5ee0beSSteven Rostedt 7536c5ee0beSSteven Rostedt $in_patchcheck = 1; 7546c5ee0beSSteven Rostedt foreach my $item (@list) { 7556c5ee0beSSteven Rostedt my $sha1 = $item; 7566c5ee0beSSteven Rostedt $sha1 =~ s/^([[:xdigit:]]+).*/$1/; 7576c5ee0beSSteven Rostedt 7586c5ee0beSSteven Rostedt doprint "\nProcessing commit $item\n\n"; 7596c5ee0beSSteven Rostedt 7606c5ee0beSSteven Rostedt run_command "git checkout $sha1" or 7616c5ee0beSSteven Rostedt die "Failed to checkout $sha1"; 7626c5ee0beSSteven Rostedt 7636c5ee0beSSteven Rostedt # only clean on the first and last patch 7646c5ee0beSSteven Rostedt if ($item eq $list[0] || 7656c5ee0beSSteven Rostedt $item eq $list[$#list]) { 7666c5ee0beSSteven Rostedt $noclean = $save_clean; 7676c5ee0beSSteven Rostedt } else { 7686c5ee0beSSteven Rostedt $noclean = 1; 7696c5ee0beSSteven Rostedt } 7706c5ee0beSSteven Rostedt 7716c5ee0beSSteven Rostedt if (defined($minconfig)) { 772*2b7d9b21SSteven Rostedt build "useconfig:$minconfig" or return 0; 7736c5ee0beSSteven Rostedt } else { 7746c5ee0beSSteven Rostedt # ?? no config to use? 775*2b7d9b21SSteven Rostedt build "oldconfig" or return 0; 7766c5ee0beSSteven Rostedt } 7776c5ee0beSSteven Rostedt 778*2b7d9b21SSteven Rostedt check_buildlog $sha1 or return 0; 7796c5ee0beSSteven Rostedt 7806c5ee0beSSteven Rostedt next if ($type eq "build"); 7816c5ee0beSSteven Rostedt 7826c5ee0beSSteven Rostedt get_grub_index; 7836c5ee0beSSteven Rostedt get_version; 7846c5ee0beSSteven Rostedt install; 785*2b7d9b21SSteven Rostedt monitor or return 0; 7866c5ee0beSSteven Rostedt 7876c5ee0beSSteven Rostedt next if ($type eq "boot"); 788*2b7d9b21SSteven Rostedt do_run_test or next; 7896c5ee0beSSteven Rostedt } 7906c5ee0beSSteven Rostedt $in_patchcheck = 0; 7916c5ee0beSSteven Rostedt success $i; 792*2b7d9b21SSteven Rostedt 793*2b7d9b21SSteven Rostedt return 1; 7946c5ee0beSSteven Rostedt} 7956c5ee0beSSteven Rostedt 7962545eb61SSteven Rostedtread_config $ARGV[0]; 7972545eb61SSteven Rostedt 7982545eb61SSteven Rostedt# mandatory configs 7992545eb61SSteven Rostedtdie "MACHINE not defined\n" if (!defined($opt{"MACHINE"})); 8002545eb61SSteven Rostedtdie "SSH_USER not defined\n" if (!defined($opt{"SSH_USER"})); 8012545eb61SSteven Rostedtdie "BUILD_DIR not defined\n" if (!defined($opt{"BUILD_DIR"})); 8022545eb61SSteven Rostedtdie "OUTPUT_DIR not defined\n" if (!defined($opt{"OUTPUT_DIR"})); 8032545eb61SSteven Rostedtdie "BUILD_TARGET not defined\n" if (!defined($opt{"BUILD_TARGET"})); 80475c3fda7SSteven Rostedtdie "TARGET_IMAGE not defined\n" if (!defined($opt{"TARGET_IMAGE"})); 8052545eb61SSteven Rostedtdie "POWER_CYCLE not defined\n" if (!defined($opt{"POWER_CYCLE"})); 8062545eb61SSteven Rostedtdie "CONSOLE not defined\n" if (!defined($opt{"CONSOLE"})); 8072545eb61SSteven Rostedtdie "LOCALVERSION not defined\n" if (!defined($opt{"LOCALVERSION"})); 8082545eb61SSteven Rostedtdie "GRUB_MENU not defined\n" if (!defined($opt{"GRUB_MENU"})); 8092545eb61SSteven Rostedt 8102545eb61SSteven Rostedtchdir $opt{"BUILD_DIR"} || die "can't change directory to $opt{BUILD_DIR}"; 8112545eb61SSteven Rostedt 8122545eb61SSteven Rostedt$target = "$opt{SSH_USER}\@$opt{MACHINE}"; 8132545eb61SSteven Rostedt 814*2b7d9b21SSteven Rostedtif ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { 815*2b7d9b21SSteven Rostedt unlink $opt{"LOG_FILE"}; 816*2b7d9b21SSteven Rostedt} 8172545eb61SSteven Rostedt 818*2b7d9b21SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n\n"; 819*2b7d9b21SSteven Rostedt 820*2b7d9b21SSteven Rostedtforeach my $option (sort keys %opt) { 821*2b7d9b21SSteven Rostedt doprint "$option = $opt{$option}\n"; 822*2b7d9b21SSteven Rostedt} 8232545eb61SSteven Rostedt 8242545eb61SSteven Rostedt$make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}"; 8252545eb61SSteven Rostedt 8265a391fbfSSteven Rostedtsub set_build_option { 8275a391fbfSSteven Rostedt my ($name, $i) = @_; 8285a391fbfSSteven Rostedt 8295a391fbfSSteven Rostedt my $option = "$name\[$i\]"; 8305a391fbfSSteven Rostedt 8315a391fbfSSteven Rostedt if (defined($opt{$option})) { 8325a391fbfSSteven Rostedt return $opt{$option}; 8335a391fbfSSteven Rostedt } 8345a391fbfSSteven Rostedt 8355a391fbfSSteven Rostedt if (defined($opt{$name})) { 8365a391fbfSSteven Rostedt return $opt{$name}; 8375a391fbfSSteven Rostedt } 8385a391fbfSSteven Rostedt 8395a391fbfSSteven Rostedt return undef; 8405a391fbfSSteven Rostedt} 8415a391fbfSSteven Rostedt 8422545eb61SSteven Rostedt# First we need to do is the builds 8432545eb61SSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { 8442545eb61SSteven Rostedt my $type = "BUILD_TYPE[$i]"; 8452545eb61SSteven Rostedt 8461a5cfce3SSteven Rostedt if (!defined($opt{$type})) { 8471a5cfce3SSteven Rostedt $opt{$type} = $opt{"DEFAULT_BUILD_TYPE"}; 8481a5cfce3SSteven Rostedt } 8491a5cfce3SSteven Rostedt 8505a391fbfSSteven Rostedt $noclean = set_build_option("BUILD_NOCLEAN", $i); 8515a391fbfSSteven Rostedt $minconfig = set_build_option("MIN_CONFIG", $i); 8525a391fbfSSteven Rostedt $run_test = set_build_option("TEST", $i); 853*2b7d9b21SSteven Rostedt $addconfig = set_build_option("ADD_CONFIG", $i); 8542545eb61SSteven Rostedt 8552545eb61SSteven Rostedt doprint "\n\n"; 8562545eb61SSteven Rostedt doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $opt{$type}\n\n"; 8572545eb61SSteven Rostedt 858*2b7d9b21SSteven Rostedt if (!defined($minconfig)) { 859*2b7d9b21SSteven Rostedt $minconfig = $addconfig; 860*2b7d9b21SSteven Rostedt 861*2b7d9b21SSteven Rostedt } elsif (defined($addconfig)) { 862*2b7d9b21SSteven Rostedt run_command "cat $addconfig $minconfig > $opt{TMP_DIR}/use_config" or 863*2b7d9b21SSteven Rostedt dodie "Failed to create temp config"; 864*2b7d9b21SSteven Rostedt $minconfig = "$opt{TMP_DIR}/use_config"; 865*2b7d9b21SSteven Rostedt } 866*2b7d9b21SSteven Rostedt 8676c5ee0beSSteven Rostedt my $checkout = $opt{"CHECKOUT[$i]"}; 8686c5ee0beSSteven Rostedt if (defined($checkout)) { 8696c5ee0beSSteven Rostedt run_command "git checkout $checkout" or 8706c5ee0beSSteven Rostedt die "failed to checkout $checkout"; 8716c5ee0beSSteven Rostedt } 8726c5ee0beSSteven Rostedt 8735f9b6cedSSteven Rostedt if ($opt{$type} eq "bisect") { 8745f9b6cedSSteven Rostedt bisect $i; 8755f9b6cedSSteven Rostedt next; 8766c5ee0beSSteven Rostedt } elsif ($opt{$type} eq "patchcheck") { 8776c5ee0beSSteven Rostedt patchcheck $i; 8786c5ee0beSSteven Rostedt next; 8795f9b6cedSSteven Rostedt } 8805f9b6cedSSteven Rostedt 8812545eb61SSteven Rostedt if ($opt{$type} ne "nobuild") { 882*2b7d9b21SSteven Rostedt build $opt{$type} or next; 8832545eb61SSteven Rostedt } 8842545eb61SSteven Rostedt 8855f9b6cedSSteven Rostedt get_grub_index; 8865f9b6cedSSteven Rostedt get_version; 8872545eb61SSteven Rostedt install; 888*2b7d9b21SSteven Rostedt monitor or next; 8895a391fbfSSteven Rostedt 8905a391fbfSSteven Rostedt if (defined($run_test)) { 891*2b7d9b21SSteven Rostedt do_run_test or next; 8925a391fbfSSteven Rostedt } 8935a391fbfSSteven Rostedt 8945f9b6cedSSteven Rostedt success $i; 89575c3fda7SSteven Rostedt} 8962545eb61SSteven Rostedt 8975c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) { 89875c3fda7SSteven Rostedt halt; 8991a5cfce3SSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"}) { 90075c3fda7SSteven Rostedt reboot; 9015c42fc5bSSteven Rostedt} 90275c3fda7SSteven Rostedt 9032545eb61SSteven Rostedtexit 0; 904