X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=grading%2Fvm%2Frun-tests;h=f74bd9978aaec241878ce68cb59c5f473035ccdd;hb=83fc2d89cf608ee9395b853c0628fc684c6f250e;hp=85164aa28bbdc94fa8a072c929d22d943484b15d;hpb=892590a6b5883b307fe6b3c15c91a9c1d9c014db;p=pintos-anon diff --git a/grading/vm/run-tests b/grading/vm/run-tests index 85164aa..f74bd99 100755 --- a/grading/vm/run-tests +++ b/grading/vm/run-tests @@ -1,5 +1,14 @@ #! /usr/bin/perl +# Find the directory that contains the grading files. +our ($GRADES_DIR); + +BEGIN { + ($GRADES_DIR = $0) =~ s#/[^/]+$##; + -d $GRADES_DIR or die "$GRADES_DIR: stat: $!\n"; + unshift @INC, "$GRADES_DIR/../lib"; +} + use warnings; use strict; use POSIX; @@ -97,11 +106,6 @@ if ($grade) { exit 0; } -# Find the directory that contains the grading files. -our ($GRADES_DIR); -($GRADES_DIR = $0) =~ s#/[^/]+$##; --d $GRADES_DIR or die "$GRADES_DIR: stat: $!\n"; - if ($clean) { # Verify that we're roughly in the correct directory # before we go blasting away files. @@ -294,86 +298,30 @@ sub grade_test { return "ok"; } -sub grade_write_normal { - my (@output) = @_; - verify_common (@output); - compare_output ("$GRADES_DIR/write-normal.exp", @output); - my ($test_txt) = "output/$test/test.txt"; - get_file ("test.txt", $test_txt) if ! -e $test_txt; - - my (@actual) = snarf ($test_txt); - my (@expected) = snarf ("$GRADES_DIR/sample.txt"); - - my ($eq); - if ($#actual == $#expected) { - $eq = 1; - for my $i (0...$#actual) { - $eq = 0 if $actual[$i] ne $expected[$i]; - } - } else { - $eq = 0; - } - if (!$eq) { - my ($details); - $details = "Expected file content:\n"; - $details .= join ('', map (" $_\n", @expected)); - $details .= "Actual file content:\n"; - $details .= join ('', map (" $_\n", @actual)); - $extra{$test} = $details; +sub grade_process_death { + my ($proc_name, @output) = @_; - die "File written didn't have expected content.\n"; - } -} - -sub grade_multi_oom { - my (@output) = @_; verify_common (@output); + @output = get_core_output (@output); + die "First line of output is not `($proc_name) begin' message.\n" + if $output[0] ne "($proc_name) begin"; + die "Output contains `FAIL' message.\n" + if grep (/FAIL/, @output); + die "Output contains spurious ($proc_name) message.\n" + if grep (/\($proc_name\)/, @output) > 1; +} - @output = fix_exit_codes (get_core_output (@output)); - my ($n) = 0; - while (my ($m) = $output[0] =~ /^\(multi-oom\) begin (\d+)$/) { - die "Child process $m started out of order.\n" if $m != $n; - $n = $m + 1; - shift @output; - } - die "Only $n child process(es) started.\n" if $n < 15; - - # There could be a death notice for a process that didn't get - # fully loaded, and/or notices from the loader. - while (@output > 0 - && ($output[0] =~ /^multi-oom: exit\(-1\)$/ - || $output[0] =~ /^load: /)) { - shift @output; - } - - while (--$n >= 0) { - die "Output ended unexpectedly before process $n finished.\n" - if @output < 2; - - local ($_); - chomp ($_ = shift @output); - die "Found '$_' expecting 'end' message.\n" if !/^\(multi-oom\) end/; - die "Child process $n ended out of order.\n" - if !/^\(multi-oom\) end $n$/; - - chomp ($_ = shift @output); - die "Kernel didn't print proper exit message for process $n.\n" - if !/^multi-oom: exit\($n\)$/; - } - die "Spurious output at end: '$output[0]'.\n" if @output; +sub grade_pt_bad_addr { + grade_process_death ('pt-bad-addr', @_); } -sub get_file { - my ($guest_fn, $host_fn) = @_; - xsystem ("pintos " - . "--os-disk=pintos/src/vm/build/os.dsk " - . "--fs-disk=output/$test/fs.dsk " - . "-v get $guest_fn $host_fn", - LOG => "$test/get-$guest_fn", - TIMEOUT => 10) - or die "get $guest_fn failed\n"; +sub grade_pt_write_code { + grade_process_death ('pt-write-code', @_); } +sub grade_mmap_unmap { + grade_process_death ('mmap-unmap', @_); +} sub verify_common { my (@output) = @_; @@ -694,25 +642,34 @@ sub xsystem { $status = $?; alarm 0; }; + + my ($ok); if ($@) { die unless $@ eq "alarm\n"; # propagate unexpected errors - print "Timed out $pid.\n"; - kill ('SIGTERM', $pid); - $status = 0; - } + print "Timed out: "; + for (my ($i) = 0; $i < 10; $i++) { + kill ('SIGTERM', $pid); + sleep (1); + my ($retval) = waitpid ($pid, WNOHANG); + last if $retval == $pid || $retval == -1; + print "Waiting for $pid to die" if $i == 0; + print "."; + } + $ok = 1; + } else { + if (WIFSIGNALED ($status)) { + my ($signal) = WTERMSIG ($status); + die "Interrupted\n" if $signal == SIGINT; + print "Child terminated with signal $signal\n"; + } - if (WIFSIGNALED ($status)) { - my ($signal) = WTERMSIG ($status); - die "Interrupted\n" if $signal == SIGINT; - print "Child terminated with signal $signal\n"; + my ($exp_status) = !defined ($options{EXPECT}) ? 0 : $options{EXPECT}; + $ok = WIFEXITED ($status) && WEXITSTATUS ($status) == $exp_status; } - my ($expected_exit) = !defined ($options{EXPECT}) ? 0 : $options{EXPECT}; - my ($ok) = WIFEXITED ($status) && WEXITSTATUS ($status) == $expected_exit; - unlink ("output/$log.err") if defined ($log) && $ok; - die $options{DIE} if $status != 0 && defined $options{DIE}; + die $options{DIE} if !$ok && defined $options{DIE}; return $ok; }