xref: /openbmc/linux/tools/testing/ktest/ktest.pl (revision 6c5ee0be02f73ebd70eb50b84013e8830f08a6da)
12545eb61SSteven Rostedt#!/usr/bin/perl -w
22545eb61SSteven Rostedt
32545eb61SSteven Rostedtuse strict;
42545eb61SSteven Rostedtuse IPC::Open2;
52545eb61SSteven Rostedtuse Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
62545eb61SSteven Rostedtuse FileHandle;
72545eb61SSteven Rostedt
82545eb61SSteven Rostedt$#ARGV >= 0 || die "usage: autotest.pl config-file\n";
92545eb61SSteven Rostedt
102545eb61SSteven Rostedt$| = 1;
112545eb61SSteven Rostedt
122545eb61SSteven Rostedtmy %opt;
132545eb61SSteven Rostedt
142545eb61SSteven Rostedt#default opts
152545eb61SSteven Rostedt$opt{"NUM_BUILDS"}		= 5;
162545eb61SSteven Rostedt$opt{"DEFAULT_BUILD_TYPE"}	= "randconfig";
172545eb61SSteven Rostedt$opt{"MAKE_CMD"}		= "make";
182545eb61SSteven Rostedt$opt{"TIMEOUT"}			= 50;
192545eb61SSteven Rostedt$opt{"TMP_DIR"}			= "/tmp/autotest";
202545eb61SSteven Rostedt$opt{"SLEEP_TIME"}		= 60;	# sleep time between tests
215c42fc5bSSteven Rostedt$opt{"BUILD_NOCLEAN"}		= 0;
2275c3fda7SSteven Rostedt$opt{"REBOOT_ON_ERROR"}		= 0;
235c42fc5bSSteven Rostedt$opt{"POWEROFF_ON_ERROR"}	= 0;
241a5cfce3SSteven Rostedt$opt{"REBOOT_ON_SUCCESS"}	= 1;
255c42fc5bSSteven Rostedt$opt{"POWEROFF_ON_SUCCESS"}	= 0;
2675c3fda7SSteven Rostedt$opt{"BUILD_OPTIONS"}		= "";
275a391fbfSSteven Rostedt$opt{"BISECT_SLEEP_TIME"}	= 10;   # sleep time between bisects
282545eb61SSteven Rostedt
292545eb61SSteven Rostedtmy $version;
302545eb61SSteven Rostedtmy $grub_number;
312545eb61SSteven Rostedtmy $target;
322545eb61SSteven Rostedtmy $make;
335c42fc5bSSteven Rostedtmy $noclean;
345f9b6cedSSteven Rostedtmy $minconfig;
355f9b6cedSSteven Rostedtmy $in_bisect = 0;
365f9b6cedSSteven Rostedtmy $bisect_bad = "";
37*6c5ee0beSSteven Rostedtmy $in_patchcheck = 0;
385a391fbfSSteven Rostedtmy $run_test;
39*6c5ee0beSSteven Rostedtmy $redirect;
402545eb61SSteven Rostedt
412545eb61SSteven Rostedtsub read_config {
422545eb61SSteven Rostedt    my ($config) = @_;
432545eb61SSteven Rostedt
442545eb61SSteven Rostedt    open(IN, $config) || die "can't read file $config";
452545eb61SSteven Rostedt
462545eb61SSteven Rostedt    while (<IN>) {
472545eb61SSteven Rostedt
482545eb61SSteven Rostedt	# ignore blank lines and comments
492545eb61SSteven Rostedt	next if (/^\s*$/ || /\s*\#/);
502545eb61SSteven Rostedt
512545eb61SSteven Rostedt	if (/^\s*(\S+)\s*=\s*(.*?)\s*$/) {
522545eb61SSteven Rostedt	    my $lvalue = $1;
532545eb61SSteven Rostedt	    my $rvalue = $2;
542545eb61SSteven Rostedt
552545eb61SSteven Rostedt	    $opt{$lvalue} = $rvalue;
562545eb61SSteven Rostedt	}
572545eb61SSteven Rostedt    }
582545eb61SSteven Rostedt
592545eb61SSteven Rostedt    close(IN);
602545eb61SSteven Rostedt}
612545eb61SSteven Rostedt
625f9b6cedSSteven Rostedtsub logit {
632545eb61SSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
642545eb61SSteven Rostedt	open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
652545eb61SSteven Rostedt	print OUT @_;
662545eb61SSteven Rostedt	close(OUT);
672545eb61SSteven Rostedt    }
682545eb61SSteven Rostedt}
692545eb61SSteven Rostedt
705f9b6cedSSteven Rostedtsub doprint {
715f9b6cedSSteven Rostedt    print @_;
725f9b6cedSSteven Rostedt    logit @_;
735f9b6cedSSteven Rostedt}
745f9b6cedSSteven Rostedt
755c42fc5bSSteven Rostedtsub dodie {
765a391fbfSSteven Rostedt    doprint "CRITICAL FAILURE... ", @_, "\n";
775c42fc5bSSteven Rostedt
7875c3fda7SSteven Rostedt    if ($opt{"REBOOT_ON_ERROR"}) {
7975c3fda7SSteven Rostedt	doprint "REBOOTING\n";
8075c3fda7SSteven Rostedt	`$opt{"POWER_CYCLE"}`;
8175c3fda7SSteven Rostedt
8275c3fda7SSteven Rostedt    } elsif ($opt{"POWEROFF_ON_ERROR"} && defined($opt{"POWER_OFF"})) {
835c42fc5bSSteven Rostedt	doprint "POWERING OFF\n";
845c42fc5bSSteven Rostedt	`$opt{"POWER_OFF"}`;
855c42fc5bSSteven Rostedt    }
8675c3fda7SSteven Rostedt
875c42fc5bSSteven Rostedt    die @_;
885c42fc5bSSteven Rostedt}
895c42fc5bSSteven Rostedt
902545eb61SSteven Rostedtsub run_command {
912545eb61SSteven Rostedt    my ($command) = @_;
925a391fbfSSteven Rostedt    my $redirect_log = "";
93*6c5ee0beSSteven Rostedt    my $redirect_tee = "";
942545eb61SSteven Rostedt
952545eb61SSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
96*6c5ee0beSSteven Rostedt	$redirect_log = "| tee -a $opt{LOG_FILE}";
97*6c5ee0beSSteven Rostedt    }
98*6c5ee0beSSteven Rostedt
99*6c5ee0beSSteven Rostedt    if (defined($redirect)) {
100*6c5ee0beSSteven Rostedt	$redirect_tee = "| tee $redirect"
1012545eb61SSteven Rostedt    }
1022545eb61SSteven Rostedt
1032545eb61SSteven Rostedt    doprint "$command ... ";
104*6c5ee0beSSteven Rostedt    `$command 2>&1 $redirect_tee $redirect_log > /dev/null`;
1052545eb61SSteven Rostedt
1062545eb61SSteven Rostedt    my $failed = $?;
1072545eb61SSteven Rostedt
1082545eb61SSteven Rostedt    if ($failed) {
1092545eb61SSteven Rostedt	doprint "FAILED!\n";
1102545eb61SSteven Rostedt    } else {
1112545eb61SSteven Rostedt	doprint "SUCCESS\n";
1122545eb61SSteven Rostedt    }
1132545eb61SSteven Rostedt
1145f9b6cedSSteven Rostedt    return !$failed;
1155f9b6cedSSteven Rostedt}
1165f9b6cedSSteven Rostedt
1175f9b6cedSSteven Rostedtsub get_grub_index {
1185f9b6cedSSteven Rostedt
1195a391fbfSSteven Rostedt    return if (defined($grub_number));
1205f9b6cedSSteven Rostedt
1215f9b6cedSSteven Rostedt    doprint "Find grub menu ... ";
1225f9b6cedSSteven Rostedt    $grub_number = -1;
1235f9b6cedSSteven Rostedt    open(IN, "ssh $target cat /boot/grub/menu.lst |")
1245f9b6cedSSteven Rostedt	or die "unable to get menu.lst";
1255f9b6cedSSteven Rostedt    while (<IN>) {
1265f9b6cedSSteven Rostedt	if (/^\s*title\s+$opt{GRUB_MENU}\s*$/) {
1275f9b6cedSSteven Rostedt	    $grub_number++;
1285f9b6cedSSteven Rostedt	    last;
1295f9b6cedSSteven Rostedt	} elsif (/^\s*title\s/) {
1305f9b6cedSSteven Rostedt	    $grub_number++;
1315f9b6cedSSteven Rostedt	}
1325f9b6cedSSteven Rostedt    }
1335f9b6cedSSteven Rostedt    close(IN);
1345f9b6cedSSteven Rostedt
1355f9b6cedSSteven Rostedt    die "Could not find '$opt{GRUB_MENU}' in /boot/grub/menu on $opt{MACHINE}"
1365f9b6cedSSteven Rostedt	if ($grub_number < 0);
1375f9b6cedSSteven Rostedt    doprint "$grub_number\n";
1382545eb61SSteven Rostedt}
1392545eb61SSteven Rostedt
1402545eb61SSteven Rostedtmy $timeout = $opt{"TIMEOUT"};
1412545eb61SSteven Rostedt
1422545eb61SSteven Rostedtsub wait_for_input
1432545eb61SSteven Rostedt{
1442545eb61SSteven Rostedt    my ($fp, $time) = @_;
1452545eb61SSteven Rostedt    my $rin;
1462545eb61SSteven Rostedt    my $ready;
1472545eb61SSteven Rostedt    my $line;
1482545eb61SSteven Rostedt    my $ch;
1492545eb61SSteven Rostedt
1502545eb61SSteven Rostedt    if (!defined($time)) {
1512545eb61SSteven Rostedt	$time = $timeout;
1522545eb61SSteven Rostedt    }
1532545eb61SSteven Rostedt
1542545eb61SSteven Rostedt    $rin = '';
1552545eb61SSteven Rostedt    vec($rin, fileno($fp), 1) = 1;
1562545eb61SSteven Rostedt    $ready = select($rin, undef, undef, $time);
1572545eb61SSteven Rostedt
1582545eb61SSteven Rostedt    $line = "";
1592545eb61SSteven Rostedt
1602545eb61SSteven Rostedt    # try to read one char at a time
1612545eb61SSteven Rostedt    while (sysread $fp, $ch, 1) {
1622545eb61SSteven Rostedt	$line .= $ch;
1632545eb61SSteven Rostedt	last if ($ch eq "\n");
1642545eb61SSteven Rostedt    }
1652545eb61SSteven Rostedt
1662545eb61SSteven Rostedt    if (!length($line)) {
1672545eb61SSteven Rostedt	return undef;
1682545eb61SSteven Rostedt    }
1692545eb61SSteven Rostedt
1702545eb61SSteven Rostedt    return $line;
1712545eb61SSteven Rostedt}
1722545eb61SSteven Rostedt
17375c3fda7SSteven Rostedtsub reboot_to {
1742545eb61SSteven Rostedt    run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
1752545eb61SSteven Rostedt}
1762545eb61SSteven Rostedt
1775a391fbfSSteven Rostedtsub open_console {
1785a391fbfSSteven Rostedt    my ($fp) = @_;
1795a391fbfSSteven Rostedt
1802545eb61SSteven Rostedt    my $flags;
1815a391fbfSSteven Rostedt
1825a391fbfSSteven Rostedt    my $pid = open($fp, "$opt{CONSOLE}|") or
1835a391fbfSSteven Rostedt	dodie "Can't open console $opt{CONSOLE}";
1845a391fbfSSteven Rostedt
1855a391fbfSSteven Rostedt    $flags = fcntl($fp, F_GETFL, 0) or
1865a391fbfSSteven Rostedt	dodie "Can't get flags for the socket: $!\n";
1875a391fbfSSteven Rostedt    $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
1885a391fbfSSteven Rostedt	dodie "Can't set flags for the socket: $!\n";
1895a391fbfSSteven Rostedt
1905a391fbfSSteven Rostedt    return $pid;
1915a391fbfSSteven Rostedt}
1925a391fbfSSteven Rostedt
1935a391fbfSSteven Rostedtsub close_console {
1945a391fbfSSteven Rostedt    my ($fp, $pid) = @_;
1955a391fbfSSteven Rostedt
1965a391fbfSSteven Rostedt    doprint "kill child process $pid\n";
1975a391fbfSSteven Rostedt    kill 2, $pid;
1985a391fbfSSteven Rostedt
1995a391fbfSSteven Rostedt    print "closing!\n";
2005a391fbfSSteven Rostedt    close($fp);
2015a391fbfSSteven Rostedt}
2025a391fbfSSteven Rostedt
2035a391fbfSSteven Rostedtsub monitor {
2042545eb61SSteven Rostedt    my $booted = 0;
2052545eb61SSteven Rostedt    my $bug = 0;
2062545eb61SSteven Rostedt    my $pid;
2075c42fc5bSSteven Rostedt    my $skip_call_trace = 0;
2085a391fbfSSteven Rostedt    my $fp = \*IN;
2092545eb61SSteven Rostedt
2105a391fbfSSteven Rostedt    $pid = open_console($fp);
2112545eb61SSteven Rostedt
2122545eb61SSteven Rostedt    my $line;
2132545eb61SSteven Rostedt    my $full_line = "";
2142545eb61SSteven Rostedt
2152545eb61SSteven Rostedt    doprint "Wait for monitor to settle down.\n";
2162545eb61SSteven Rostedt    # read the monitor and wait for the system to calm down
2172545eb61SSteven Rostedt    do {
2185a391fbfSSteven Rostedt	$line = wait_for_input($fp, 5);
2192545eb61SSteven Rostedt    } while (defined($line));
2202545eb61SSteven Rostedt
22175c3fda7SSteven Rostedt    reboot_to;
2222545eb61SSteven Rostedt
2232545eb61SSteven Rostedt    for (;;) {
2242545eb61SSteven Rostedt
2255a391fbfSSteven Rostedt	$line = wait_for_input($fp);
2262545eb61SSteven Rostedt
2272545eb61SSteven Rostedt	last if (!defined($line));
2282545eb61SSteven Rostedt
2292545eb61SSteven Rostedt	doprint $line;
2302545eb61SSteven Rostedt
2312545eb61SSteven Rostedt	# we are not guaranteed to get a full line
2322545eb61SSteven Rostedt	$full_line .= $line;
2332545eb61SSteven Rostedt
2342545eb61SSteven Rostedt	if ($full_line =~ /login:/) {
2352545eb61SSteven Rostedt	    $booted = 1;
2362545eb61SSteven Rostedt	}
2372545eb61SSteven Rostedt
2385c42fc5bSSteven Rostedt	if ($full_line =~ /\[ backtrace testing \]/) {
2395c42fc5bSSteven Rostedt	    $skip_call_trace = 1;
2405c42fc5bSSteven Rostedt	}
2415c42fc5bSSteven Rostedt
2422545eb61SSteven Rostedt	if ($full_line =~ /call trace:/i) {
2435c42fc5bSSteven Rostedt	    $bug = 1 if (!$skip_call_trace);
2445c42fc5bSSteven Rostedt	}
2455c42fc5bSSteven Rostedt
2465c42fc5bSSteven Rostedt	if ($full_line =~ /\[ end of backtrace testing \]/) {
2475c42fc5bSSteven Rostedt	    $skip_call_trace = 0;
2485c42fc5bSSteven Rostedt	}
2495c42fc5bSSteven Rostedt
2505c42fc5bSSteven Rostedt	if ($full_line =~ /Kernel panic -/) {
2512545eb61SSteven Rostedt	    $bug = 1;
2522545eb61SSteven Rostedt	}
2532545eb61SSteven Rostedt
2542545eb61SSteven Rostedt	if ($line =~ /\n/) {
2552545eb61SSteven Rostedt	    $full_line = "";
2562545eb61SSteven Rostedt	}
2572545eb61SSteven Rostedt    }
2582545eb61SSteven Rostedt
2595a391fbfSSteven Rostedt    close_console($fp, $pid);
2602545eb61SSteven Rostedt
2612545eb61SSteven Rostedt    if (!$booted) {
2625a391fbfSSteven Rostedt	return 1 if ($in_bisect);
2635c42fc5bSSteven Rostedt	dodie "failed - never got a boot prompt.\n";
2642545eb61SSteven Rostedt    }
2652545eb61SSteven Rostedt
2662545eb61SSteven Rostedt    if ($bug) {
2675a391fbfSSteven Rostedt	return 1 if ($in_bisect);
2685c42fc5bSSteven Rostedt	dodie "failed - got a bug report\n";
2692545eb61SSteven Rostedt    }
2705f9b6cedSSteven Rostedt
2715f9b6cedSSteven Rostedt    return 0;
2722545eb61SSteven Rostedt}
2732545eb61SSteven Rostedt
2742545eb61SSteven Rostedtsub install {
2752545eb61SSteven Rostedt
2765f9b6cedSSteven Rostedt    run_command "scp $opt{OUTPUT_DIR}/$opt{BUILD_TARGET} $target:$opt{TARGET_IMAGE}" or
2775c42fc5bSSteven Rostedt	dodie "failed to copy image";
2785f9b6cedSSteven Rostedt
2795f9b6cedSSteven Rostedt    my $install_mods = 0;
2805f9b6cedSSteven Rostedt
2815f9b6cedSSteven Rostedt    # should we process modules?
2825f9b6cedSSteven Rostedt    $install_mods = 0;
2835f9b6cedSSteven Rostedt    open(IN, "$opt{OUTPUT_DIR}/.config") or dodie("Can't read config file");
2845f9b6cedSSteven Rostedt    while (<IN>) {
2855f9b6cedSSteven Rostedt	if (/CONFIG_MODULES(=y)?/) {
2865f9b6cedSSteven Rostedt	    $install_mods = 1 if (defined($1));
2875f9b6cedSSteven Rostedt	    last;
2885f9b6cedSSteven Rostedt	}
2895f9b6cedSSteven Rostedt    }
2905f9b6cedSSteven Rostedt    close(IN);
2915f9b6cedSSteven Rostedt
2925f9b6cedSSteven Rostedt    if (!$install_mods) {
2935f9b6cedSSteven Rostedt	doprint "No modules needed\n";
2945f9b6cedSSteven Rostedt	return;
2952545eb61SSteven Rostedt    }
2962545eb61SSteven Rostedt
2975f9b6cedSSteven Rostedt    run_command "$make INSTALL_MOD_PATH=$opt{TMP_DIR} modules_install" or
2985f9b6cedSSteven Rostedt	dodie "Failed to install modules";
2995f9b6cedSSteven Rostedt
3002545eb61SSteven Rostedt    my $modlib = "/lib/modules/$version";
3015c42fc5bSSteven Rostedt    my $modtar = "autotest-mods.tar.bz2";
3022545eb61SSteven Rostedt
3035f9b6cedSSteven Rostedt    run_command "ssh $target rm -rf $modlib" or
3045c42fc5bSSteven Rostedt	dodie "failed to remove old mods: $modlib";
3052545eb61SSteven Rostedt
3065c42fc5bSSteven Rostedt    # would be nice if scp -r did not follow symbolic links
3075f9b6cedSSteven Rostedt    run_command "cd $opt{TMP_DIR} && tar -cjf $modtar lib/modules/$version" or
3085c42fc5bSSteven Rostedt	dodie "making tarball";
3095c42fc5bSSteven Rostedt
3105f9b6cedSSteven Rostedt    run_command "scp $opt{TMP_DIR}/$modtar $target:/tmp" or
3115c42fc5bSSteven Rostedt	dodie "failed to copy modules";
3125c42fc5bSSteven Rostedt
3135c42fc5bSSteven Rostedt    unlink "$opt{TMP_DIR}/$modtar";
3145c42fc5bSSteven Rostedt
3155f9b6cedSSteven Rostedt    run_command "ssh $target '(cd / && tar xf /tmp/$modtar)'" or
3165c42fc5bSSteven Rostedt	dodie "failed to tar modules";
3175c42fc5bSSteven Rostedt
3185c42fc5bSSteven Rostedt    run_command "ssh $target rm -f /tmp/$modtar";
3192545eb61SSteven Rostedt}
3202545eb61SSteven Rostedt
321*6c5ee0beSSteven Rostedtsub check_buildlog {
322*6c5ee0beSSteven Rostedt    my ($patch) = @_;
323*6c5ee0beSSteven Rostedt
324*6c5ee0beSSteven Rostedt    my $buildlog = "$opt{TMP_DIR}/buildlog";
325*6c5ee0beSSteven Rostedt    my @files = `git show $patch | diffstat -l`;
326*6c5ee0beSSteven Rostedt
327*6c5ee0beSSteven Rostedt    open(IN, "git show $patch |") or
328*6c5ee0beSSteven Rostedt	dodie "failed to show $patch";
329*6c5ee0beSSteven Rostedt    while (<IN>) {
330*6c5ee0beSSteven Rostedt	if (m,^--- a/(.*),) {
331*6c5ee0beSSteven Rostedt	    chomp $1;
332*6c5ee0beSSteven Rostedt	    $files[$#files] = $1;
333*6c5ee0beSSteven Rostedt	}
334*6c5ee0beSSteven Rostedt    }
335*6c5ee0beSSteven Rostedt    close(IN);
336*6c5ee0beSSteven Rostedt
337*6c5ee0beSSteven Rostedt    open(IN, $buildlog) or dodie "Can't open $buildlog";
338*6c5ee0beSSteven Rostedt    while (<IN>) {
339*6c5ee0beSSteven Rostedt	if (/^\s*(.*?):.*(warning|error)/) {
340*6c5ee0beSSteven Rostedt	    my $err = $1;
341*6c5ee0beSSteven Rostedt	    foreach my $file (@files) {
342*6c5ee0beSSteven Rostedt		my $fullpath = "$opt{BUILD_DIR}/$file";
343*6c5ee0beSSteven Rostedt		if ($file eq $err || $fullpath eq $err) {
344*6c5ee0beSSteven Rostedt		    dodie "$file built with warnings";
345*6c5ee0beSSteven Rostedt		}
346*6c5ee0beSSteven Rostedt	    }
347*6c5ee0beSSteven Rostedt	}
348*6c5ee0beSSteven Rostedt    }
349*6c5ee0beSSteven Rostedt    close(IN);
350*6c5ee0beSSteven Rostedt}
351*6c5ee0beSSteven Rostedt
3522545eb61SSteven Rostedtsub build {
3532545eb61SSteven Rostedt    my ($type) = @_;
3545c42fc5bSSteven Rostedt    my $defconfig = "";
3555c42fc5bSSteven Rostedt    my $append = "";
3562545eb61SSteven Rostedt
35775c3fda7SSteven Rostedt    if ($type =~ /^useconfig:(.*)/) {
3585f9b6cedSSteven Rostedt	run_command "cp $1 $opt{OUTPUT_DIR}/.config" or
35975c3fda7SSteven Rostedt	    dodie "could not copy $1 to .config";
3605f9b6cedSSteven Rostedt
36175c3fda7SSteven Rostedt	$type = "oldconfig";
36275c3fda7SSteven Rostedt    }
36375c3fda7SSteven Rostedt
3645c42fc5bSSteven Rostedt    # old config can ask questions
3655c42fc5bSSteven Rostedt    if ($type eq "oldconfig") {
3665c42fc5bSSteven Rostedt	$append = "yes ''|";
36775c3fda7SSteven Rostedt
36875c3fda7SSteven Rostedt	# allow for empty configs
36975c3fda7SSteven Rostedt	run_command "touch $opt{OUTPUT_DIR}/.config";
37075c3fda7SSteven Rostedt
3715f9b6cedSSteven Rostedt	run_command "mv $opt{OUTPUT_DIR}/.config $opt{OUTPUT_DIR}/config_temp" or
3725c42fc5bSSteven Rostedt	    dodie "moving .config";
3735c42fc5bSSteven Rostedt
3745f9b6cedSSteven Rostedt	if (!$noclean && !run_command "$make mrproper") {
3755c42fc5bSSteven Rostedt	    dodie "make mrproper";
3765c42fc5bSSteven Rostedt	}
3775c42fc5bSSteven Rostedt
3785f9b6cedSSteven Rostedt	run_command "mv $opt{OUTPUT_DIR}/config_temp $opt{OUTPUT_DIR}/.config" or
3795c42fc5bSSteven Rostedt	    dodie "moving config_temp";
3805c42fc5bSSteven Rostedt
3815c42fc5bSSteven Rostedt    } elsif (!$noclean) {
3822545eb61SSteven Rostedt	unlink "$opt{OUTPUT_DIR}/.config";
3835f9b6cedSSteven Rostedt	run_command "$make mrproper" or
3845c42fc5bSSteven Rostedt	    dodie "make mrproper";
3855c42fc5bSSteven Rostedt    }
3862545eb61SSteven Rostedt
3872545eb61SSteven Rostedt    # add something to distinguish this build
3885c42fc5bSSteven Rostedt    open(OUT, "> $opt{OUTPUT_DIR}/localversion") or dodie("Can't make localversion file");
3892545eb61SSteven Rostedt    print OUT "$opt{LOCALVERSION}\n";
3902545eb61SSteven Rostedt    close(OUT);
3912545eb61SSteven Rostedt
3925f9b6cedSSteven Rostedt    if (defined($minconfig)) {
3935f9b6cedSSteven Rostedt	$defconfig = "KCONFIG_ALLCONFIG=$minconfig";
3942545eb61SSteven Rostedt    }
3952545eb61SSteven Rostedt
3965f9b6cedSSteven Rostedt    run_command "$defconfig $append $make $type" or
3975c42fc5bSSteven Rostedt	dodie "failed make config";
3982545eb61SSteven Rostedt
399*6c5ee0beSSteven Rostedt    # patch check will examine the log
400*6c5ee0beSSteven Rostedt    if ($in_patchcheck) {
401*6c5ee0beSSteven Rostedt	$redirect = "$opt{TMP_DIR}/buildlog";
402*6c5ee0beSSteven Rostedt    }
403*6c5ee0beSSteven Rostedt
4045f9b6cedSSteven Rostedt    if (!run_command "$make $opt{BUILD_OPTIONS}") {
405*6c5ee0beSSteven Rostedt	undef $redirect;
4065f9b6cedSSteven Rostedt	# bisect may need this to pass
4075f9b6cedSSteven Rostedt	return 1 if ($in_bisect);
4085c42fc5bSSteven Rostedt	dodie "failed build";
4092545eb61SSteven Rostedt    }
410*6c5ee0beSSteven Rostedt    undef $redirect;
4115f9b6cedSSteven Rostedt
4125f9b6cedSSteven Rostedt    return 0;
4132545eb61SSteven Rostedt}
4142545eb61SSteven Rostedt
41575c3fda7SSteven Rostedtsub reboot {
41675c3fda7SSteven Rostedt    # try to reboot normally
4175f9b6cedSSteven Rostedt    if (!run_command "ssh $target reboot") {
41875c3fda7SSteven Rostedt	# nope? power cycle it.
41975c3fda7SSteven Rostedt	run_command "$opt{POWER_CYCLE}";
42075c3fda7SSteven Rostedt    }
42175c3fda7SSteven Rostedt}
42275c3fda7SSteven Rostedt
42375c3fda7SSteven Rostedtsub halt {
4245f9b6cedSSteven Rostedt    if (!run_command "ssh $target halt" or defined($opt{"POWER_OFF"})) {
42575c3fda7SSteven Rostedt	# nope? the zap it!
42675c3fda7SSteven Rostedt	run_command "$opt{POWER_OFF}";
42775c3fda7SSteven Rostedt    }
42875c3fda7SSteven Rostedt}
42975c3fda7SSteven Rostedt
4305f9b6cedSSteven Rostedtsub success {
4315f9b6cedSSteven Rostedt    my ($i) = @_;
4325f9b6cedSSteven Rostedt
4335f9b6cedSSteven Rostedt    doprint "\n\n*******************************************\n";
4345f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
4355f9b6cedSSteven Rostedt    doprint     "**            SUCCESS!!!!                **\n";
4365f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
4375f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
4385f9b6cedSSteven Rostedt
4395f9b6cedSSteven Rostedt    if ($i != $opt{"NUM_BUILDS"}) {
4405f9b6cedSSteven Rostedt	reboot;
4415f9b6cedSSteven Rostedt	doprint "Sleeping $opt{SLEEP_TIME} seconds\n";
4425f9b6cedSSteven Rostedt	sleep "$opt{SLEEP_TIME}";
4435f9b6cedSSteven Rostedt    }
4445f9b6cedSSteven Rostedt}
4455f9b6cedSSteven Rostedt
4465f9b6cedSSteven Rostedtsub get_version {
4475f9b6cedSSteven Rostedt    # get the release name
4485f9b6cedSSteven Rostedt    doprint "$make kernelrelease ... ";
4495f9b6cedSSteven Rostedt    $version = `$make kernelrelease | tail -1`;
4505f9b6cedSSteven Rostedt    chomp($version);
4515f9b6cedSSteven Rostedt    doprint "$version\n";
4525f9b6cedSSteven Rostedt}
4535f9b6cedSSteven Rostedt
4545a391fbfSSteven Rostedtsub child_run_test {
4555a391fbfSSteven Rostedt    my $failed;
4565a391fbfSSteven Rostedt
4575a391fbfSSteven Rostedt    $failed = !run_command $run_test;
4585a391fbfSSteven Rostedt    exit $failed;
4595a391fbfSSteven Rostedt}
4605a391fbfSSteven Rostedt
4615a391fbfSSteven Rostedtmy $child_done;
4625a391fbfSSteven Rostedt
4635a391fbfSSteven Rostedtsub child_finished {
4645a391fbfSSteven Rostedt    $child_done = 1;
4655a391fbfSSteven Rostedt}
4665a391fbfSSteven Rostedt
4675a391fbfSSteven Rostedtsub do_run_test {
4685a391fbfSSteven Rostedt    my $child_pid;
4695a391fbfSSteven Rostedt    my $child_exit;
4705a391fbfSSteven Rostedt    my $pid;
4715a391fbfSSteven Rostedt    my $line;
4725a391fbfSSteven Rostedt    my $full_line;
4735a391fbfSSteven Rostedt    my $bug = 0;
4745a391fbfSSteven Rostedt    my $fp = \*IN;
4755a391fbfSSteven Rostedt
4765a391fbfSSteven Rostedt    $pid = open_console($fp);
4775a391fbfSSteven Rostedt
4785a391fbfSSteven Rostedt    # read the monitor and wait for the system to calm down
4795a391fbfSSteven Rostedt    do {
4805a391fbfSSteven Rostedt	$line = wait_for_input($fp, 1);
4815a391fbfSSteven Rostedt    } while (defined($line));
4825a391fbfSSteven Rostedt
4835a391fbfSSteven Rostedt    $child_done = 0;
4845a391fbfSSteven Rostedt
4855a391fbfSSteven Rostedt    $SIG{CHLD} = qw(child_finished);
4865a391fbfSSteven Rostedt
4875a391fbfSSteven Rostedt    $child_pid = fork;
4885a391fbfSSteven Rostedt
4895a391fbfSSteven Rostedt    child_run_test if (!$child_pid);
4905a391fbfSSteven Rostedt
4915a391fbfSSteven Rostedt    $full_line = "";
4925a391fbfSSteven Rostedt
4935a391fbfSSteven Rostedt    do {
4945a391fbfSSteven Rostedt	$line = wait_for_input($fp, 1);
4955a391fbfSSteven Rostedt	if (defined($line)) {
4965a391fbfSSteven Rostedt
4975a391fbfSSteven Rostedt	    # we are not guaranteed to get a full line
4985a391fbfSSteven Rostedt	    $full_line .= $line;
4995a391fbfSSteven Rostedt
5005a391fbfSSteven Rostedt	    if ($full_line =~ /call trace:/i) {
5015a391fbfSSteven Rostedt		$bug = 1;
5025a391fbfSSteven Rostedt	    }
5035a391fbfSSteven Rostedt
5045a391fbfSSteven Rostedt	    if ($full_line =~ /Kernel panic -/) {
5055a391fbfSSteven Rostedt		$bug = 1;
5065a391fbfSSteven Rostedt	    }
5075a391fbfSSteven Rostedt
5085a391fbfSSteven Rostedt	    if ($line =~ /\n/) {
5095a391fbfSSteven Rostedt		$full_line = "";
5105a391fbfSSteven Rostedt	    }
5115a391fbfSSteven Rostedt	}
5125a391fbfSSteven Rostedt    } while (!$child_done && !$bug);
5135a391fbfSSteven Rostedt
5145a391fbfSSteven Rostedt    if ($bug) {
5155a391fbfSSteven Rostedt	doprint "Detected kernel crash!\n";
5165a391fbfSSteven Rostedt	# kill the child with extreme prejudice
5175a391fbfSSteven Rostedt	kill 9, $child_pid;
5185a391fbfSSteven Rostedt    }
5195a391fbfSSteven Rostedt
5205a391fbfSSteven Rostedt    waitpid $child_pid, 0;
5215a391fbfSSteven Rostedt    $child_exit = $?;
5225a391fbfSSteven Rostedt
5235a391fbfSSteven Rostedt    close_console($fp, $pid);
5245a391fbfSSteven Rostedt
5255a391fbfSSteven Rostedt    if ($bug || $child_exit) {
5265a391fbfSSteven Rostedt	return 1 if $in_bisect;
5275a391fbfSSteven Rostedt	dodie "test failed";
5285a391fbfSSteven Rostedt    }
5295a391fbfSSteven Rostedt    return 0;
5305a391fbfSSteven Rostedt}
5315a391fbfSSteven Rostedt
5325f9b6cedSSteven Rostedtsub run_bisect {
5335f9b6cedSSteven Rostedt    my ($type) = @_;
5345f9b6cedSSteven Rostedt
5355f9b6cedSSteven Rostedt    my $failed;
5365f9b6cedSSteven Rostedt    my $result;
5375f9b6cedSSteven Rostedt    my $output;
5385f9b6cedSSteven Rostedt    my $ret;
5395f9b6cedSSteven Rostedt
5405f9b6cedSSteven Rostedt
5415f9b6cedSSteven Rostedt    if (defined($minconfig)) {
5425f9b6cedSSteven Rostedt	$failed = build "useconfig:$minconfig";
5435f9b6cedSSteven Rostedt    } else {
5445f9b6cedSSteven Rostedt	# ?? no config to use?
5455f9b6cedSSteven Rostedt	$failed = build "oldconfig";
5465f9b6cedSSteven Rostedt    }
5475f9b6cedSSteven Rostedt
5485f9b6cedSSteven Rostedt    if ($type ne "build") {
5495f9b6cedSSteven Rostedt	dodie "Failed on build" if $failed;
5505f9b6cedSSteven Rostedt
5515f9b6cedSSteven Rostedt	# Now boot the box
5525f9b6cedSSteven Rostedt	get_grub_index;
5535f9b6cedSSteven Rostedt	get_version;
5545f9b6cedSSteven Rostedt	install;
5555f9b6cedSSteven Rostedt	$failed = monitor;
5565f9b6cedSSteven Rostedt
5575f9b6cedSSteven Rostedt	if ($type ne "boot") {
5585f9b6cedSSteven Rostedt	    dodie "Failed on boot" if $failed;
5595a391fbfSSteven Rostedt
5605a391fbfSSteven Rostedt	    $failed = do_run_test;
5615f9b6cedSSteven Rostedt	}
5625f9b6cedSSteven Rostedt    }
5635f9b6cedSSteven Rostedt
5645f9b6cedSSteven Rostedt    if ($failed) {
5655f9b6cedSSteven Rostedt	$result = "bad";
5665a391fbfSSteven Rostedt
5675a391fbfSSteven Rostedt	# reboot the box to a good kernel
5685a391fbfSSteven Rostedt	if ($type eq "boot") {
5695a391fbfSSteven Rostedt	    reboot;
5705a391fbfSSteven Rostedt	    doprint "sleep a little for reboot\n";
5715a391fbfSSteven Rostedt	    sleep $opt{"BISECT_SLEEP_TIME"};
5725a391fbfSSteven Rostedt	}
5735f9b6cedSSteven Rostedt    } else {
5745f9b6cedSSteven Rostedt	$result = "good";
5755f9b6cedSSteven Rostedt    }
5765f9b6cedSSteven Rostedt
5775f9b6cedSSteven Rostedt    doprint "git bisect $result ... ";
5785f9b6cedSSteven Rostedt    $output = `git bisect $result 2>&1`;
5795f9b6cedSSteven Rostedt    $ret = $?;
5805f9b6cedSSteven Rostedt
5815f9b6cedSSteven Rostedt    logit $output;
5825f9b6cedSSteven Rostedt
5835f9b6cedSSteven Rostedt    if ($ret) {
5845f9b6cedSSteven Rostedt	doprint "FAILED\n";
5855f9b6cedSSteven Rostedt	dodie "Failed to git bisect";
5865f9b6cedSSteven Rostedt    }
5875f9b6cedSSteven Rostedt
5885f9b6cedSSteven Rostedt    doprint "SUCCESS\n";
5895a391fbfSSteven Rostedt    if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) {
5905f9b6cedSSteven Rostedt	doprint "$1 [$2]\n";
5915f9b6cedSSteven Rostedt    } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
5925f9b6cedSSteven Rostedt	$bisect_bad = $1;
5935f9b6cedSSteven Rostedt	doprint "Found bad commit... $1\n";
5945f9b6cedSSteven Rostedt	return 0;
5955a391fbfSSteven Rostedt    } else {
5965a391fbfSSteven Rostedt	# we already logged it, just print it now.
5975a391fbfSSteven Rostedt	print $output;
5985f9b6cedSSteven Rostedt    }
5995f9b6cedSSteven Rostedt
6005f9b6cedSSteven Rostedt
6015f9b6cedSSteven Rostedt    return 1;
6025f9b6cedSSteven Rostedt}
6035f9b6cedSSteven Rostedt
6045f9b6cedSSteven Rostedtsub bisect {
6055f9b6cedSSteven Rostedt    my ($i) = @_;
6065f9b6cedSSteven Rostedt
6075f9b6cedSSteven Rostedt    my $result;
6085f9b6cedSSteven Rostedt
6095f9b6cedSSteven Rostedt    die "BISECT_GOOD[$i] not defined\n"	if (!defined($opt{"BISECT_GOOD[$i]"}));
6105f9b6cedSSteven Rostedt    die "BISECT_BAD[$i] not defined\n"	if (!defined($opt{"BISECT_BAD[$i]"}));
6115f9b6cedSSteven Rostedt    die "BISECT_TYPE[$i] not defined\n"	if (!defined($opt{"BISECT_TYPE[$i]"}));
6125f9b6cedSSteven Rostedt
6135f9b6cedSSteven Rostedt    my $good = $opt{"BISECT_GOOD[$i]"};
6145f9b6cedSSteven Rostedt    my $bad = $opt{"BISECT_BAD[$i]"};
6155f9b6cedSSteven Rostedt    my $type = $opt{"BISECT_TYPE[$i]"};
6165f9b6cedSSteven Rostedt
6175f9b6cedSSteven Rostedt    $in_bisect = 1;
6185f9b6cedSSteven Rostedt
6195f9b6cedSSteven Rostedt    run_command "git bisect start" or
6205f9b6cedSSteven Rostedt	dodie "could not start bisect";
6215f9b6cedSSteven Rostedt
6225f9b6cedSSteven Rostedt    run_command "git bisect good $good" or
6235f9b6cedSSteven Rostedt	dodie "could not set bisect good to $good";
6245f9b6cedSSteven Rostedt
6255f9b6cedSSteven Rostedt    run_command "git bisect bad $bad" or
6265f9b6cedSSteven Rostedt	dodie "could not set bisect good to $bad";
6275f9b6cedSSteven Rostedt
6285a391fbfSSteven Rostedt    # Can't have a test without having a test to run
6295a391fbfSSteven Rostedt    if ($type eq "test" && !defined($run_test)) {
6305a391fbfSSteven Rostedt	$type = "boot";
6315a391fbfSSteven Rostedt    }
6325a391fbfSSteven Rostedt
6335f9b6cedSSteven Rostedt    do {
6345f9b6cedSSteven Rostedt	$result = run_bisect $type;
6355f9b6cedSSteven Rostedt    } while ($result);
6365f9b6cedSSteven Rostedt
6375f9b6cedSSteven Rostedt    run_command "git bisect log" or
6385f9b6cedSSteven Rostedt	dodie "could not capture git bisect log";
6395f9b6cedSSteven Rostedt
6405f9b6cedSSteven Rostedt    run_command "git bisect reset" or
6415f9b6cedSSteven Rostedt	dodie "could not reset git bisect";
6425f9b6cedSSteven Rostedt
6435f9b6cedSSteven Rostedt    doprint "Bad commit was [$bisect_bad]\n";
6445f9b6cedSSteven Rostedt
6455f9b6cedSSteven Rostedt    $in_bisect = 0;
6465f9b6cedSSteven Rostedt
6475f9b6cedSSteven Rostedt    success $i;
6485f9b6cedSSteven Rostedt}
6495f9b6cedSSteven Rostedt
650*6c5ee0beSSteven Rostedtsub patchcheck {
651*6c5ee0beSSteven Rostedt    my ($i) = @_;
652*6c5ee0beSSteven Rostedt
653*6c5ee0beSSteven Rostedt    die "PATCHCHECK_START[$i] not defined\n"
654*6c5ee0beSSteven Rostedt	if (!defined($opt{"PATCHCHECK_START[$i]"}));
655*6c5ee0beSSteven Rostedt    die "PATCHCHECK_TYPE[$i] not defined\n"
656*6c5ee0beSSteven Rostedt	if (!defined($opt{"PATCHCHECK_TYPE[$i]"}));
657*6c5ee0beSSteven Rostedt
658*6c5ee0beSSteven Rostedt    my $start = $opt{"PATCHCHECK_START[$i]"};
659*6c5ee0beSSteven Rostedt
660*6c5ee0beSSteven Rostedt    my $end = "HEAD";
661*6c5ee0beSSteven Rostedt    if (defined($opt{"PATCHCHECK_END[$i]"})) {
662*6c5ee0beSSteven Rostedt	$end = $opt{"PATCHCHECK_END[$i]"};
663*6c5ee0beSSteven Rostedt    }
664*6c5ee0beSSteven Rostedt
665*6c5ee0beSSteven Rostedt    my $type = $opt{"PATCHCHECK_TYPE[$i]"};
666*6c5ee0beSSteven Rostedt
667*6c5ee0beSSteven Rostedt    # Can't have a test without having a test to run
668*6c5ee0beSSteven Rostedt    if ($type eq "test" && !defined($run_test)) {
669*6c5ee0beSSteven Rostedt	$type = "boot";
670*6c5ee0beSSteven Rostedt    }
671*6c5ee0beSSteven Rostedt
672*6c5ee0beSSteven Rostedt    open (IN, "git log --pretty=oneline $end|") or
673*6c5ee0beSSteven Rostedt	dodie "could not get git list";
674*6c5ee0beSSteven Rostedt
675*6c5ee0beSSteven Rostedt    my @list;
676*6c5ee0beSSteven Rostedt
677*6c5ee0beSSteven Rostedt    while (<IN>) {
678*6c5ee0beSSteven Rostedt	chomp;
679*6c5ee0beSSteven Rostedt	$list[$#list+1] = $_;
680*6c5ee0beSSteven Rostedt	last if (/^$start/);
681*6c5ee0beSSteven Rostedt    }
682*6c5ee0beSSteven Rostedt    close(IN);
683*6c5ee0beSSteven Rostedt
684*6c5ee0beSSteven Rostedt    if ($list[$#list] !~ /^$start/) {
685*6c5ee0beSSteven Rostedt	dodie "SHA1 $start not found";
686*6c5ee0beSSteven Rostedt    }
687*6c5ee0beSSteven Rostedt
688*6c5ee0beSSteven Rostedt    # go backwards in the list
689*6c5ee0beSSteven Rostedt    @list = reverse @list;
690*6c5ee0beSSteven Rostedt
691*6c5ee0beSSteven Rostedt    my $save_clean = $noclean;
692*6c5ee0beSSteven Rostedt
693*6c5ee0beSSteven Rostedt    $in_patchcheck = 1;
694*6c5ee0beSSteven Rostedt    foreach my $item (@list) {
695*6c5ee0beSSteven Rostedt	my $sha1 = $item;
696*6c5ee0beSSteven Rostedt	$sha1 =~ s/^([[:xdigit:]]+).*/$1/;
697*6c5ee0beSSteven Rostedt
698*6c5ee0beSSteven Rostedt	doprint "\nProcessing commit $item\n\n";
699*6c5ee0beSSteven Rostedt
700*6c5ee0beSSteven Rostedt	run_command "git checkout $sha1" or
701*6c5ee0beSSteven Rostedt	    die "Failed to checkout $sha1";
702*6c5ee0beSSteven Rostedt
703*6c5ee0beSSteven Rostedt	# only clean on the first and last patch
704*6c5ee0beSSteven Rostedt	if ($item eq $list[0] ||
705*6c5ee0beSSteven Rostedt	    $item eq $list[$#list]) {
706*6c5ee0beSSteven Rostedt	    $noclean = $save_clean;
707*6c5ee0beSSteven Rostedt	} else {
708*6c5ee0beSSteven Rostedt	    $noclean = 1;
709*6c5ee0beSSteven Rostedt	}
710*6c5ee0beSSteven Rostedt
711*6c5ee0beSSteven Rostedt	if (defined($minconfig)) {
712*6c5ee0beSSteven Rostedt	    build "useconfig:$minconfig";
713*6c5ee0beSSteven Rostedt	} else {
714*6c5ee0beSSteven Rostedt	    # ?? no config to use?
715*6c5ee0beSSteven Rostedt	    build "oldconfig";
716*6c5ee0beSSteven Rostedt	}
717*6c5ee0beSSteven Rostedt
718*6c5ee0beSSteven Rostedt	check_buildlog $sha1;
719*6c5ee0beSSteven Rostedt
720*6c5ee0beSSteven Rostedt	next if ($type eq "build");
721*6c5ee0beSSteven Rostedt
722*6c5ee0beSSteven Rostedt	get_grub_index;
723*6c5ee0beSSteven Rostedt	get_version;
724*6c5ee0beSSteven Rostedt	install;
725*6c5ee0beSSteven Rostedt	monitor;
726*6c5ee0beSSteven Rostedt
727*6c5ee0beSSteven Rostedt	next if ($type eq "boot");
728*6c5ee0beSSteven Rostedt	do_run_test;
729*6c5ee0beSSteven Rostedt    }
730*6c5ee0beSSteven Rostedt    $in_patchcheck = 0;
731*6c5ee0beSSteven Rostedt    success $i;
732*6c5ee0beSSteven Rostedt}
733*6c5ee0beSSteven Rostedt
7342545eb61SSteven Rostedtread_config $ARGV[0];
7352545eb61SSteven Rostedt
7362545eb61SSteven Rostedt# mandatory configs
7372545eb61SSteven Rostedtdie "MACHINE not defined\n"		if (!defined($opt{"MACHINE"}));
7382545eb61SSteven Rostedtdie "SSH_USER not defined\n"		if (!defined($opt{"SSH_USER"}));
7392545eb61SSteven Rostedtdie "BUILD_DIR not defined\n"		if (!defined($opt{"BUILD_DIR"}));
7402545eb61SSteven Rostedtdie "OUTPUT_DIR not defined\n"		if (!defined($opt{"OUTPUT_DIR"}));
7412545eb61SSteven Rostedtdie "BUILD_TARGET not defined\n"	if (!defined($opt{"BUILD_TARGET"}));
74275c3fda7SSteven Rostedtdie "TARGET_IMAGE not defined\n"	if (!defined($opt{"TARGET_IMAGE"}));
7432545eb61SSteven Rostedtdie "POWER_CYCLE not defined\n"		if (!defined($opt{"POWER_CYCLE"}));
7442545eb61SSteven Rostedtdie "CONSOLE not defined\n"		if (!defined($opt{"CONSOLE"}));
7452545eb61SSteven Rostedtdie "LOCALVERSION not defined\n"	if (!defined($opt{"LOCALVERSION"}));
7462545eb61SSteven Rostedtdie "GRUB_MENU not defined\n"		if (!defined($opt{"GRUB_MENU"}));
7472545eb61SSteven Rostedt
7482545eb61SSteven Rostedtchdir $opt{"BUILD_DIR"} || die "can't change directory to $opt{BUILD_DIR}";
7492545eb61SSteven Rostedt
7502545eb61SSteven Rostedt$target = "$opt{SSH_USER}\@$opt{MACHINE}";
7512545eb61SSteven Rostedt
7522545eb61SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n";
7532545eb61SSteven Rostedt
7542545eb61SSteven Rostedt
7552545eb61SSteven Rostedt$make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}";
7562545eb61SSteven Rostedt
7575a391fbfSSteven Rostedtsub set_build_option {
7585a391fbfSSteven Rostedt    my ($name, $i) = @_;
7595a391fbfSSteven Rostedt
7605a391fbfSSteven Rostedt    my $option = "$name\[$i\]";
7615a391fbfSSteven Rostedt
7625a391fbfSSteven Rostedt    if (defined($opt{$option})) {
7635a391fbfSSteven Rostedt	return $opt{$option};
7645a391fbfSSteven Rostedt    }
7655a391fbfSSteven Rostedt
7665a391fbfSSteven Rostedt    if (defined($opt{$name})) {
7675a391fbfSSteven Rostedt	return $opt{$name};
7685a391fbfSSteven Rostedt    }
7695a391fbfSSteven Rostedt
7705a391fbfSSteven Rostedt    return undef;
7715a391fbfSSteven Rostedt}
7725a391fbfSSteven Rostedt
7732545eb61SSteven Rostedt# First we need to do is the builds
7742545eb61SSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) {
7752545eb61SSteven Rostedt    my $type = "BUILD_TYPE[$i]";
7762545eb61SSteven Rostedt
7771a5cfce3SSteven Rostedt    if (!defined($opt{$type})) {
7781a5cfce3SSteven Rostedt	$opt{$type} = $opt{"DEFAULT_BUILD_TYPE"};
7791a5cfce3SSteven Rostedt    }
7801a5cfce3SSteven Rostedt
7815a391fbfSSteven Rostedt    $noclean = set_build_option("BUILD_NOCLEAN", $i);
7825a391fbfSSteven Rostedt    $minconfig = set_build_option("MIN_CONFIG", $i);
7835a391fbfSSteven Rostedt    $run_test = set_build_option("TEST", $i);
7842545eb61SSteven Rostedt
7852545eb61SSteven Rostedt    doprint "\n\n";
7862545eb61SSteven Rostedt    doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $opt{$type}\n\n";
7872545eb61SSteven Rostedt
788*6c5ee0beSSteven Rostedt    my $checkout = $opt{"CHECKOUT[$i]"};
789*6c5ee0beSSteven Rostedt    if (defined($checkout)) {
790*6c5ee0beSSteven Rostedt	run_command "git checkout $checkout" or
791*6c5ee0beSSteven Rostedt	    die "failed to checkout $checkout";
792*6c5ee0beSSteven Rostedt    }
793*6c5ee0beSSteven Rostedt
7945f9b6cedSSteven Rostedt    if ($opt{$type} eq "bisect") {
7955f9b6cedSSteven Rostedt	bisect $i;
7965f9b6cedSSteven Rostedt	next;
797*6c5ee0beSSteven Rostedt    } elsif ($opt{$type} eq "patchcheck") {
798*6c5ee0beSSteven Rostedt	patchcheck $i;
799*6c5ee0beSSteven Rostedt	next;
8005f9b6cedSSteven Rostedt    }
8015f9b6cedSSteven Rostedt
8022545eb61SSteven Rostedt    if ($opt{$type} ne "nobuild") {
8035c42fc5bSSteven Rostedt	build $opt{$type};
8042545eb61SSteven Rostedt    }
8052545eb61SSteven Rostedt
8065f9b6cedSSteven Rostedt    get_grub_index;
8075f9b6cedSSteven Rostedt    get_version;
8082545eb61SSteven Rostedt    install;
8092545eb61SSteven Rostedt    monitor;
8105a391fbfSSteven Rostedt
8115a391fbfSSteven Rostedt    if (defined($run_test)) {
8125a391fbfSSteven Rostedt	do_run_test;
8135a391fbfSSteven Rostedt    }
8145a391fbfSSteven Rostedt
8155f9b6cedSSteven Rostedt    success $i;
81675c3fda7SSteven Rostedt}
8172545eb61SSteven Rostedt
8185c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) {
81975c3fda7SSteven Rostedt    halt;
8201a5cfce3SSteven Rostedt} elsif ($opt{"REBOOT_ON_SUCCESS"}) {
82175c3fda7SSteven Rostedt    reboot;
8225c42fc5bSSteven Rostedt}
82375c3fda7SSteven Rostedt
8242545eb61SSteven Rostedtexit 0;
825