xref: /openbmc/linux/tools/testing/ktest/ktest.pl (revision 2b7d9b21426f10448cb047d1d7c3be05da848fd2)
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