xref: /openbmc/linux/tools/testing/ktest/ktest.pl (revision d6ce2a0b33eb71f6862dfb6cbddd0e842f8132de)
12545eb61SSteven Rostedt#!/usr/bin/perl -w
2*d6ce2a0bSSteven Rostedt#
3*d6ce2a0bSSteven Rostedt# Copywrite 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
4*d6ce2a0bSSteven Rostedt# Licensed under the terms of the GNU GPL License version 2
5*d6ce2a0bSSteven 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";
222545eb61SSteven Rostedt$opt{"TIMEOUT"}			= 50;
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
322545eb61SSteven Rostedt
332545eb61SSteven Rostedtmy $version;
342545eb61SSteven Rostedtmy $grub_number;
352545eb61SSteven Rostedtmy $target;
362545eb61SSteven Rostedtmy $make;
375c42fc5bSSteven Rostedtmy $noclean;
385f9b6cedSSteven Rostedtmy $minconfig;
395f9b6cedSSteven Rostedtmy $in_bisect = 0;
405f9b6cedSSteven Rostedtmy $bisect_bad = "";
41*d6ce2a0bSSteven Rostedtmy $reverse_bisect;
426c5ee0beSSteven Rostedtmy $in_patchcheck = 0;
435a391fbfSSteven Rostedtmy $run_test;
446c5ee0beSSteven Rostedtmy $redirect;
452545eb61SSteven Rostedt
462545eb61SSteven Rostedtsub read_config {
472545eb61SSteven Rostedt    my ($config) = @_;
482545eb61SSteven Rostedt
492545eb61SSteven Rostedt    open(IN, $config) || die "can't read file $config";
502545eb61SSteven Rostedt
512545eb61SSteven Rostedt    while (<IN>) {
522545eb61SSteven Rostedt
532545eb61SSteven Rostedt	# ignore blank lines and comments
542545eb61SSteven Rostedt	next if (/^\s*$/ || /\s*\#/);
552545eb61SSteven Rostedt
562545eb61SSteven Rostedt	if (/^\s*(\S+)\s*=\s*(.*?)\s*$/) {
572545eb61SSteven Rostedt	    my $lvalue = $1;
582545eb61SSteven Rostedt	    my $rvalue = $2;
592545eb61SSteven Rostedt
602545eb61SSteven Rostedt	    $opt{$lvalue} = $rvalue;
612545eb61SSteven Rostedt	}
622545eb61SSteven Rostedt    }
632545eb61SSteven Rostedt
642545eb61SSteven Rostedt    close(IN);
652545eb61SSteven Rostedt}
662545eb61SSteven Rostedt
675f9b6cedSSteven Rostedtsub logit {
682545eb61SSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
692545eb61SSteven Rostedt	open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
702545eb61SSteven Rostedt	print OUT @_;
712545eb61SSteven Rostedt	close(OUT);
722545eb61SSteven Rostedt    }
732545eb61SSteven Rostedt}
742545eb61SSteven Rostedt
755f9b6cedSSteven Rostedtsub doprint {
765f9b6cedSSteven Rostedt    print @_;
775f9b6cedSSteven Rostedt    logit @_;
785f9b6cedSSteven Rostedt}
795f9b6cedSSteven Rostedt
805c42fc5bSSteven Rostedtsub dodie {
815a391fbfSSteven Rostedt    doprint "CRITICAL FAILURE... ", @_, "\n";
825c42fc5bSSteven Rostedt
8375c3fda7SSteven Rostedt    if ($opt{"REBOOT_ON_ERROR"}) {
8475c3fda7SSteven Rostedt	doprint "REBOOTING\n";
8575c3fda7SSteven Rostedt	`$opt{"POWER_CYCLE"}`;
8675c3fda7SSteven Rostedt
8775c3fda7SSteven Rostedt    } elsif ($opt{"POWEROFF_ON_ERROR"} && defined($opt{"POWER_OFF"})) {
885c42fc5bSSteven Rostedt	doprint "POWERING OFF\n";
895c42fc5bSSteven Rostedt	`$opt{"POWER_OFF"}`;
905c42fc5bSSteven Rostedt    }
9175c3fda7SSteven Rostedt
925c42fc5bSSteven Rostedt    die @_;
935c42fc5bSSteven Rostedt}
945c42fc5bSSteven Rostedt
952545eb61SSteven Rostedtsub run_command {
962545eb61SSteven Rostedt    my ($command) = @_;
97*d6ce2a0bSSteven Rostedt    my $dolog = 0;
98*d6ce2a0bSSteven Rostedt    my $dord = 0;
99*d6ce2a0bSSteven Rostedt    my $pid;
100*d6ce2a0bSSteven Rostedt
101*d6ce2a0bSSteven Rostedt    doprint("$command ... ");
102*d6ce2a0bSSteven Rostedt
103*d6ce2a0bSSteven Rostedt    $pid = open(CMD, "$command 2>&1 |") or
104*d6ce2a0bSSteven Rostedt	dodie "unable to exec $command";
1052545eb61SSteven Rostedt
1062545eb61SSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
107*d6ce2a0bSSteven Rostedt	open(LOG, ">>$opt{LOG_FILE}") or
108*d6ce2a0bSSteven Rostedt	    dodie "failed to write to log";
109*d6ce2a0bSSteven Rostedt	$dolog = 1;
1106c5ee0beSSteven Rostedt    }
1116c5ee0beSSteven Rostedt
1126c5ee0beSSteven Rostedt    if (defined($redirect)) {
113*d6ce2a0bSSteven Rostedt	open (RD, ">$redirect") or
114*d6ce2a0bSSteven Rostedt	    dodie "failed to write to redirect $redirect";
115*d6ce2a0bSSteven Rostedt	$dord = 1;
1162545eb61SSteven Rostedt    }
1172545eb61SSteven Rostedt
118*d6ce2a0bSSteven Rostedt    while (<CMD>) {
119*d6ce2a0bSSteven Rostedt	print LOG if ($dolog);
120*d6ce2a0bSSteven Rostedt	print RD  if ($dord);
121*d6ce2a0bSSteven Rostedt    }
1222545eb61SSteven Rostedt
123*d6ce2a0bSSteven Rostedt    waitpid($pid, 0);
1242545eb61SSteven Rostedt    my $failed = $?;
1252545eb61SSteven Rostedt
126*d6ce2a0bSSteven Rostedt    close(CMD);
127*d6ce2a0bSSteven Rostedt    close(LOG) if ($dolog);
128*d6ce2a0bSSteven Rostedt    close(RD)  if ($dord);
129*d6ce2a0bSSteven Rostedt
1302545eb61SSteven Rostedt    if ($failed) {
1312545eb61SSteven Rostedt	doprint "FAILED!\n";
1322545eb61SSteven Rostedt    } else {
1332545eb61SSteven Rostedt	doprint "SUCCESS\n";
1342545eb61SSteven Rostedt    }
1352545eb61SSteven Rostedt
1365f9b6cedSSteven Rostedt    return !$failed;
1375f9b6cedSSteven Rostedt}
1385f9b6cedSSteven Rostedt
1395f9b6cedSSteven Rostedtsub get_grub_index {
1405f9b6cedSSteven Rostedt
1415a391fbfSSteven Rostedt    return if (defined($grub_number));
1425f9b6cedSSteven Rostedt
1435f9b6cedSSteven Rostedt    doprint "Find grub menu ... ";
1445f9b6cedSSteven Rostedt    $grub_number = -1;
1455f9b6cedSSteven Rostedt    open(IN, "ssh $target cat /boot/grub/menu.lst |")
1465f9b6cedSSteven Rostedt	or die "unable to get menu.lst";
1475f9b6cedSSteven Rostedt    while (<IN>) {
1485f9b6cedSSteven Rostedt	if (/^\s*title\s+$opt{GRUB_MENU}\s*$/) {
1495f9b6cedSSteven Rostedt	    $grub_number++;
1505f9b6cedSSteven Rostedt	    last;
1515f9b6cedSSteven Rostedt	} elsif (/^\s*title\s/) {
1525f9b6cedSSteven Rostedt	    $grub_number++;
1535f9b6cedSSteven Rostedt	}
1545f9b6cedSSteven Rostedt    }
1555f9b6cedSSteven Rostedt    close(IN);
1565f9b6cedSSteven Rostedt
1575f9b6cedSSteven Rostedt    die "Could not find '$opt{GRUB_MENU}' in /boot/grub/menu on $opt{MACHINE}"
1585f9b6cedSSteven Rostedt	if ($grub_number < 0);
1595f9b6cedSSteven Rostedt    doprint "$grub_number\n";
1602545eb61SSteven Rostedt}
1612545eb61SSteven Rostedt
1622545eb61SSteven Rostedtmy $timeout = $opt{"TIMEOUT"};
1632545eb61SSteven Rostedt
1642545eb61SSteven Rostedtsub wait_for_input
1652545eb61SSteven Rostedt{
1662545eb61SSteven Rostedt    my ($fp, $time) = @_;
1672545eb61SSteven Rostedt    my $rin;
1682545eb61SSteven Rostedt    my $ready;
1692545eb61SSteven Rostedt    my $line;
1702545eb61SSteven Rostedt    my $ch;
1712545eb61SSteven Rostedt
1722545eb61SSteven Rostedt    if (!defined($time)) {
1732545eb61SSteven Rostedt	$time = $timeout;
1742545eb61SSteven Rostedt    }
1752545eb61SSteven Rostedt
1762545eb61SSteven Rostedt    $rin = '';
1772545eb61SSteven Rostedt    vec($rin, fileno($fp), 1) = 1;
1782545eb61SSteven Rostedt    $ready = select($rin, undef, undef, $time);
1792545eb61SSteven Rostedt
1802545eb61SSteven Rostedt    $line = "";
1812545eb61SSteven Rostedt
1822545eb61SSteven Rostedt    # try to read one char at a time
1832545eb61SSteven Rostedt    while (sysread $fp, $ch, 1) {
1842545eb61SSteven Rostedt	$line .= $ch;
1852545eb61SSteven Rostedt	last if ($ch eq "\n");
1862545eb61SSteven Rostedt    }
1872545eb61SSteven Rostedt
1882545eb61SSteven Rostedt    if (!length($line)) {
1892545eb61SSteven Rostedt	return undef;
1902545eb61SSteven Rostedt    }
1912545eb61SSteven Rostedt
1922545eb61SSteven Rostedt    return $line;
1932545eb61SSteven Rostedt}
1942545eb61SSteven Rostedt
19575c3fda7SSteven Rostedtsub reboot_to {
1962545eb61SSteven Rostedt    run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
1972545eb61SSteven Rostedt}
1982545eb61SSteven Rostedt
1995a391fbfSSteven Rostedtsub open_console {
2005a391fbfSSteven Rostedt    my ($fp) = @_;
2015a391fbfSSteven Rostedt
2022545eb61SSteven Rostedt    my $flags;
2035a391fbfSSteven Rostedt
2045a391fbfSSteven Rostedt    my $pid = open($fp, "$opt{CONSOLE}|") or
2055a391fbfSSteven Rostedt	dodie "Can't open console $opt{CONSOLE}";
2065a391fbfSSteven Rostedt
2075a391fbfSSteven Rostedt    $flags = fcntl($fp, F_GETFL, 0) or
2085a391fbfSSteven Rostedt	dodie "Can't get flags for the socket: $!\n";
2095a391fbfSSteven Rostedt    $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
2105a391fbfSSteven Rostedt	dodie "Can't set flags for the socket: $!\n";
2115a391fbfSSteven Rostedt
2125a391fbfSSteven Rostedt    return $pid;
2135a391fbfSSteven Rostedt}
2145a391fbfSSteven Rostedt
2155a391fbfSSteven Rostedtsub close_console {
2165a391fbfSSteven Rostedt    my ($fp, $pid) = @_;
2175a391fbfSSteven Rostedt
2185a391fbfSSteven Rostedt    doprint "kill child process $pid\n";
2195a391fbfSSteven Rostedt    kill 2, $pid;
2205a391fbfSSteven Rostedt
2215a391fbfSSteven Rostedt    print "closing!\n";
2225a391fbfSSteven Rostedt    close($fp);
2235a391fbfSSteven Rostedt}
2245a391fbfSSteven Rostedt
2255a391fbfSSteven Rostedtsub monitor {
2262545eb61SSteven Rostedt    my $booted = 0;
2272545eb61SSteven Rostedt    my $bug = 0;
2282545eb61SSteven Rostedt    my $pid;
2295c42fc5bSSteven Rostedt    my $skip_call_trace = 0;
2305a391fbfSSteven Rostedt    my $fp = \*IN;
2312545eb61SSteven Rostedt
2325a391fbfSSteven Rostedt    $pid = open_console($fp);
2332545eb61SSteven Rostedt
2342545eb61SSteven Rostedt    my $line;
2352545eb61SSteven Rostedt    my $full_line = "";
2362545eb61SSteven Rostedt
2372545eb61SSteven Rostedt    doprint "Wait for monitor to settle down.\n";
2382545eb61SSteven Rostedt    # read the monitor and wait for the system to calm down
2392545eb61SSteven Rostedt    do {
2405a391fbfSSteven Rostedt	$line = wait_for_input($fp, 5);
2412545eb61SSteven Rostedt    } while (defined($line));
2422545eb61SSteven Rostedt
24375c3fda7SSteven Rostedt    reboot_to;
2442545eb61SSteven Rostedt
2452545eb61SSteven Rostedt    for (;;) {
2462545eb61SSteven Rostedt
2475a391fbfSSteven Rostedt	$line = wait_for_input($fp);
2482545eb61SSteven Rostedt
2492545eb61SSteven Rostedt	last if (!defined($line));
2502545eb61SSteven Rostedt
2512545eb61SSteven Rostedt	doprint $line;
2522545eb61SSteven Rostedt
2532545eb61SSteven Rostedt	# we are not guaranteed to get a full line
2542545eb61SSteven Rostedt	$full_line .= $line;
2552545eb61SSteven Rostedt
2562545eb61SSteven Rostedt	if ($full_line =~ /login:/) {
2572545eb61SSteven Rostedt	    $booted = 1;
2582545eb61SSteven Rostedt	}
2592545eb61SSteven Rostedt
2605c42fc5bSSteven Rostedt	if ($full_line =~ /\[ backtrace testing \]/) {
2615c42fc5bSSteven Rostedt	    $skip_call_trace = 1;
2625c42fc5bSSteven Rostedt	}
2635c42fc5bSSteven Rostedt
2642545eb61SSteven Rostedt	if ($full_line =~ /call trace:/i) {
2655c42fc5bSSteven Rostedt	    $bug = 1 if (!$skip_call_trace);
2665c42fc5bSSteven Rostedt	}
2675c42fc5bSSteven Rostedt
2685c42fc5bSSteven Rostedt	if ($full_line =~ /\[ end of backtrace testing \]/) {
2695c42fc5bSSteven Rostedt	    $skip_call_trace = 0;
2705c42fc5bSSteven Rostedt	}
2715c42fc5bSSteven Rostedt
2725c42fc5bSSteven Rostedt	if ($full_line =~ /Kernel panic -/) {
2732545eb61SSteven Rostedt	    $bug = 1;
2742545eb61SSteven Rostedt	}
2752545eb61SSteven Rostedt
2762545eb61SSteven Rostedt	if ($line =~ /\n/) {
2772545eb61SSteven Rostedt	    $full_line = "";
2782545eb61SSteven Rostedt	}
2792545eb61SSteven Rostedt    }
2802545eb61SSteven Rostedt
2815a391fbfSSteven Rostedt    close_console($fp, $pid);
2822545eb61SSteven Rostedt
2832545eb61SSteven Rostedt    if (!$booted) {
2845a391fbfSSteven Rostedt	return 1 if ($in_bisect);
2855c42fc5bSSteven Rostedt	dodie "failed - never got a boot prompt.\n";
2862545eb61SSteven Rostedt    }
2872545eb61SSteven Rostedt
2882545eb61SSteven Rostedt    if ($bug) {
2895a391fbfSSteven Rostedt	return 1 if ($in_bisect);
2905c42fc5bSSteven Rostedt	dodie "failed - got a bug report\n";
2912545eb61SSteven Rostedt    }
2925f9b6cedSSteven Rostedt
2935f9b6cedSSteven Rostedt    return 0;
2942545eb61SSteven Rostedt}
2952545eb61SSteven Rostedt
2962545eb61SSteven Rostedtsub install {
2972545eb61SSteven Rostedt
2985f9b6cedSSteven Rostedt    run_command "scp $opt{OUTPUT_DIR}/$opt{BUILD_TARGET} $target:$opt{TARGET_IMAGE}" or
2995c42fc5bSSteven Rostedt	dodie "failed to copy image";
3005f9b6cedSSteven Rostedt
3015f9b6cedSSteven Rostedt    my $install_mods = 0;
3025f9b6cedSSteven Rostedt
3035f9b6cedSSteven Rostedt    # should we process modules?
3045f9b6cedSSteven Rostedt    $install_mods = 0;
3055f9b6cedSSteven Rostedt    open(IN, "$opt{OUTPUT_DIR}/.config") or dodie("Can't read config file");
3065f9b6cedSSteven Rostedt    while (<IN>) {
3075f9b6cedSSteven Rostedt	if (/CONFIG_MODULES(=y)?/) {
3085f9b6cedSSteven Rostedt	    $install_mods = 1 if (defined($1));
3095f9b6cedSSteven Rostedt	    last;
3105f9b6cedSSteven Rostedt	}
3115f9b6cedSSteven Rostedt    }
3125f9b6cedSSteven Rostedt    close(IN);
3135f9b6cedSSteven Rostedt
3145f9b6cedSSteven Rostedt    if (!$install_mods) {
3155f9b6cedSSteven Rostedt	doprint "No modules needed\n";
3165f9b6cedSSteven Rostedt	return;
3172545eb61SSteven Rostedt    }
3182545eb61SSteven Rostedt
3195f9b6cedSSteven Rostedt    run_command "$make INSTALL_MOD_PATH=$opt{TMP_DIR} modules_install" or
3205f9b6cedSSteven Rostedt	dodie "Failed to install modules";
3215f9b6cedSSteven Rostedt
3222545eb61SSteven Rostedt    my $modlib = "/lib/modules/$version";
3235c42fc5bSSteven Rostedt    my $modtar = "autotest-mods.tar.bz2";
3242545eb61SSteven Rostedt
3255f9b6cedSSteven Rostedt    run_command "ssh $target rm -rf $modlib" or
3265c42fc5bSSteven Rostedt	dodie "failed to remove old mods: $modlib";
3272545eb61SSteven Rostedt
3285c42fc5bSSteven Rostedt    # would be nice if scp -r did not follow symbolic links
3295f9b6cedSSteven Rostedt    run_command "cd $opt{TMP_DIR} && tar -cjf $modtar lib/modules/$version" or
3305c42fc5bSSteven Rostedt	dodie "making tarball";
3315c42fc5bSSteven Rostedt
3325f9b6cedSSteven Rostedt    run_command "scp $opt{TMP_DIR}/$modtar $target:/tmp" or
3335c42fc5bSSteven Rostedt	dodie "failed to copy modules";
3345c42fc5bSSteven Rostedt
3355c42fc5bSSteven Rostedt    unlink "$opt{TMP_DIR}/$modtar";
3365c42fc5bSSteven Rostedt
3375f9b6cedSSteven Rostedt    run_command "ssh $target '(cd / && tar xf /tmp/$modtar)'" or
3385c42fc5bSSteven Rostedt	dodie "failed to tar modules";
3395c42fc5bSSteven Rostedt
3405c42fc5bSSteven Rostedt    run_command "ssh $target rm -f /tmp/$modtar";
3412545eb61SSteven Rostedt}
3422545eb61SSteven Rostedt
3436c5ee0beSSteven Rostedtsub check_buildlog {
3446c5ee0beSSteven Rostedt    my ($patch) = @_;
3456c5ee0beSSteven Rostedt
3466c5ee0beSSteven Rostedt    my $buildlog = "$opt{TMP_DIR}/buildlog";
3476c5ee0beSSteven Rostedt    my @files = `git show $patch | diffstat -l`;
3486c5ee0beSSteven Rostedt
3496c5ee0beSSteven Rostedt    open(IN, "git show $patch |") or
3506c5ee0beSSteven Rostedt	dodie "failed to show $patch";
3516c5ee0beSSteven Rostedt    while (<IN>) {
3526c5ee0beSSteven Rostedt	if (m,^--- a/(.*),) {
3536c5ee0beSSteven Rostedt	    chomp $1;
3546c5ee0beSSteven Rostedt	    $files[$#files] = $1;
3556c5ee0beSSteven Rostedt	}
3566c5ee0beSSteven Rostedt    }
3576c5ee0beSSteven Rostedt    close(IN);
3586c5ee0beSSteven Rostedt
3596c5ee0beSSteven Rostedt    open(IN, $buildlog) or dodie "Can't open $buildlog";
3606c5ee0beSSteven Rostedt    while (<IN>) {
3616c5ee0beSSteven Rostedt	if (/^\s*(.*?):.*(warning|error)/) {
3626c5ee0beSSteven Rostedt	    my $err = $1;
3636c5ee0beSSteven Rostedt	    foreach my $file (@files) {
3646c5ee0beSSteven Rostedt		my $fullpath = "$opt{BUILD_DIR}/$file";
3656c5ee0beSSteven Rostedt		if ($file eq $err || $fullpath eq $err) {
3666c5ee0beSSteven Rostedt		    dodie "$file built with warnings";
3676c5ee0beSSteven Rostedt		}
3686c5ee0beSSteven Rostedt	    }
3696c5ee0beSSteven Rostedt	}
3706c5ee0beSSteven Rostedt    }
3716c5ee0beSSteven Rostedt    close(IN);
3726c5ee0beSSteven Rostedt}
3736c5ee0beSSteven Rostedt
3742545eb61SSteven Rostedtsub build {
3752545eb61SSteven Rostedt    my ($type) = @_;
3765c42fc5bSSteven Rostedt    my $defconfig = "";
3775c42fc5bSSteven Rostedt    my $append = "";
3782545eb61SSteven Rostedt
37975c3fda7SSteven Rostedt    if ($type =~ /^useconfig:(.*)/) {
3805f9b6cedSSteven Rostedt	run_command "cp $1 $opt{OUTPUT_DIR}/.config" or
38175c3fda7SSteven Rostedt	    dodie "could not copy $1 to .config";
3825f9b6cedSSteven Rostedt
38375c3fda7SSteven Rostedt	$type = "oldconfig";
38475c3fda7SSteven Rostedt    }
38575c3fda7SSteven Rostedt
3865c42fc5bSSteven Rostedt    # old config can ask questions
3875c42fc5bSSteven Rostedt    if ($type eq "oldconfig") {
3885c42fc5bSSteven Rostedt	$append = "yes ''|";
38975c3fda7SSteven Rostedt
39075c3fda7SSteven Rostedt	# allow for empty configs
39175c3fda7SSteven Rostedt	run_command "touch $opt{OUTPUT_DIR}/.config";
39275c3fda7SSteven Rostedt
3935f9b6cedSSteven Rostedt	run_command "mv $opt{OUTPUT_DIR}/.config $opt{OUTPUT_DIR}/config_temp" or
3945c42fc5bSSteven Rostedt	    dodie "moving .config";
3955c42fc5bSSteven Rostedt
3965f9b6cedSSteven Rostedt	if (!$noclean && !run_command "$make mrproper") {
3975c42fc5bSSteven Rostedt	    dodie "make mrproper";
3985c42fc5bSSteven Rostedt	}
3995c42fc5bSSteven Rostedt
4005f9b6cedSSteven Rostedt	run_command "mv $opt{OUTPUT_DIR}/config_temp $opt{OUTPUT_DIR}/.config" or
4015c42fc5bSSteven Rostedt	    dodie "moving config_temp";
4025c42fc5bSSteven Rostedt
4035c42fc5bSSteven Rostedt    } elsif (!$noclean) {
4042545eb61SSteven Rostedt	unlink "$opt{OUTPUT_DIR}/.config";
4055f9b6cedSSteven Rostedt	run_command "$make mrproper" or
4065c42fc5bSSteven Rostedt	    dodie "make mrproper";
4075c42fc5bSSteven Rostedt    }
4082545eb61SSteven Rostedt
4092545eb61SSteven Rostedt    # add something to distinguish this build
4105c42fc5bSSteven Rostedt    open(OUT, "> $opt{OUTPUT_DIR}/localversion") or dodie("Can't make localversion file");
4112545eb61SSteven Rostedt    print OUT "$opt{LOCALVERSION}\n";
4122545eb61SSteven Rostedt    close(OUT);
4132545eb61SSteven Rostedt
4145f9b6cedSSteven Rostedt    if (defined($minconfig)) {
4155f9b6cedSSteven Rostedt	$defconfig = "KCONFIG_ALLCONFIG=$minconfig";
4162545eb61SSteven Rostedt    }
4172545eb61SSteven Rostedt
4185f9b6cedSSteven Rostedt    run_command "$defconfig $append $make $type" or
4195c42fc5bSSteven Rostedt	dodie "failed make config";
4202545eb61SSteven Rostedt
4216c5ee0beSSteven Rostedt    # patch check will examine the log
4226c5ee0beSSteven Rostedt    if ($in_patchcheck) {
4236c5ee0beSSteven Rostedt	$redirect = "$opt{TMP_DIR}/buildlog";
4246c5ee0beSSteven Rostedt    }
4256c5ee0beSSteven Rostedt
4265f9b6cedSSteven Rostedt    if (!run_command "$make $opt{BUILD_OPTIONS}") {
4276c5ee0beSSteven Rostedt	undef $redirect;
4285f9b6cedSSteven Rostedt	# bisect may need this to pass
4295f9b6cedSSteven Rostedt	return 1 if ($in_bisect);
4305c42fc5bSSteven Rostedt	dodie "failed build";
4312545eb61SSteven Rostedt    }
4326c5ee0beSSteven Rostedt    undef $redirect;
4335f9b6cedSSteven Rostedt
4345f9b6cedSSteven Rostedt    return 0;
4352545eb61SSteven Rostedt}
4362545eb61SSteven Rostedt
43775c3fda7SSteven Rostedtsub reboot {
43875c3fda7SSteven Rostedt    # try to reboot normally
4395f9b6cedSSteven Rostedt    if (!run_command "ssh $target reboot") {
44075c3fda7SSteven Rostedt	# nope? power cycle it.
44175c3fda7SSteven Rostedt	run_command "$opt{POWER_CYCLE}";
44275c3fda7SSteven Rostedt    }
44375c3fda7SSteven Rostedt}
44475c3fda7SSteven Rostedt
44575c3fda7SSteven Rostedtsub halt {
4465f9b6cedSSteven Rostedt    if (!run_command "ssh $target halt" or defined($opt{"POWER_OFF"})) {
44775c3fda7SSteven Rostedt	# nope? the zap it!
44875c3fda7SSteven Rostedt	run_command "$opt{POWER_OFF}";
44975c3fda7SSteven Rostedt    }
45075c3fda7SSteven Rostedt}
45175c3fda7SSteven Rostedt
4525f9b6cedSSteven Rostedtsub success {
4535f9b6cedSSteven Rostedt    my ($i) = @_;
4545f9b6cedSSteven Rostedt
4555f9b6cedSSteven Rostedt    doprint "\n\n*******************************************\n";
4565f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
4575f9b6cedSSteven Rostedt    doprint     "**            SUCCESS!!!!                **\n";
4585f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
4595f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
4605f9b6cedSSteven Rostedt
4615f9b6cedSSteven Rostedt    if ($i != $opt{"NUM_BUILDS"}) {
4625f9b6cedSSteven Rostedt	reboot;
4635f9b6cedSSteven Rostedt	doprint "Sleeping $opt{SLEEP_TIME} seconds\n";
4645f9b6cedSSteven Rostedt	sleep "$opt{SLEEP_TIME}";
4655f9b6cedSSteven Rostedt    }
4665f9b6cedSSteven Rostedt}
4675f9b6cedSSteven Rostedt
4685f9b6cedSSteven Rostedtsub get_version {
4695f9b6cedSSteven Rostedt    # get the release name
4705f9b6cedSSteven Rostedt    doprint "$make kernelrelease ... ";
4715f9b6cedSSteven Rostedt    $version = `$make kernelrelease | tail -1`;
4725f9b6cedSSteven Rostedt    chomp($version);
4735f9b6cedSSteven Rostedt    doprint "$version\n";
4745f9b6cedSSteven Rostedt}
4755f9b6cedSSteven Rostedt
4765a391fbfSSteven Rostedtsub child_run_test {
4775a391fbfSSteven Rostedt    my $failed;
4785a391fbfSSteven Rostedt
4795a391fbfSSteven Rostedt    $failed = !run_command $run_test;
4805a391fbfSSteven Rostedt    exit $failed;
4815a391fbfSSteven Rostedt}
4825a391fbfSSteven Rostedt
4835a391fbfSSteven Rostedtmy $child_done;
4845a391fbfSSteven Rostedt
4855a391fbfSSteven Rostedtsub child_finished {
4865a391fbfSSteven Rostedt    $child_done = 1;
4875a391fbfSSteven Rostedt}
4885a391fbfSSteven Rostedt
4895a391fbfSSteven Rostedtsub do_run_test {
4905a391fbfSSteven Rostedt    my $child_pid;
4915a391fbfSSteven Rostedt    my $child_exit;
4925a391fbfSSteven Rostedt    my $pid;
4935a391fbfSSteven Rostedt    my $line;
4945a391fbfSSteven Rostedt    my $full_line;
4955a391fbfSSteven Rostedt    my $bug = 0;
4965a391fbfSSteven Rostedt    my $fp = \*IN;
4975a391fbfSSteven Rostedt
4985a391fbfSSteven Rostedt    $pid = open_console($fp);
4995a391fbfSSteven Rostedt
5005a391fbfSSteven Rostedt    # read the monitor and wait for the system to calm down
5015a391fbfSSteven Rostedt    do {
5025a391fbfSSteven Rostedt	$line = wait_for_input($fp, 1);
5035a391fbfSSteven Rostedt    } while (defined($line));
5045a391fbfSSteven Rostedt
5055a391fbfSSteven Rostedt    $child_done = 0;
5065a391fbfSSteven Rostedt
5075a391fbfSSteven Rostedt    $SIG{CHLD} = qw(child_finished);
5085a391fbfSSteven Rostedt
5095a391fbfSSteven Rostedt    $child_pid = fork;
5105a391fbfSSteven Rostedt
5115a391fbfSSteven Rostedt    child_run_test if (!$child_pid);
5125a391fbfSSteven Rostedt
5135a391fbfSSteven Rostedt    $full_line = "";
5145a391fbfSSteven Rostedt
5155a391fbfSSteven Rostedt    do {
5165a391fbfSSteven Rostedt	$line = wait_for_input($fp, 1);
5175a391fbfSSteven Rostedt	if (defined($line)) {
5185a391fbfSSteven Rostedt
5195a391fbfSSteven Rostedt	    # we are not guaranteed to get a full line
5205a391fbfSSteven Rostedt	    $full_line .= $line;
5215a391fbfSSteven Rostedt
5225a391fbfSSteven Rostedt	    if ($full_line =~ /call trace:/i) {
5235a391fbfSSteven Rostedt		$bug = 1;
5245a391fbfSSteven Rostedt	    }
5255a391fbfSSteven Rostedt
5265a391fbfSSteven Rostedt	    if ($full_line =~ /Kernel panic -/) {
5275a391fbfSSteven Rostedt		$bug = 1;
5285a391fbfSSteven Rostedt	    }
5295a391fbfSSteven Rostedt
5305a391fbfSSteven Rostedt	    if ($line =~ /\n/) {
5315a391fbfSSteven Rostedt		$full_line = "";
5325a391fbfSSteven Rostedt	    }
5335a391fbfSSteven Rostedt	}
5345a391fbfSSteven Rostedt    } while (!$child_done && !$bug);
5355a391fbfSSteven Rostedt
5365a391fbfSSteven Rostedt    if ($bug) {
5375a391fbfSSteven Rostedt	doprint "Detected kernel crash!\n";
5385a391fbfSSteven Rostedt	# kill the child with extreme prejudice
5395a391fbfSSteven Rostedt	kill 9, $child_pid;
5405a391fbfSSteven Rostedt    }
5415a391fbfSSteven Rostedt
5425a391fbfSSteven Rostedt    waitpid $child_pid, 0;
5435a391fbfSSteven Rostedt    $child_exit = $?;
5445a391fbfSSteven Rostedt
5455a391fbfSSteven Rostedt    close_console($fp, $pid);
5465a391fbfSSteven Rostedt
5475a391fbfSSteven Rostedt    if ($bug || $child_exit) {
5485a391fbfSSteven Rostedt	return 1 if $in_bisect;
5495a391fbfSSteven Rostedt	dodie "test failed";
5505a391fbfSSteven Rostedt    }
5515a391fbfSSteven Rostedt    return 0;
5525a391fbfSSteven Rostedt}
5535a391fbfSSteven Rostedt
5545f9b6cedSSteven Rostedtsub run_bisect {
5555f9b6cedSSteven Rostedt    my ($type) = @_;
5565f9b6cedSSteven Rostedt
5575f9b6cedSSteven Rostedt    my $failed;
5585f9b6cedSSteven Rostedt    my $result;
5595f9b6cedSSteven Rostedt    my $output;
5605f9b6cedSSteven Rostedt    my $ret;
5615f9b6cedSSteven Rostedt
5625f9b6cedSSteven Rostedt
5635f9b6cedSSteven Rostedt    if (defined($minconfig)) {
5645f9b6cedSSteven Rostedt	$failed = build "useconfig:$minconfig";
5655f9b6cedSSteven Rostedt    } else {
5665f9b6cedSSteven Rostedt	# ?? no config to use?
5675f9b6cedSSteven Rostedt	$failed = build "oldconfig";
5685f9b6cedSSteven Rostedt    }
5695f9b6cedSSteven Rostedt
5705f9b6cedSSteven Rostedt    if ($type ne "build") {
5715f9b6cedSSteven Rostedt	dodie "Failed on build" if $failed;
5725f9b6cedSSteven Rostedt
5735f9b6cedSSteven Rostedt	# Now boot the box
5745f9b6cedSSteven Rostedt	get_grub_index;
5755f9b6cedSSteven Rostedt	get_version;
5765f9b6cedSSteven Rostedt	install;
5775f9b6cedSSteven Rostedt	$failed = monitor;
5785f9b6cedSSteven Rostedt
5795f9b6cedSSteven Rostedt	if ($type ne "boot") {
5805f9b6cedSSteven Rostedt	    dodie "Failed on boot" if $failed;
5815a391fbfSSteven Rostedt
5825a391fbfSSteven Rostedt	    $failed = do_run_test;
5835f9b6cedSSteven Rostedt	}
5845f9b6cedSSteven Rostedt    }
5855f9b6cedSSteven Rostedt
5865f9b6cedSSteven Rostedt    if ($failed) {
5875f9b6cedSSteven Rostedt	$result = "bad";
5885a391fbfSSteven Rostedt
5895a391fbfSSteven Rostedt	# reboot the box to a good kernel
5905a391fbfSSteven Rostedt	if ($type eq "boot") {
5915a391fbfSSteven Rostedt	    reboot;
5925a391fbfSSteven Rostedt	    doprint "sleep a little for reboot\n";
5935a391fbfSSteven Rostedt	    sleep $opt{"BISECT_SLEEP_TIME"};
5945a391fbfSSteven Rostedt	}
5955f9b6cedSSteven Rostedt    } else {
5965f9b6cedSSteven Rostedt	$result = "good";
5975f9b6cedSSteven Rostedt    }
5985f9b6cedSSteven Rostedt
599*d6ce2a0bSSteven Rostedt    # Are we looking for where it worked, not failed?
600*d6ce2a0bSSteven Rostedt    if ($reverse_bisect) {
601*d6ce2a0bSSteven Rostedt	if ($failed) {
602*d6ce2a0bSSteven Rostedt	    $result = "good";
603*d6ce2a0bSSteven Rostedt	} else {
604*d6ce2a0bSSteven Rostedt	    $result = "bad";
605*d6ce2a0bSSteven Rostedt	}
606*d6ce2a0bSSteven Rostedt    }
607*d6ce2a0bSSteven Rostedt
6085f9b6cedSSteven Rostedt    doprint "git bisect $result ... ";
6095f9b6cedSSteven Rostedt    $output = `git bisect $result 2>&1`;
6105f9b6cedSSteven Rostedt    $ret = $?;
6115f9b6cedSSteven Rostedt
6125f9b6cedSSteven Rostedt    logit $output;
6135f9b6cedSSteven Rostedt
6145f9b6cedSSteven Rostedt    if ($ret) {
6155f9b6cedSSteven Rostedt	doprint "FAILED\n";
6165f9b6cedSSteven Rostedt	dodie "Failed to git bisect";
6175f9b6cedSSteven Rostedt    }
6185f9b6cedSSteven Rostedt
6195f9b6cedSSteven Rostedt    doprint "SUCCESS\n";
6205a391fbfSSteven Rostedt    if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
6215f9b6cedSSteven Rostedt	doprint "$1 [$2]\n";
6225f9b6cedSSteven Rostedt    } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
6235f9b6cedSSteven Rostedt	$bisect_bad = $1;
6245f9b6cedSSteven Rostedt	doprint "Found bad commit... $1\n";
6255f9b6cedSSteven Rostedt	return 0;
6265a391fbfSSteven Rostedt    } else {
6275a391fbfSSteven Rostedt	# we already logged it, just print it now.
6285a391fbfSSteven Rostedt	print $output;
6295f9b6cedSSteven Rostedt    }
6305f9b6cedSSteven Rostedt
6315f9b6cedSSteven Rostedt
6325f9b6cedSSteven Rostedt    return 1;
6335f9b6cedSSteven Rostedt}
6345f9b6cedSSteven Rostedt
6355f9b6cedSSteven Rostedtsub bisect {
6365f9b6cedSSteven Rostedt    my ($i) = @_;
6375f9b6cedSSteven Rostedt
6385f9b6cedSSteven Rostedt    my $result;
6395f9b6cedSSteven Rostedt
6405f9b6cedSSteven Rostedt    die "BISECT_GOOD[$i] not defined\n"	if (!defined($opt{"BISECT_GOOD[$i]"}));
6415f9b6cedSSteven Rostedt    die "BISECT_BAD[$i] not defined\n"	if (!defined($opt{"BISECT_BAD[$i]"}));
6425f9b6cedSSteven Rostedt    die "BISECT_TYPE[$i] not defined\n"	if (!defined($opt{"BISECT_TYPE[$i]"}));
6435f9b6cedSSteven Rostedt
6445f9b6cedSSteven Rostedt    my $good = $opt{"BISECT_GOOD[$i]"};
6455f9b6cedSSteven Rostedt    my $bad = $opt{"BISECT_BAD[$i]"};
6465f9b6cedSSteven Rostedt    my $type = $opt{"BISECT_TYPE[$i]"};
6475f9b6cedSSteven Rostedt
648*d6ce2a0bSSteven Rostedt    if (defined($opt{"BISECT_REVERSE[$i]"}) &&
649*d6ce2a0bSSteven Rostedt	$opt{"BISECT_REVERSE[$i]"} == 1) {
650*d6ce2a0bSSteven Rostedt	doprint "Performing a reverse bisect (bad is good, good is bad!)\n";
651*d6ce2a0bSSteven Rostedt	$reverse_bisect = 1;
652*d6ce2a0bSSteven Rostedt    } else {
653*d6ce2a0bSSteven Rostedt	$reverse_bisect = 0;
654*d6ce2a0bSSteven Rostedt    }
655*d6ce2a0bSSteven Rostedt
6565f9b6cedSSteven Rostedt    $in_bisect = 1;
6575f9b6cedSSteven Rostedt
6585f9b6cedSSteven Rostedt    run_command "git bisect start" or
6595f9b6cedSSteven Rostedt	dodie "could not start bisect";
6605f9b6cedSSteven Rostedt
6615f9b6cedSSteven Rostedt    run_command "git bisect good $good" or
6625f9b6cedSSteven Rostedt	dodie "could not set bisect good to $good";
6635f9b6cedSSteven Rostedt
6645f9b6cedSSteven Rostedt    run_command "git bisect bad $bad" or
6655f9b6cedSSteven Rostedt	dodie "could not set bisect good to $bad";
6665f9b6cedSSteven Rostedt
6675a391fbfSSteven Rostedt    # Can't have a test without having a test to run
6685a391fbfSSteven Rostedt    if ($type eq "test" && !defined($run_test)) {
6695a391fbfSSteven Rostedt	$type = "boot";
6705a391fbfSSteven Rostedt    }
6715a391fbfSSteven Rostedt
6725f9b6cedSSteven Rostedt    do {
6735f9b6cedSSteven Rostedt	$result = run_bisect $type;
6745f9b6cedSSteven Rostedt    } while ($result);
6755f9b6cedSSteven Rostedt
6765f9b6cedSSteven Rostedt    run_command "git bisect log" or
6775f9b6cedSSteven Rostedt	dodie "could not capture git bisect log";
6785f9b6cedSSteven Rostedt
6795f9b6cedSSteven Rostedt    run_command "git bisect reset" or
6805f9b6cedSSteven Rostedt	dodie "could not reset git bisect";
6815f9b6cedSSteven Rostedt
6825f9b6cedSSteven Rostedt    doprint "Bad commit was [$bisect_bad]\n";
6835f9b6cedSSteven Rostedt
6845f9b6cedSSteven Rostedt    $in_bisect = 0;
6855f9b6cedSSteven Rostedt
6865f9b6cedSSteven Rostedt    success $i;
6875f9b6cedSSteven Rostedt}
6885f9b6cedSSteven Rostedt
6896c5ee0beSSteven Rostedtsub patchcheck {
6906c5ee0beSSteven Rostedt    my ($i) = @_;
6916c5ee0beSSteven Rostedt
6926c5ee0beSSteven Rostedt    die "PATCHCHECK_START[$i] not defined\n"
6936c5ee0beSSteven Rostedt	if (!defined($opt{"PATCHCHECK_START[$i]"}));
6946c5ee0beSSteven Rostedt    die "PATCHCHECK_TYPE[$i] not defined\n"
6956c5ee0beSSteven Rostedt	if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
6966c5ee0beSSteven Rostedt
6976c5ee0beSSteven Rostedt    my $start = $opt{"PATCHCHECK_START[$i]"};
6986c5ee0beSSteven Rostedt
6996c5ee0beSSteven Rostedt    my $end = "HEAD";
7006c5ee0beSSteven Rostedt    if (defined($opt{"PATCHCHECK_END[$i]"})) {
7016c5ee0beSSteven Rostedt	$end = $opt{"PATCHCHECK_END[$i]"};
7026c5ee0beSSteven Rostedt    }
7036c5ee0beSSteven Rostedt
7046c5ee0beSSteven Rostedt    my $type = $opt{"PATCHCHECK_TYPE[$i]"};
7056c5ee0beSSteven Rostedt
7066c5ee0beSSteven Rostedt    # Can't have a test without having a test to run
7076c5ee0beSSteven Rostedt    if ($type eq "test" && !defined($run_test)) {
7086c5ee0beSSteven Rostedt	$type = "boot";
7096c5ee0beSSteven Rostedt    }
7106c5ee0beSSteven Rostedt
7116c5ee0beSSteven Rostedt    open (IN, "git log --pretty=oneline $end|") or
7126c5ee0beSSteven Rostedt	dodie "could not get git list";
7136c5ee0beSSteven Rostedt
7146c5ee0beSSteven Rostedt    my @list;
7156c5ee0beSSteven Rostedt
7166c5ee0beSSteven Rostedt    while (<IN>) {
7176c5ee0beSSteven Rostedt	chomp;
7186c5ee0beSSteven Rostedt	$list[$#list+1] = $_;
7196c5ee0beSSteven Rostedt	last if (/^$start/);
7206c5ee0beSSteven Rostedt    }
7216c5ee0beSSteven Rostedt    close(IN);
7226c5ee0beSSteven Rostedt
7236c5ee0beSSteven Rostedt    if ($list[$#list] !~ /^$start/) {
7246c5ee0beSSteven Rostedt	dodie "SHA1 $start not found";
7256c5ee0beSSteven Rostedt    }
7266c5ee0beSSteven Rostedt
7276c5ee0beSSteven Rostedt    # go backwards in the list
7286c5ee0beSSteven Rostedt    @list = reverse @list;
7296c5ee0beSSteven Rostedt
7306c5ee0beSSteven Rostedt    my $save_clean = $noclean;
7316c5ee0beSSteven Rostedt
7326c5ee0beSSteven Rostedt    $in_patchcheck = 1;
7336c5ee0beSSteven Rostedt    foreach my $item (@list) {
7346c5ee0beSSteven Rostedt	my $sha1 = $item;
7356c5ee0beSSteven Rostedt	$sha1 =~ s/^([[:xdigit:]]+).*/$1/;
7366c5ee0beSSteven Rostedt
7376c5ee0beSSteven Rostedt	doprint "\nProcessing commit $item\n\n";
7386c5ee0beSSteven Rostedt
7396c5ee0beSSteven Rostedt	run_command "git checkout $sha1" or
7406c5ee0beSSteven Rostedt	    die "Failed to checkout $sha1";
7416c5ee0beSSteven Rostedt
7426c5ee0beSSteven Rostedt	# only clean on the first and last patch
7436c5ee0beSSteven Rostedt	if ($item eq $list[0] ||
7446c5ee0beSSteven Rostedt	    $item eq $list[$#list]) {
7456c5ee0beSSteven Rostedt	    $noclean = $save_clean;
7466c5ee0beSSteven Rostedt	} else {
7476c5ee0beSSteven Rostedt	    $noclean = 1;
7486c5ee0beSSteven Rostedt	}
7496c5ee0beSSteven Rostedt
7506c5ee0beSSteven Rostedt	if (defined($minconfig)) {
7516c5ee0beSSteven Rostedt	    build "useconfig:$minconfig";
7526c5ee0beSSteven Rostedt	} else {
7536c5ee0beSSteven Rostedt	    # ?? no config to use?
7546c5ee0beSSteven Rostedt	    build "oldconfig";
7556c5ee0beSSteven Rostedt	}
7566c5ee0beSSteven Rostedt
7576c5ee0beSSteven Rostedt	check_buildlog $sha1;
7586c5ee0beSSteven Rostedt
7596c5ee0beSSteven Rostedt	next if ($type eq "build");
7606c5ee0beSSteven Rostedt
7616c5ee0beSSteven Rostedt	get_grub_index;
7626c5ee0beSSteven Rostedt	get_version;
7636c5ee0beSSteven Rostedt	install;
7646c5ee0beSSteven Rostedt	monitor;
7656c5ee0beSSteven Rostedt
7666c5ee0beSSteven Rostedt	next if ($type eq "boot");
7676c5ee0beSSteven Rostedt	do_run_test;
7686c5ee0beSSteven Rostedt    }
7696c5ee0beSSteven Rostedt    $in_patchcheck = 0;
7706c5ee0beSSteven Rostedt    success $i;
7716c5ee0beSSteven Rostedt}
7726c5ee0beSSteven Rostedt
7732545eb61SSteven Rostedtread_config $ARGV[0];
7742545eb61SSteven Rostedt
7752545eb61SSteven Rostedt# mandatory configs
7762545eb61SSteven Rostedtdie "MACHINE not defined\n"		if (!defined($opt{"MACHINE"}));
7772545eb61SSteven Rostedtdie "SSH_USER not defined\n"		if (!defined($opt{"SSH_USER"}));
7782545eb61SSteven Rostedtdie "BUILD_DIR not defined\n"		if (!defined($opt{"BUILD_DIR"}));
7792545eb61SSteven Rostedtdie "OUTPUT_DIR not defined\n"		if (!defined($opt{"OUTPUT_DIR"}));
7802545eb61SSteven Rostedtdie "BUILD_TARGET not defined\n"	if (!defined($opt{"BUILD_TARGET"}));
78175c3fda7SSteven Rostedtdie "TARGET_IMAGE not defined\n"	if (!defined($opt{"TARGET_IMAGE"}));
7822545eb61SSteven Rostedtdie "POWER_CYCLE not defined\n"		if (!defined($opt{"POWER_CYCLE"}));
7832545eb61SSteven Rostedtdie "CONSOLE not defined\n"		if (!defined($opt{"CONSOLE"}));
7842545eb61SSteven Rostedtdie "LOCALVERSION not defined\n"	if (!defined($opt{"LOCALVERSION"}));
7852545eb61SSteven Rostedtdie "GRUB_MENU not defined\n"		if (!defined($opt{"GRUB_MENU"}));
7862545eb61SSteven Rostedt
7872545eb61SSteven Rostedtchdir $opt{"BUILD_DIR"} || die "can't change directory to $opt{BUILD_DIR}";
7882545eb61SSteven Rostedt
7892545eb61SSteven Rostedt$target = "$opt{SSH_USER}\@$opt{MACHINE}";
7902545eb61SSteven Rostedt
7912545eb61SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n";
7922545eb61SSteven Rostedt
7932545eb61SSteven Rostedt
7942545eb61SSteven Rostedt$make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}";
7952545eb61SSteven Rostedt
7965a391fbfSSteven Rostedtsub set_build_option {
7975a391fbfSSteven Rostedt    my ($name, $i) = @_;
7985a391fbfSSteven Rostedt
7995a391fbfSSteven Rostedt    my $option = "$name\[$i\]";
8005a391fbfSSteven Rostedt
8015a391fbfSSteven Rostedt    if (defined($opt{$option})) {
8025a391fbfSSteven Rostedt	return $opt{$option};
8035a391fbfSSteven Rostedt    }
8045a391fbfSSteven Rostedt
8055a391fbfSSteven Rostedt    if (defined($opt{$name})) {
8065a391fbfSSteven Rostedt	return $opt{$name};
8075a391fbfSSteven Rostedt    }
8085a391fbfSSteven Rostedt
8095a391fbfSSteven Rostedt    return undef;
8105a391fbfSSteven Rostedt}
8115a391fbfSSteven Rostedt
8122545eb61SSteven Rostedt# First we need to do is the builds
8132545eb61SSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) {
8142545eb61SSteven Rostedt    my $type = "BUILD_TYPE[$i]";
8152545eb61SSteven Rostedt
8161a5cfce3SSteven Rostedt    if (!defined($opt{$type})) {
8171a5cfce3SSteven Rostedt	$opt{$type} = $opt{"DEFAULT_BUILD_TYPE"};
8181a5cfce3SSteven Rostedt    }
8191a5cfce3SSteven Rostedt
8205a391fbfSSteven Rostedt    $noclean = set_build_option("BUILD_NOCLEAN", $i);
8215a391fbfSSteven Rostedt    $minconfig = set_build_option("MIN_CONFIG", $i);
8225a391fbfSSteven Rostedt    $run_test = set_build_option("TEST", $i);
8232545eb61SSteven Rostedt
8242545eb61SSteven Rostedt    doprint "\n\n";
8252545eb61SSteven Rostedt    doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $opt{$type}\n\n";
8262545eb61SSteven Rostedt
8276c5ee0beSSteven Rostedt    my $checkout = $opt{"CHECKOUT[$i]"};
8286c5ee0beSSteven Rostedt    if (defined($checkout)) {
8296c5ee0beSSteven Rostedt	run_command "git checkout $checkout" or
8306c5ee0beSSteven Rostedt	    die "failed to checkout $checkout";
8316c5ee0beSSteven Rostedt    }
8326c5ee0beSSteven Rostedt
8335f9b6cedSSteven Rostedt    if ($opt{$type} eq "bisect") {
8345f9b6cedSSteven Rostedt	bisect $i;
8355f9b6cedSSteven Rostedt	next;
8366c5ee0beSSteven Rostedt    } elsif ($opt{$type} eq "patchcheck") {
8376c5ee0beSSteven Rostedt	patchcheck $i;
8386c5ee0beSSteven Rostedt	next;
8395f9b6cedSSteven Rostedt    }
8405f9b6cedSSteven Rostedt
8412545eb61SSteven Rostedt    if ($opt{$type} ne "nobuild") {
8425c42fc5bSSteven Rostedt	build $opt{$type};
8432545eb61SSteven Rostedt    }
8442545eb61SSteven Rostedt
8455f9b6cedSSteven Rostedt    get_grub_index;
8465f9b6cedSSteven Rostedt    get_version;
8472545eb61SSteven Rostedt    install;
8482545eb61SSteven Rostedt    monitor;
8495a391fbfSSteven Rostedt
8505a391fbfSSteven Rostedt    if (defined($run_test)) {
8515a391fbfSSteven Rostedt	do_run_test;
8525a391fbfSSteven Rostedt    }
8535a391fbfSSteven Rostedt
8545f9b6cedSSteven Rostedt    success $i;
85575c3fda7SSteven Rostedt}
8562545eb61SSteven Rostedt
8575c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) {
85875c3fda7SSteven Rostedt    halt;
8591a5cfce3SSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"}) {
86075c3fda7SSteven Rostedt    reboot;
8615c42fc5bSSteven Rostedt}
86275c3fda7SSteven Rostedt
8632545eb61SSteven Rostedtexit 0;
864