xref: /openbmc/linux/tools/testing/ktest/ktest.pl (revision 5f9b6ced04a4e9c3ee6b4d4042ac5935ef5a8dbd)
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;
245c42fc5bSSteven Rostedt$opt{"POWEROFF_ON_SUCCESS"}	= 0;
2575c3fda7SSteven Rostedt$opt{"BUILD_OPTIONS"}		= "";
262545eb61SSteven Rostedt
272545eb61SSteven Rostedtmy $version;
282545eb61SSteven Rostedtmy $grub_number;
292545eb61SSteven Rostedtmy $target;
302545eb61SSteven Rostedtmy $make;
315c42fc5bSSteven Rostedtmy $noclean;
32*5f9b6cedSSteven Rostedtmy $minconfig;
33*5f9b6cedSSteven Rostedtmy $in_bisect = 0;
34*5f9b6cedSSteven Rostedtmy $bisect_bad = "";
352545eb61SSteven Rostedt
362545eb61SSteven Rostedtsub read_config {
372545eb61SSteven Rostedt    my ($config) = @_;
382545eb61SSteven Rostedt
392545eb61SSteven Rostedt    open(IN, $config) || die "can't read file $config";
402545eb61SSteven Rostedt
412545eb61SSteven Rostedt    while (<IN>) {
422545eb61SSteven Rostedt
432545eb61SSteven Rostedt	# ignore blank lines and comments
442545eb61SSteven Rostedt	next if (/^\s*$/ || /\s*\#/);
452545eb61SSteven Rostedt
462545eb61SSteven Rostedt	if (/^\s*(\S+)\s*=\s*(.*?)\s*$/) {
472545eb61SSteven Rostedt	    my $lvalue = $1;
482545eb61SSteven Rostedt	    my $rvalue = $2;
492545eb61SSteven Rostedt
502545eb61SSteven Rostedt	    $opt{$lvalue} = $rvalue;
512545eb61SSteven Rostedt	}
522545eb61SSteven Rostedt    }
532545eb61SSteven Rostedt
542545eb61SSteven Rostedt    close(IN);
552545eb61SSteven Rostedt}
562545eb61SSteven Rostedt
57*5f9b6cedSSteven Rostedtsub logit {
582545eb61SSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
592545eb61SSteven Rostedt	open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
602545eb61SSteven Rostedt	print OUT @_;
612545eb61SSteven Rostedt	close(OUT);
622545eb61SSteven Rostedt    }
632545eb61SSteven Rostedt}
642545eb61SSteven Rostedt
65*5f9b6cedSSteven Rostedtsub doprint {
66*5f9b6cedSSteven Rostedt    print @_;
67*5f9b6cedSSteven Rostedt    logit @_;
68*5f9b6cedSSteven Rostedt}
69*5f9b6cedSSteven Rostedt
705c42fc5bSSteven Rostedtsub dodie {
715c42fc5bSSteven Rostedt    doprint "CRITICAL FAILURE... ", @_;
725c42fc5bSSteven Rostedt
7375c3fda7SSteven Rostedt    if ($opt{"REBOOT_ON_ERROR"}) {
7475c3fda7SSteven Rostedt	doprint "REBOOTING\n";
7575c3fda7SSteven Rostedt	`$opt{"POWER_CYCLE"}`;
7675c3fda7SSteven Rostedt
7775c3fda7SSteven Rostedt    } elsif ($opt{"POWEROFF_ON_ERROR"} && defined($opt{"POWER_OFF"})) {
785c42fc5bSSteven Rostedt	doprint "POWERING OFF\n";
795c42fc5bSSteven Rostedt	`$opt{"POWER_OFF"}`;
805c42fc5bSSteven Rostedt    }
8175c3fda7SSteven Rostedt
825c42fc5bSSteven Rostedt    die @_;
835c42fc5bSSteven Rostedt}
845c42fc5bSSteven Rostedt
852545eb61SSteven Rostedtsub run_command {
862545eb61SSteven Rostedt    my ($command) = @_;
872545eb61SSteven Rostedt    my $redirect = "";
882545eb61SSteven Rostedt
892545eb61SSteven Rostedt    if (defined($opt{"LOG_FILE"})) {
902545eb61SSteven Rostedt	$redirect = " >> $opt{LOG_FILE} 2>&1";
912545eb61SSteven Rostedt    }
922545eb61SSteven Rostedt
932545eb61SSteven Rostedt    doprint "$command ... ";
942545eb61SSteven Rostedt    `$command $redirect`;
952545eb61SSteven Rostedt
962545eb61SSteven Rostedt    my $failed = $?;
972545eb61SSteven Rostedt
982545eb61SSteven Rostedt    if ($failed) {
992545eb61SSteven Rostedt	doprint "FAILED!\n";
1002545eb61SSteven Rostedt    } else {
1012545eb61SSteven Rostedt	doprint "SUCCESS\n";
1022545eb61SSteven Rostedt    }
1032545eb61SSteven Rostedt
104*5f9b6cedSSteven Rostedt    return !$failed;
105*5f9b6cedSSteven Rostedt}
106*5f9b6cedSSteven Rostedt
107*5f9b6cedSSteven Rostedtsub get_grub_index {
108*5f9b6cedSSteven Rostedt
109*5f9b6cedSSteven Rostedt    return if ($grub_number >= 0);
110*5f9b6cedSSteven Rostedt
111*5f9b6cedSSteven Rostedt    doprint "Find grub menu ... ";
112*5f9b6cedSSteven Rostedt    $grub_number = -1;
113*5f9b6cedSSteven Rostedt    open(IN, "ssh $target cat /boot/grub/menu.lst |")
114*5f9b6cedSSteven Rostedt	or die "unable to get menu.lst";
115*5f9b6cedSSteven Rostedt    while (<IN>) {
116*5f9b6cedSSteven Rostedt	if (/^\s*title\s+$opt{GRUB_MENU}\s*$/) {
117*5f9b6cedSSteven Rostedt	    $grub_number++;
118*5f9b6cedSSteven Rostedt	    last;
119*5f9b6cedSSteven Rostedt	} elsif (/^\s*title\s/) {
120*5f9b6cedSSteven Rostedt	    $grub_number++;
121*5f9b6cedSSteven Rostedt	}
122*5f9b6cedSSteven Rostedt    }
123*5f9b6cedSSteven Rostedt    close(IN);
124*5f9b6cedSSteven Rostedt
125*5f9b6cedSSteven Rostedt    die "Could not find '$opt{GRUB_MENU}' in /boot/grub/menu on $opt{MACHINE}"
126*5f9b6cedSSteven Rostedt	if ($grub_number < 0);
127*5f9b6cedSSteven Rostedt    doprint "$grub_number\n";
1282545eb61SSteven Rostedt}
1292545eb61SSteven Rostedt
1302545eb61SSteven Rostedtmy $timeout = $opt{"TIMEOUT"};
1312545eb61SSteven Rostedt
1322545eb61SSteven Rostedtsub wait_for_input
1332545eb61SSteven Rostedt{
1342545eb61SSteven Rostedt    my ($fp, $time) = @_;
1352545eb61SSteven Rostedt    my $rin;
1362545eb61SSteven Rostedt    my $ready;
1372545eb61SSteven Rostedt    my $line;
1382545eb61SSteven Rostedt    my $ch;
1392545eb61SSteven Rostedt
1402545eb61SSteven Rostedt    if (!defined($time)) {
1412545eb61SSteven Rostedt	$time = $timeout;
1422545eb61SSteven Rostedt    }
1432545eb61SSteven Rostedt
1442545eb61SSteven Rostedt    $rin = '';
1452545eb61SSteven Rostedt    vec($rin, fileno($fp), 1) = 1;
1462545eb61SSteven Rostedt    $ready = select($rin, undef, undef, $time);
1472545eb61SSteven Rostedt
1482545eb61SSteven Rostedt    $line = "";
1492545eb61SSteven Rostedt
1502545eb61SSteven Rostedt    # try to read one char at a time
1512545eb61SSteven Rostedt    while (sysread $fp, $ch, 1) {
1522545eb61SSteven Rostedt	$line .= $ch;
1532545eb61SSteven Rostedt	last if ($ch eq "\n");
1542545eb61SSteven Rostedt    }
1552545eb61SSteven Rostedt
1562545eb61SSteven Rostedt    if (!length($line)) {
1572545eb61SSteven Rostedt	return undef;
1582545eb61SSteven Rostedt    }
1592545eb61SSteven Rostedt
1602545eb61SSteven Rostedt    return $line;
1612545eb61SSteven Rostedt}
1622545eb61SSteven Rostedt
16375c3fda7SSteven Rostedtsub reboot_to {
1642545eb61SSteven Rostedt    run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'";
1652545eb61SSteven Rostedt}
1662545eb61SSteven Rostedt
1672545eb61SSteven Rostedtsub monitor {
1682545eb61SSteven Rostedt    my $flags;
1692545eb61SSteven Rostedt    my $booted = 0;
1702545eb61SSteven Rostedt    my $bug = 0;
1712545eb61SSteven Rostedt    my $pid;
1722545eb61SSteven Rostedt    my $doopen2 = 0;
1735c42fc5bSSteven Rostedt    my $skip_call_trace = 0;
1742545eb61SSteven Rostedt
1752545eb61SSteven Rostedt    if ($doopen2) {
17675c3fda7SSteven Rostedt	$pid = open2(\*IN, \*OUT, $opt{"CONSOLE"});
1772545eb61SSteven Rostedt	if ($pid < 0) {
1785c42fc5bSSteven Rostedt	    dodie "Failed to connect to the console";
1792545eb61SSteven Rostedt	}
1802545eb61SSteven Rostedt    } else {
1812545eb61SSteven Rostedt	$pid = open(IN, "$opt{CONSOLE} |");
1822545eb61SSteven Rostedt    }
1832545eb61SSteven Rostedt
1842545eb61SSteven Rostedt    $flags = fcntl(IN, F_GETFL, 0) or
1855c42fc5bSSteven Rostedt	dodie "Can't get flags for the socket: $!\n";
1862545eb61SSteven Rostedt
1872545eb61SSteven Rostedt    $flags = fcntl(IN, F_SETFL, $flags | O_NONBLOCK) or
1885c42fc5bSSteven Rostedt	dodie "Can't set flags for the socket: $!\n";
1892545eb61SSteven Rostedt
1902545eb61SSteven Rostedt    my $line;
1912545eb61SSteven Rostedt    my $full_line = "";
1922545eb61SSteven Rostedt
1932545eb61SSteven Rostedt    doprint "Wait for monitor to settle down.\n";
1942545eb61SSteven Rostedt    # read the monitor and wait for the system to calm down
1952545eb61SSteven Rostedt    do {
1962545eb61SSteven Rostedt	$line = wait_for_input(\*IN, 5);
1972545eb61SSteven Rostedt    } while (defined($line));
1982545eb61SSteven Rostedt
19975c3fda7SSteven Rostedt    reboot_to;
2002545eb61SSteven Rostedt
2012545eb61SSteven Rostedt    for (;;) {
2022545eb61SSteven Rostedt
2032545eb61SSteven Rostedt	$line = wait_for_input(\*IN);
2042545eb61SSteven Rostedt
2052545eb61SSteven Rostedt	last if (!defined($line));
2062545eb61SSteven Rostedt
2072545eb61SSteven Rostedt	doprint $line;
2082545eb61SSteven Rostedt
2092545eb61SSteven Rostedt	# we are not guaranteed to get a full line
2102545eb61SSteven Rostedt	$full_line .= $line;
2112545eb61SSteven Rostedt
2122545eb61SSteven Rostedt	if ($full_line =~ /login:/) {
2132545eb61SSteven Rostedt	    $booted = 1;
2142545eb61SSteven Rostedt	}
2152545eb61SSteven Rostedt
2165c42fc5bSSteven Rostedt	if ($full_line =~ /\[ backtrace testing \]/) {
2175c42fc5bSSteven Rostedt	    $skip_call_trace = 1;
2185c42fc5bSSteven Rostedt	}
2195c42fc5bSSteven Rostedt
2202545eb61SSteven Rostedt	if ($full_line =~ /call trace:/i) {
2215c42fc5bSSteven Rostedt	    $bug = 1 if (!$skip_call_trace);
2225c42fc5bSSteven Rostedt	}
2235c42fc5bSSteven Rostedt
2245c42fc5bSSteven Rostedt	if ($full_line =~ /\[ end of backtrace testing \]/) {
2255c42fc5bSSteven Rostedt	    $skip_call_trace = 0;
2265c42fc5bSSteven Rostedt	}
2275c42fc5bSSteven Rostedt
2285c42fc5bSSteven Rostedt	if ($full_line =~ /Kernel panic -/) {
2292545eb61SSteven Rostedt	    $bug = 1;
2302545eb61SSteven Rostedt	}
2312545eb61SSteven Rostedt
2322545eb61SSteven Rostedt	if ($line =~ /\n/) {
2332545eb61SSteven Rostedt	    $full_line = "";
2342545eb61SSteven Rostedt	}
2352545eb61SSteven Rostedt    }
2362545eb61SSteven Rostedt
2372545eb61SSteven Rostedt    doprint "kill child process $pid\n";
2382545eb61SSteven Rostedt    kill 2, $pid;
2392545eb61SSteven Rostedt
2402545eb61SSteven Rostedt    print "closing!\n";
2412545eb61SSteven Rostedt    close(IN);
2422545eb61SSteven Rostedt
2432545eb61SSteven Rostedt    if (!$booted) {
244*5f9b6cedSSteven Rostedt	return 1 if (!$in_bisect);
2455c42fc5bSSteven Rostedt	dodie "failed - never got a boot prompt.\n";
2462545eb61SSteven Rostedt    }
2472545eb61SSteven Rostedt
2482545eb61SSteven Rostedt    if ($bug) {
249*5f9b6cedSSteven Rostedt	return 1 if (!$in_bisect);
2505c42fc5bSSteven Rostedt	dodie "failed - got a bug report\n";
2512545eb61SSteven Rostedt    }
252*5f9b6cedSSteven Rostedt
253*5f9b6cedSSteven Rostedt    return 0;
2542545eb61SSteven Rostedt}
2552545eb61SSteven Rostedt
2562545eb61SSteven Rostedtsub install {
2572545eb61SSteven Rostedt
258*5f9b6cedSSteven Rostedt    run_command "scp $opt{OUTPUT_DIR}/$opt{BUILD_TARGET} $target:$opt{TARGET_IMAGE}" or
2595c42fc5bSSteven Rostedt	dodie "failed to copy image";
260*5f9b6cedSSteven Rostedt
261*5f9b6cedSSteven Rostedt    my $install_mods = 0;
262*5f9b6cedSSteven Rostedt
263*5f9b6cedSSteven Rostedt    # should we process modules?
264*5f9b6cedSSteven Rostedt    $install_mods = 0;
265*5f9b6cedSSteven Rostedt    open(IN, "$opt{OUTPUT_DIR}/.config") or dodie("Can't read config file");
266*5f9b6cedSSteven Rostedt    while (<IN>) {
267*5f9b6cedSSteven Rostedt	if (/CONFIG_MODULES(=y)?/) {
268*5f9b6cedSSteven Rostedt	    $install_mods = 1 if (defined($1));
269*5f9b6cedSSteven Rostedt	    last;
270*5f9b6cedSSteven Rostedt	}
271*5f9b6cedSSteven Rostedt    }
272*5f9b6cedSSteven Rostedt    close(IN);
273*5f9b6cedSSteven Rostedt
274*5f9b6cedSSteven Rostedt    if (!$install_mods) {
275*5f9b6cedSSteven Rostedt	doprint "No modules needed\n";
276*5f9b6cedSSteven Rostedt	return;
2772545eb61SSteven Rostedt    }
2782545eb61SSteven Rostedt
279*5f9b6cedSSteven Rostedt    run_command "$make INSTALL_MOD_PATH=$opt{TMP_DIR} modules_install" or
280*5f9b6cedSSteven Rostedt	dodie "Failed to install modules";
281*5f9b6cedSSteven Rostedt
2822545eb61SSteven Rostedt    my $modlib = "/lib/modules/$version";
2835c42fc5bSSteven Rostedt    my $modtar = "autotest-mods.tar.bz2";
2842545eb61SSteven Rostedt
285*5f9b6cedSSteven Rostedt    run_command "ssh $target rm -rf $modlib" or
2865c42fc5bSSteven Rostedt	dodie "failed to remove old mods: $modlib";
2872545eb61SSteven Rostedt
2885c42fc5bSSteven Rostedt    # would be nice if scp -r did not follow symbolic links
289*5f9b6cedSSteven Rostedt    run_command "cd $opt{TMP_DIR} && tar -cjf $modtar lib/modules/$version" or
2905c42fc5bSSteven Rostedt	dodie "making tarball";
2915c42fc5bSSteven Rostedt
292*5f9b6cedSSteven Rostedt    run_command "scp $opt{TMP_DIR}/$modtar $target:/tmp" or
2935c42fc5bSSteven Rostedt	dodie "failed to copy modules";
2945c42fc5bSSteven Rostedt
2955c42fc5bSSteven Rostedt    unlink "$opt{TMP_DIR}/$modtar";
2965c42fc5bSSteven Rostedt
297*5f9b6cedSSteven Rostedt    run_command "ssh $target '(cd / && tar xf /tmp/$modtar)'" or
2985c42fc5bSSteven Rostedt	dodie "failed to tar modules";
2995c42fc5bSSteven Rostedt
3005c42fc5bSSteven Rostedt    run_command "ssh $target rm -f /tmp/$modtar";
3012545eb61SSteven Rostedt}
3022545eb61SSteven Rostedt
3032545eb61SSteven Rostedtsub build {
3042545eb61SSteven Rostedt    my ($type) = @_;
3055c42fc5bSSteven Rostedt    my $defconfig = "";
3065c42fc5bSSteven Rostedt    my $append = "";
3072545eb61SSteven Rostedt
30875c3fda7SSteven Rostedt    if ($type =~ /^useconfig:(.*)/) {
309*5f9b6cedSSteven Rostedt	run_command "cp $1 $opt{OUTPUT_DIR}/.config" or
31075c3fda7SSteven Rostedt	    dodie "could not copy $1 to .config";
311*5f9b6cedSSteven Rostedt
31275c3fda7SSteven Rostedt	$type = "oldconfig";
31375c3fda7SSteven Rostedt    }
31475c3fda7SSteven Rostedt
3155c42fc5bSSteven Rostedt    # old config can ask questions
3165c42fc5bSSteven Rostedt    if ($type eq "oldconfig") {
3175c42fc5bSSteven Rostedt	$append = "yes ''|";
31875c3fda7SSteven Rostedt
31975c3fda7SSteven Rostedt	# allow for empty configs
32075c3fda7SSteven Rostedt	run_command "touch $opt{OUTPUT_DIR}/.config";
32175c3fda7SSteven Rostedt
322*5f9b6cedSSteven Rostedt	run_command "mv $opt{OUTPUT_DIR}/.config $opt{OUTPUT_DIR}/config_temp" or
3235c42fc5bSSteven Rostedt	    dodie "moving .config";
3245c42fc5bSSteven Rostedt
325*5f9b6cedSSteven Rostedt	if (!$noclean && !run_command "$make mrproper") {
3265c42fc5bSSteven Rostedt	    dodie "make mrproper";
3275c42fc5bSSteven Rostedt	}
3285c42fc5bSSteven Rostedt
329*5f9b6cedSSteven Rostedt	run_command "mv $opt{OUTPUT_DIR}/config_temp $opt{OUTPUT_DIR}/.config" or
3305c42fc5bSSteven Rostedt	    dodie "moving config_temp";
3315c42fc5bSSteven Rostedt
3325c42fc5bSSteven Rostedt    } elsif (!$noclean) {
3332545eb61SSteven Rostedt	unlink "$opt{OUTPUT_DIR}/.config";
334*5f9b6cedSSteven Rostedt	run_command "$make mrproper" or
3355c42fc5bSSteven Rostedt	    dodie "make mrproper";
3365c42fc5bSSteven Rostedt    }
3372545eb61SSteven Rostedt
3382545eb61SSteven Rostedt    # add something to distinguish this build
3395c42fc5bSSteven Rostedt    open(OUT, "> $opt{OUTPUT_DIR}/localversion") or dodie("Can't make localversion file");
3402545eb61SSteven Rostedt    print OUT "$opt{LOCALVERSION}\n";
3412545eb61SSteven Rostedt    close(OUT);
3422545eb61SSteven Rostedt
343*5f9b6cedSSteven Rostedt    if (defined($minconfig)) {
344*5f9b6cedSSteven Rostedt	$defconfig = "KCONFIG_ALLCONFIG=$minconfig";
3452545eb61SSteven Rostedt    }
3462545eb61SSteven Rostedt
347*5f9b6cedSSteven Rostedt    run_command "$defconfig $append $make $type" or
3485c42fc5bSSteven Rostedt	dodie "failed make config";
3492545eb61SSteven Rostedt
350*5f9b6cedSSteven Rostedt    if (!run_command "$make $opt{BUILD_OPTIONS}") {
351*5f9b6cedSSteven Rostedt	# bisect may need this to pass
352*5f9b6cedSSteven Rostedt	return 1 if ($in_bisect);
3535c42fc5bSSteven Rostedt	dodie "failed build";
3542545eb61SSteven Rostedt    }
355*5f9b6cedSSteven Rostedt
356*5f9b6cedSSteven Rostedt    return 0;
3572545eb61SSteven Rostedt}
3582545eb61SSteven Rostedt
35975c3fda7SSteven Rostedtsub reboot {
36075c3fda7SSteven Rostedt    # try to reboot normally
361*5f9b6cedSSteven Rostedt    if (!run_command "ssh $target reboot") {
36275c3fda7SSteven Rostedt	# nope? power cycle it.
36375c3fda7SSteven Rostedt	run_command "$opt{POWER_CYCLE}";
36475c3fda7SSteven Rostedt    }
36575c3fda7SSteven Rostedt}
36675c3fda7SSteven Rostedt
36775c3fda7SSteven Rostedtsub halt {
368*5f9b6cedSSteven Rostedt    if (!run_command "ssh $target halt" or defined($opt{"POWER_OFF"})) {
36975c3fda7SSteven Rostedt	# nope? the zap it!
37075c3fda7SSteven Rostedt	run_command "$opt{POWER_OFF}";
37175c3fda7SSteven Rostedt    }
37275c3fda7SSteven Rostedt}
37375c3fda7SSteven Rostedt
374*5f9b6cedSSteven Rostedtsub success {
375*5f9b6cedSSteven Rostedt    my ($i) = @_;
376*5f9b6cedSSteven Rostedt
377*5f9b6cedSSteven Rostedt    doprint "\n\n*******************************************\n";
378*5f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
379*5f9b6cedSSteven Rostedt    doprint     "**            SUCCESS!!!!                **\n";
380*5f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
381*5f9b6cedSSteven Rostedt    doprint     "*******************************************\n";
382*5f9b6cedSSteven Rostedt
383*5f9b6cedSSteven Rostedt    if ($i != $opt{"NUM_BUILDS"}) {
384*5f9b6cedSSteven Rostedt	reboot;
385*5f9b6cedSSteven Rostedt	doprint "Sleeping $opt{SLEEP_TIME} seconds\n";
386*5f9b6cedSSteven Rostedt	sleep "$opt{SLEEP_TIME}";
387*5f9b6cedSSteven Rostedt    }
388*5f9b6cedSSteven Rostedt}
389*5f9b6cedSSteven Rostedt
390*5f9b6cedSSteven Rostedtsub get_version {
391*5f9b6cedSSteven Rostedt    # get the release name
392*5f9b6cedSSteven Rostedt    doprint "$make kernelrelease ... ";
393*5f9b6cedSSteven Rostedt    $version = `$make kernelrelease | tail -1`;
394*5f9b6cedSSteven Rostedt    chomp($version);
395*5f9b6cedSSteven Rostedt    doprint "$version\n";
396*5f9b6cedSSteven Rostedt}
397*5f9b6cedSSteven Rostedt
398*5f9b6cedSSteven Rostedtsub run_bisect {
399*5f9b6cedSSteven Rostedt    my ($type) = @_;
400*5f9b6cedSSteven Rostedt
401*5f9b6cedSSteven Rostedt    my $failed;
402*5f9b6cedSSteven Rostedt    my $result;
403*5f9b6cedSSteven Rostedt    my $output;
404*5f9b6cedSSteven Rostedt    my $ret;
405*5f9b6cedSSteven Rostedt
406*5f9b6cedSSteven Rostedt
407*5f9b6cedSSteven Rostedt    if (defined($minconfig)) {
408*5f9b6cedSSteven Rostedt	$failed = build "useconfig:$minconfig";
409*5f9b6cedSSteven Rostedt    } else {
410*5f9b6cedSSteven Rostedt	# ?? no config to use?
411*5f9b6cedSSteven Rostedt	$failed = build "oldconfig";
412*5f9b6cedSSteven Rostedt    }
413*5f9b6cedSSteven Rostedt
414*5f9b6cedSSteven Rostedt    if ($type ne "build") {
415*5f9b6cedSSteven Rostedt	dodie "Failed on build" if $failed;
416*5f9b6cedSSteven Rostedt
417*5f9b6cedSSteven Rostedt	# Now boot the box
418*5f9b6cedSSteven Rostedt	get_grub_index;
419*5f9b6cedSSteven Rostedt	get_version;
420*5f9b6cedSSteven Rostedt	install;
421*5f9b6cedSSteven Rostedt	$failed = monitor;
422*5f9b6cedSSteven Rostedt
423*5f9b6cedSSteven Rostedt	if ($type ne "boot") {
424*5f9b6cedSSteven Rostedt	    dodie "Failed on boot" if $failed;
425*5f9b6cedSSteven Rostedt	}
426*5f9b6cedSSteven Rostedt    }
427*5f9b6cedSSteven Rostedt
428*5f9b6cedSSteven Rostedt    if ($failed) {
429*5f9b6cedSSteven Rostedt	$result = "bad";
430*5f9b6cedSSteven Rostedt    } else {
431*5f9b6cedSSteven Rostedt	$result = "good";
432*5f9b6cedSSteven Rostedt    }
433*5f9b6cedSSteven Rostedt
434*5f9b6cedSSteven Rostedt    doprint "git bisect $result ... ";
435*5f9b6cedSSteven Rostedt    $output = `git bisect $result 2>&1`;
436*5f9b6cedSSteven Rostedt    $ret = $?;
437*5f9b6cedSSteven Rostedt
438*5f9b6cedSSteven Rostedt    logit $output;
439*5f9b6cedSSteven Rostedt
440*5f9b6cedSSteven Rostedt    if ($ret) {
441*5f9b6cedSSteven Rostedt	doprint "FAILED\n";
442*5f9b6cedSSteven Rostedt	dodie "Failed to git bisect";
443*5f9b6cedSSteven Rostedt    }
444*5f9b6cedSSteven Rostedt
445*5f9b6cedSSteven Rostedt    doprint "SUCCESS\n";
446*5f9b6cedSSteven Rostedt    if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\)) \[([[:xdigit:]]+)\]/) {
447*5f9b6cedSSteven Rostedt	doprint "$1 [$2]\n";
448*5f9b6cedSSteven Rostedt    } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) {
449*5f9b6cedSSteven Rostedt	$bisect_bad = $1;
450*5f9b6cedSSteven Rostedt	doprint "Found bad commit... $1\n";
451*5f9b6cedSSteven Rostedt	return 0;
452*5f9b6cedSSteven Rostedt    }
453*5f9b6cedSSteven Rostedt
454*5f9b6cedSSteven Rostedt
455*5f9b6cedSSteven Rostedt    return 1;
456*5f9b6cedSSteven Rostedt}
457*5f9b6cedSSteven Rostedt
458*5f9b6cedSSteven Rostedtsub bisect {
459*5f9b6cedSSteven Rostedt    my ($i) = @_;
460*5f9b6cedSSteven Rostedt
461*5f9b6cedSSteven Rostedt    my $result;
462*5f9b6cedSSteven Rostedt
463*5f9b6cedSSteven Rostedt    die "BISECT_GOOD[$i] not defined\n"	if (!defined($opt{"BISECT_GOOD[$i]"}));
464*5f9b6cedSSteven Rostedt    die "BISECT_BAD[$i] not defined\n"	if (!defined($opt{"BISECT_BAD[$i]"}));
465*5f9b6cedSSteven Rostedt    die "BISECT_TYPE[$i] not defined\n"	if (!defined($opt{"BISECT_TYPE[$i]"}));
466*5f9b6cedSSteven Rostedt
467*5f9b6cedSSteven Rostedt    my $good = $opt{"BISECT_GOOD[$i]"};
468*5f9b6cedSSteven Rostedt    my $bad = $opt{"BISECT_BAD[$i]"};
469*5f9b6cedSSteven Rostedt    my $type = $opt{"BISECT_TYPE[$i]"};
470*5f9b6cedSSteven Rostedt
471*5f9b6cedSSteven Rostedt    $in_bisect = 1;
472*5f9b6cedSSteven Rostedt
473*5f9b6cedSSteven Rostedt    run_command "git bisect start" or
474*5f9b6cedSSteven Rostedt	dodie "could not start bisect";
475*5f9b6cedSSteven Rostedt
476*5f9b6cedSSteven Rostedt    run_command "git bisect good $good" or
477*5f9b6cedSSteven Rostedt	dodie "could not set bisect good to $good";
478*5f9b6cedSSteven Rostedt
479*5f9b6cedSSteven Rostedt    run_command "git bisect bad $bad" or
480*5f9b6cedSSteven Rostedt	dodie "could not set bisect good to $bad";
481*5f9b6cedSSteven Rostedt
482*5f9b6cedSSteven Rostedt    do {
483*5f9b6cedSSteven Rostedt	$result = run_bisect $type;
484*5f9b6cedSSteven Rostedt    } while ($result);
485*5f9b6cedSSteven Rostedt
486*5f9b6cedSSteven Rostedt    run_command "git bisect log" or
487*5f9b6cedSSteven Rostedt	dodie "could not capture git bisect log";
488*5f9b6cedSSteven Rostedt
489*5f9b6cedSSteven Rostedt    run_command "git bisect reset" or
490*5f9b6cedSSteven Rostedt	dodie "could not reset git bisect";
491*5f9b6cedSSteven Rostedt
492*5f9b6cedSSteven Rostedt    doprint "Bad commit was [$bisect_bad]\n";
493*5f9b6cedSSteven Rostedt
494*5f9b6cedSSteven Rostedt    $in_bisect = 0;
495*5f9b6cedSSteven Rostedt
496*5f9b6cedSSteven Rostedt    success $i;
497*5f9b6cedSSteven Rostedt}
498*5f9b6cedSSteven Rostedt
4992545eb61SSteven Rostedtread_config $ARGV[0];
5002545eb61SSteven Rostedt
5012545eb61SSteven Rostedt# mandatory configs
5022545eb61SSteven Rostedtdie "MACHINE not defined\n"		if (!defined($opt{"MACHINE"}));
5032545eb61SSteven Rostedtdie "SSH_USER not defined\n"		if (!defined($opt{"SSH_USER"}));
5042545eb61SSteven Rostedtdie "BUILD_DIR not defined\n"		if (!defined($opt{"BUILD_DIR"}));
5052545eb61SSteven Rostedtdie "OUTPUT_DIR not defined\n"		if (!defined($opt{"OUTPUT_DIR"}));
5062545eb61SSteven Rostedtdie "BUILD_TARGET not defined\n"	if (!defined($opt{"BUILD_TARGET"}));
50775c3fda7SSteven Rostedtdie "TARGET_IMAGE not defined\n"	if (!defined($opt{"TARGET_IMAGE"}));
5082545eb61SSteven Rostedtdie "POWER_CYCLE not defined\n"		if (!defined($opt{"POWER_CYCLE"}));
5092545eb61SSteven Rostedtdie "CONSOLE not defined\n"		if (!defined($opt{"CONSOLE"}));
5102545eb61SSteven Rostedtdie "LOCALVERSION not defined\n"	if (!defined($opt{"LOCALVERSION"}));
5112545eb61SSteven Rostedtdie "GRUB_MENU not defined\n"		if (!defined($opt{"GRUB_MENU"}));
5122545eb61SSteven Rostedt
5132545eb61SSteven Rostedtchdir $opt{"BUILD_DIR"} || die "can't change directory to $opt{BUILD_DIR}";
5142545eb61SSteven Rostedt
5152545eb61SSteven Rostedt$target = "$opt{SSH_USER}\@$opt{MACHINE}";
5162545eb61SSteven Rostedt
5172545eb61SSteven Rostedtdoprint "\n\nSTARTING AUTOMATED TESTS\n";
5182545eb61SSteven Rostedt
5192545eb61SSteven Rostedt
5202545eb61SSteven Rostedt$make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}";
5212545eb61SSteven Rostedt
5222545eb61SSteven Rostedt# First we need to do is the builds
5232545eb61SSteven Rostedtfor (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) {
5242545eb61SSteven Rostedt    my $type = "BUILD_TYPE[$i]";
5252545eb61SSteven Rostedt
5265c42fc5bSSteven Rostedt    if (defined($opt{"BUILD_NOCLEAN[$i]"}) &&
5275c42fc5bSSteven Rostedt	$opt{"BUILD_NOCLEAN[$i]"} != 0) {
5285c42fc5bSSteven Rostedt	$noclean = 1;
5295c42fc5bSSteven Rostedt    } else {
5305c42fc5bSSteven Rostedt	$noclean = $opt{"BUILD_NOCLEAN"};
5315c42fc5bSSteven Rostedt    }
5325c42fc5bSSteven Rostedt
533*5f9b6cedSSteven Rostedt    if (defined($opt{"MIN_CONFIG[$i]"})) {
534*5f9b6cedSSteven Rostedt	$minconfig = $opt{"MIN_CONFIG[$i]"};
535*5f9b6cedSSteven Rostedt    } elsif (defined($opt{"MIN_CONFIG"})) {
536*5f9b6cedSSteven Rostedt	$minconfig = $opt{"MIN_CONFIG"};
537*5f9b6cedSSteven Rostedt    } else {
538*5f9b6cedSSteven Rostedt	undef $minconfig;
539*5f9b6cedSSteven Rostedt    }
540*5f9b6cedSSteven Rostedt
5412545eb61SSteven Rostedt    if (!defined($opt{$type})) {
5422545eb61SSteven Rostedt	$opt{$type} = $opt{"DEFAULT_BUILD_TYPE"};
5432545eb61SSteven Rostedt    }
5442545eb61SSteven Rostedt
5452545eb61SSteven Rostedt    doprint "\n\n";
5462545eb61SSteven Rostedt    doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $opt{$type}\n\n";
5472545eb61SSteven Rostedt
548*5f9b6cedSSteven Rostedt    if ($opt{$type} eq "bisect") {
549*5f9b6cedSSteven Rostedt	bisect $i;
550*5f9b6cedSSteven Rostedt	next;
551*5f9b6cedSSteven Rostedt    }
552*5f9b6cedSSteven Rostedt
5532545eb61SSteven Rostedt    if ($opt{$type} ne "nobuild") {
5545c42fc5bSSteven Rostedt	build $opt{$type};
5552545eb61SSteven Rostedt    }
5562545eb61SSteven Rostedt
557*5f9b6cedSSteven Rostedt    get_grub_index;
558*5f9b6cedSSteven Rostedt    get_version;
5592545eb61SSteven Rostedt    install;
5602545eb61SSteven Rostedt    monitor;
561*5f9b6cedSSteven Rostedt    success $i;
56275c3fda7SSteven Rostedt}
5632545eb61SSteven Rostedt
5645c42fc5bSSteven Rostedtif ($opt{"POWEROFF_ON_SUCCESS"}) {
56575c3fda7SSteven Rostedt    halt;
56675c3fda7SSteven Rostedt} else {
56775c3fda7SSteven Rostedt    reboot;
5685c42fc5bSSteven Rostedt}
56975c3fda7SSteven Rostedt
5702545eb61SSteven Rostedtexit 0;
571