From 7faafbd69639b53b6cc2d450c283d9cc12e62c70 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Nov 2010 14:58:22 -0400 Subject: ktest: Add open and close console and start stop monitor It is much better to keep the monitor running throughout a test than to constantly start and stop it. Some console readers will show everything that has happened before when opening the console, and by opening it several times, causes the old content to be read multiple times in a single test. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 257 ++++++++++++++++++++++++++++--------------- 1 file changed, 170 insertions(+), 87 deletions(-) (limited to 'tools') diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 0a0b1b16fccd..ff6283a44847 100644 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -7,6 +7,8 @@ use strict; use IPC::Open2; use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK); +use File::Path qw(mkpath); +use File::Copy qw(cp); use FileHandle; $#ARGV >= 0 || die "usage: autotest.pl config-file\n"; @@ -17,7 +19,7 @@ my %opt; #default opts $opt{"NUM_BUILDS"} = 5; -$opt{"DEFAULT_BUILD_TYPE"} = "randconfig"; +$opt{"BUILD_TYPE"} = "randconfig"; $opt{"MAKE_CMD"} = "make"; $opt{"TIMEOUT"} = 120; $opt{"TMP_DIR"} = "/tmp/autotest"; @@ -35,6 +37,7 @@ $opt{"BOOTED_TIMEOUT"} = 1; $opt{"DIE_ON_FAILURE"} = 1; my $version; +my $build_type; my $grub_number; my $target; my $make; @@ -47,6 +50,11 @@ my $reverse_bisect; my $in_patchcheck = 0; my $run_test; my $redirect; +my $buildlog; +my $dmesg; +my $monitor_fp; +my $monitor_pid; +my $monitor_cnt = 0; sub read_config { my ($config) = @_; @@ -82,12 +90,22 @@ sub doprint { logit @_; } +sub run_command; + +sub reboot { + # try to reboot normally + if (!run_command "ssh $target reboot") { + # nope? power cycle it. + run_command "$opt{POWER_CYCLE}"; + } +} + sub dodie { doprint "CRITICAL FAILURE... ", @_, "\n"; if ($opt{"REBOOT_ON_ERROR"}) { doprint "REBOOTING\n"; - `$opt{"POWER_CYCLE"}`; + reboot; } elsif ($opt{"POWEROFF_ON_ERROR"} && defined($opt{"POWER_OFF"})) { doprint "POWERING OFF\n"; @@ -97,6 +115,59 @@ sub dodie { die @_; } +sub open_console { + my ($fp) = @_; + + my $flags; + + my $pid = open($fp, "$opt{CONSOLE}|") or + dodie "Can't open console $opt{CONSOLE}"; + + $flags = fcntl($fp, F_GETFL, 0) or + dodie "Can't get flags for the socket: $!\n"; + $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or + dodie "Can't set flags for the socket: $!\n"; + + return $pid; +} + +sub close_console { + my ($fp, $pid) = @_; + + doprint "kill child process $pid\n"; + kill 2, $pid; + + print "closing!\n"; + close($fp); +} + +sub start_monitor { + if ($monitor_cnt++) { + return; + } + $monitor_fp = \*MONFD; + $monitor_pid = open_console $monitor_fp; +} + +sub end_monitor { + if (--$monitor_cnt) { + return; + } + close_console($monitor_fp, $monitor_pid); +} + +sub wait_for_monitor { + my ($time) = @_; + my $line; + + doprint "Wait for monitor to settle down.\n"; + + # read the monitor and wait for the system to calm down + do { + $line = wait_for_input($monitor_fp, $time); + } while (defined($line)); +} + sub fail { if ($opt{"DIE_ON_FAILURE"}) { @@ -104,6 +175,41 @@ sub fail { } doprint "Failed: ", @_, "\n"; + + doprint "REBOOTING\n"; + reboot; + start_monitor; + wait_for_monitor $opt{"SLEEP_TIME"}; + end_monitor; + + return 1 if (!defined($opt{"STORE_FAILURES"})); + + my @t = localtime; + my $date = sprintf "%04d%02d%02d%02d%02d%02d", + 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; + + my $dir = "$opt{MACHINE}-$build_type-fail-$date"; + my $faildir = "$opt{STORE_FAILURES}/$dir"; + + if (!-d $faildir) { + mkpath($faildir) or + die "can't create $opt{STORE_FAILURES}"; + } + if (-f "$opt{OUTPUT_DIR}/.config") { + cp "$opt{OUTPUT_DIR}/.config", "$faildir/config" or + die "failed to copy .config"; + } + if (-f $buildlog) { + cp $buildlog, "$faildir/buildlog" or + die "failed to move $buildlog"; + } + if (-f $dmesg) { + cp $dmesg, "$faildir/dmesg" or + die "failed to move $dmesg"; + } + + doprint "*** Saved info to $faildir ***\n"; + return 1; } @@ -211,64 +317,34 @@ sub reboot_to { run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; } -sub open_console { - my ($fp) = @_; - - my $flags; - - my $pid = open($fp, "$opt{CONSOLE}|") or - dodie "Can't open console $opt{CONSOLE}"; - - $flags = fcntl($fp, F_GETFL, 0) or - dodie "Can't get flags for the socket: $!\n"; - $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or - dodie "Can't set flags for the socket: $!\n"; - - return $pid; -} - -sub close_console { - my ($fp, $pid) = @_; - - doprint "kill child process $pid\n"; - kill 2, $pid; - - print "closing!\n"; - close($fp); -} - sub monitor { my $booted = 0; my $bug = 0; - my $pid; my $skip_call_trace = 0; - my $fp = \*IN; my $loops; - $pid = open_console($fp); + wait_for_monitor 5; my $line; my $full_line = ""; - doprint "Wait for monitor to settle down.\n"; - # read the monitor and wait for the system to calm down - do { - $line = wait_for_input($fp, 5); - } while (defined($line)); + open(DMESG, "> $dmesg") or + die "unable to write to $dmesg"; reboot_to; for (;;) { if ($booted) { - $line = wait_for_input($fp, $opt{"BOOTED_TIMEOUT"}); + $line = wait_for_input($monitor_fp, $opt{"BOOTED_TIMEOUT"}); } else { - $line = wait_for_input($fp); + $line = wait_for_input($monitor_fp); } last if (!defined($line)); doprint $line; + print DMESG $line; # we are not guaranteed to get a full line $full_line .= $line; @@ -298,7 +374,7 @@ sub monitor { } } - close_console($fp, $pid); + close(DMESG); if (!$booted) { return 0 if ($in_bisect); @@ -363,7 +439,6 @@ sub install { sub check_buildlog { my ($patch) = @_; - my $buildlog = "$opt{TMP_DIR}/buildlog"; my @files = `git show $patch | diffstat -l`; open(IN, "git show $patch |") or @@ -398,6 +473,8 @@ sub build { my $defconfig = ""; my $append = ""; + unlink $buildlog; + if ($type =~ /^useconfig:(.*)/) { run_command "cp $1 $opt{OUTPUT_DIR}/.config" or dodie "could not copy $1 to .config"; @@ -440,11 +517,7 @@ sub build { run_command "$defconfig $append $make $type" or dodie "failed make config"; - # patch check will examine the log - if ($in_patchcheck) { - $redirect = "$opt{TMP_DIR}/buildlog"; - } - + $redirect = "$opt{TMP_DIR}/buildlog"; if (!run_command "$make $opt{BUILD_OPTIONS}") { undef $redirect; # bisect may need this to pass @@ -456,14 +529,6 @@ sub build { return 1; } -sub reboot { - # try to reboot normally - if (!run_command "ssh $target reboot") { - # nope? power cycle it. - run_command "$opt{POWER_CYCLE}"; - } -} - sub halt { if (!run_command "ssh $target halt" or defined($opt{"POWER_OFF"})) { # nope? the zap it! @@ -481,9 +546,11 @@ sub success { doprint "*******************************************\n"; if ($i != $opt{"NUM_BUILDS"}) { + doprint "Reboot and wait $opt{SLEEP_TIME} seconds\n"; reboot; - doprint "Sleeping $opt{SLEEP_TIME} seconds\n"; - sleep "$opt{SLEEP_TIME}"; + start_monitor; + wait_for_monitor $opt{"SLEEP_TIME"}; + end_monitor; } } @@ -496,9 +563,14 @@ sub get_version { } sub child_run_test { - my $failed; + my $failed = 0; - $failed = !run_command $run_test; + # child should have no power + $opt{"REBOOT_ON_ERROR"} = 0; + $opt{"POWEROFF_ON_ERROR"} = 0; + $opt{"DIE_ON_FAILURE"} = 1; + + run_command $run_test or $failed = 1; exit $failed; } @@ -511,18 +583,13 @@ sub child_finished { sub do_run_test { my $child_pid; my $child_exit; - my $pid; my $line; my $full_line; my $bug = 0; - my $fp = \*IN; - $pid = open_console($fp); + wait_for_monitor 1; - # read the monitor and wait for the system to calm down - do { - $line = wait_for_input($fp, 1); - } while (defined($line)); + doprint "run test $run_test\n"; $child_done = 0; @@ -535,7 +602,7 @@ sub do_run_test { $full_line = ""; do { - $line = wait_for_input($fp, 1); + $line = wait_for_input($monitor_fp, 1); if (defined($line)) { # we are not guaranteed to get a full line @@ -564,8 +631,6 @@ sub do_run_test { waitpid $child_pid, 0; $child_exit = $?; - close_console($fp, $pid); - if ($bug || $child_exit) { return 0 if $in_bisect; fail "test failed" and return 0; @@ -589,19 +654,22 @@ sub run_bisect { } if ($type ne "build") { - fail "Failed on build" if $failed; + dodie "Failed on build" if $failed; # Now boot the box get_grub_index; get_version; install; + + start_monitor; monitor or $failed = 1; if ($type ne "boot") { - fail "Failed on boot" if $failed; + dodie "Failed on boot" if $failed; do_run_test or $failed = 1; } + end_monitor; } if ($failed) { @@ -609,9 +677,11 @@ sub run_bisect { # reboot the box to a good kernel if ($type eq "boot") { + doprint "Reboot and sleep $opt{BISECT_SLEEP_TIME} seconds\n"; reboot; - doprint "sleep a little for reboot\n"; - sleep $opt{"BISECT_SLEEP_TIME"}; + start_monitor; + wait_for_monitor $opt{"BISECT_SLEEP_TIME"}; + end_monitor; } } else { $result = "good"; @@ -782,10 +852,18 @@ sub patchcheck { get_grub_index; get_version; install; - monitor or return 0; - next if ($type eq "boot"); - do_run_test or next; + my $failed = 0; + + start_monitor; + monitor or $failed = 1; + + if (!$failed && $type ne "boot"){ + do_run_test or $failed = 1; + } + end_monitor; + return 0 if ($failed); + } $in_patchcheck = 0; success $i; @@ -821,6 +899,8 @@ foreach my $option (sort keys %opt) { doprint "$option = $opt{$option}\n"; } +$buildlog = "$opt{TMP_DIR}/buildlog"; +$dmesg = "$opt{TMP_DIR}/dmesg"; $make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}"; sub set_build_option { @@ -841,19 +921,18 @@ sub set_build_option { # First we need to do is the builds for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { - my $type = "BUILD_TYPE[$i]"; - - if (!defined($opt{$type})) { - $opt{$type} = $opt{"DEFAULT_BUILD_TYPE"}; - } + $build_type = set_build_option("BUILD_TYPE", $i); $noclean = set_build_option("BUILD_NOCLEAN", $i); $minconfig = set_build_option("MIN_CONFIG", $i); $run_test = set_build_option("TEST", $i); $addconfig = set_build_option("ADD_CONFIG", $i); doprint "\n\n"; - doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $opt{$type}\n\n"; + doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $build_type\n\n"; + + unlink $dmesg; + unlink $buildlog; if (!defined($minconfig)) { $minconfig = $addconfig; @@ -870,26 +949,30 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { die "failed to checkout $checkout"; } - if ($opt{$type} eq "bisect") { + if ($build_type eq "bisect") { bisect $i; next; - } elsif ($opt{$type} eq "patchcheck") { + } elsif ($build_type eq "patchcheck") { patchcheck $i; next; } - if ($opt{$type} ne "nobuild") { - build $opt{$type} or next; + if ($build_type ne "nobuild") { + build $build_type or next; } get_grub_index; get_version; install; - monitor or next; - if (defined($run_test)) { - do_run_test or next; + my $failed = 0; + start_monitor; + monitor or $failed = 1;; + if (!$failed && defined($run_test)) { + do_run_test or $failed = 1; } + end_monitor; + next if ($failed); success $i; } -- cgit v1.2.1