#!/usr/bin/perl -w
#
# Copywrite 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
# Licensed under the terms of the GNU GPL License version 2
#
use strict;
use IPC::Open2;
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK);
use FileHandle;
$#ARGV >= 0 || die "usage: autotest.pl config-file\n";
$| = 1;
my %opt;
#default opts
$opt{"NUM_BUILDS"} = 5;
$opt{"DEFAULT_BUILD_TYPE"} = "randconfig";
$opt{"MAKE_CMD"} = "make";
$opt{"TIMEOUT"} = 120;
$opt{"TMP_DIR"} = "/tmp/autotest";
$opt{"SLEEP_TIME"} = 60; # sleep time between tests
$opt{"BUILD_NOCLEAN"} = 0;
$opt{"REBOOT_ON_ERROR"} = 0;
$opt{"POWEROFF_ON_ERROR"} = 0;
$opt{"REBOOT_ON_SUCCESS"} = 1;
$opt{"POWEROFF_ON_SUCCESS"} = 0;
$opt{"BUILD_OPTIONS"} = "";
$opt{"BISECT_SLEEP_TIME"} = 10; # sleep time between bisects
$opt{"CLEAR_LOG"} = 0;
$opt{"SUCCESS_LINE"} = "login:";
$opt{"BOOTED_TIMEOUT"} = 1;
$opt{"DIE_ON_FAILURE"} = 1;
my $version;
my $grub_number;
my $target;
my $make;
my $noclean;
my $minconfig;
my $addconfig;
my $in_bisect = 0;
my $bisect_bad = "";
my $reverse_bisect;
my $in_patchcheck = 0;
my $run_test;
my $redirect;
sub read_config {
my ($config) = @_;
open(IN, $config) || die "can't read file $config";
while (<IN>) {
# ignore blank lines and comments
next if (/^\s*$/ || /\s*\#/);
if (/^\s*(\S+)\s*=\s*(.*?)\s*$/) {
my $lvalue = $1;
my $rvalue = $2;
$opt{$lvalue} = $rvalue;
}
}
close(IN);
}
sub logit {
if (defined($opt{"LOG_FILE"})) {
open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}";
print OUT @_;
close(OUT);
}
}
sub doprint {
print @_;
logit @_;
}
sub dodie {
doprint "CRITICAL FAILURE... ", @_, "\n";
if ($opt{"REBOOT_ON_ERROR"}) {
doprint "REBOOTING\n";
`$opt{"POWER_CYCLE"}`;
} elsif ($opt{"POWEROFF_ON_ERROR"} && defined($opt{"POWER_OFF"})) {
doprint "POWERING OFF\n";
`$opt{"POWER_OFF"}`;
}
die @_;
}
sub fail {
if ($opt{"DIE_ON_FAILURE"}) {
dodie @_;
}
doprint "Failed: ", @_, "\n";
return 1;
}
sub run_command {
my ($command) = @_;
my $dolog = 0;
my $dord = 0;
my $pid;
doprint("$command ... ");
$pid = open(CMD, "$command 2>&1 |") or
(fail "unable to exec $command" and return 0);
if (defined($opt{"LOG_FILE"})) {
open(LOG, ">>$opt{LOG_FILE}") or
dodie "failed to write to log";
$dolog = 1;
}
if (defined($redirect)) {
open (RD, ">$redirect") or
dodie "failed to write to redirect $redirect";
$dord = 1;
}
while (<CMD>) {
print LOG if ($dolog);
print RD if ($dord);
}
waitpid($pid, 0);
my $failed = $?;
close(CMD);
close(LOG) if ($dolog);
close(RD) if ($dord);
if ($failed) {
doprint "FAILED!\n";
} else {
doprint "SUCCESS\n";
}
return !$failed;
}
sub get_grub_index {
return if (defined($grub_number));
doprint "Find grub menu ... ";
$grub_number = -1;
open(IN, "ssh $target cat /boot/grub/menu.lst |")
or die "unable to get menu.lst";
while (<IN>) {
if (/^\s*title\s+$opt{GRUB_MENU}\s*$/) {
$grub_number++;
last;
} elsif (/^\s*title\s/) {
$grub_number++;
}
}
close(IN);
die "Could not find '$opt{GRUB_MENU}' in /boot/grub/menu on $opt{MACHINE}"
if ($grub_number < 0);
doprint "$grub_number\n";
}
my $timeout = $opt{"TIMEOUT"};
sub wait_for_input
{
my ($fp, $time) = @_;
my $rin;
my $ready;
my $line;
my $ch;
if (!defined($time)) {
$time = $timeo