Update point values.
[pintos-anon] / grading / userprog / run-tests
index e2587c20a44e2f6ddf2fb8dce94d5910b1e2ccab..dd7cd218b901d2e0fc889f4fe6916aa2e280f255 100755 (executable)
@@ -51,6 +51,7 @@ sub usage {
             write-normal write-bad-ptr write-boundary write-zero write-stdin
             write-bad-fd
             exec-once exec-arg exec-multiple exec-missing exec-bad-ptr
+            join-simple join-twice join-killed join-bad-pid
             multi-recurse multi-oom multi-child-fd
             ) unless @TESTS > 0;
 
@@ -188,6 +189,11 @@ sub extract_tarball {
     xsystem ("cd pintos/src && tar xzf ../../$tarball",
             DIE => "extraction failed\n");
 
+    if (-e "fixme.sh") {
+       print "Running fixme.sh...\n";
+       xsystem ("sh -e fixme.sh", DIE => "fix script failed\n");
+    }
+
     print "Patching...\n";
     xsystem ("patch -fs pintos/src/lib/debug.c < $GRADES_DIR/panic.diff",
             LOG => "patch",
@@ -269,7 +275,7 @@ sub really_run_test {
 
     # Run.
     my ($timeout) = 10;
-    $timeout = 60 if $test eq 'multi-oom';
+    $timeout = 600 if $test =~ /^multi-/;
     my ($testargs) = defined ($args{$test}) ? " $args{$test}" : "";
     xsystem ("pintos "
             . "--os-disk=pintos/src/userprog/build/os.dsk "
@@ -346,17 +352,29 @@ sub grade_multi_oom {
        $n = $m + 1;
        shift @output;
     }
-    die "Only $n child processes started.\n" if $n < 15;
+    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 $output[0] !~ /^\(multi-oom\) end $n$/;
-       shift @output;
+           if !/^\(multi-oom\) end $n$/;
 
-       die "Child process $n didn't print proper exit message.\n"
-           if $output[0] !~ /^multi-oom: exit\($n\)$/;
-       shift @output;
+       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;
 }
@@ -407,6 +425,25 @@ sub verify_common {
        die "Kernel panic.  Details at end of file.\n"
     }
 
+    if (grep (/Pintos booting/, @output) > 1) {
+       my ($details);
+
+       $details = "Pintos spontaneously rebooted during this test.\n";
+       $details .= "This is most often due to unhandled page faults.\n";
+       $details .= "Here's the output from the initial boot through the\n";
+       $details .= "first reboot:\n\n";
+
+       my ($i) = 0;
+       local ($_);
+       for (@output) {
+           $details .= "  $_\n";
+           last if /Pintos booting/ && ++$i > 1;
+       }
+       $details{$test} = $details;
+       die "Triple-fault caused spontaneous reboot(s).  "
+           . "Details at end of file.\n";
+    }
+
     die "No output at all\n" if @output == 0;
     die "Didn't start up properly: no \"Pintos booting\" startup message\n"
        if !grep (/Pintos booting with.*kB RAM\.\.\./, @output);
@@ -446,9 +483,18 @@ sub fix_exit_codes {
     my (@output) = @_;
 
     # Fix up lines that look like exit codes.
+    # Exit codes are supposed to be printed in the form "process: exit(code)"
+    # but people get unfortunately creative with it.
     for my $i (0...$#output) {
-       if (my ($process, $code)
-           = $output[$i] =~ /^([-a-zA-Z0-9 ]+):.*[ \(](-?\d+)\b\)?$/) {
+       local ($_) = $output[$i];
+       
+       my ($process, $code);
+       if ((($process, $code) = /^([-a-zA-Z0-9 ]+):.*[ \(](-?\d+)\b\)?$/)
+           || (($process, $code) = /^([-a-zA-Z0-9 ]+) exit\((-?\d+)\)$/)
+           || (($process, $code)
+               = /^([-a-zA-Z0-9 ]+) \(.*\): exit\((-?\d+)\)$/)
+           || (($process, $code) = /^([-a-zA-Z0-9 ]+):\( (-?\d+) \) $/)
+) {
            $process = substr ($process, 0, 15);
            $process =~ s/\s.*//;
            $output[$i] = "$process: exit($code)\n";
@@ -510,7 +556,22 @@ sub compare_output {
 
        $details .= "Differences in `diff -u' format:\n";
        $details .= join ('', @diff);
-       $details .= "(This is considered a `fuzzy match'.)\n" if $fuzzy_match;
+       $details .= "(This is considered a `fuzzy match'.)\n"
+           if !$not_fuzzy_match;
+    }
+
+    if ($fuzzy_match) {
+       $details =
+           "This test passed, but with extra, unexpected output.\n"
+           . "Please inspect your code to make sure that it does not\n"
+           . "produce output other than as specified in the project\n"
+           . "description.\n\n"
+           . "$details";
+    } else {
+       $details =
+           "This test failed because its output did not match any\n"
+           . "of the acceptable form(s).\n\n"
+           . "$details";
     }
 
     $details{$test} = $details;
@@ -524,14 +585,26 @@ sub write_grades {
     my ($ploss) = 0;
     my ($tloss) = 0;
     my ($total) = 0;
+    my ($warnings) = 0;
     for (my ($i) = 0; $i <= $#summary; $i++) {
        local ($_) = $summary[$i];
        if (my ($loss, $test) = /^  -(\d+) ([-a-zA-Z0-9]+):/) {
            my ($result) = $result{$test} || "Not tested.";
 
            if ($result eq 'ok') {
-               splice (@summary, $i, 1);
-               $i--;
+               if (!defined $details{$test}) {
+                   # Test successful and no warnings.
+                   splice (@summary, $i, 1);
+                   $i--;
+               } else {
+                   # Test successful with warnings.
+                   s/-(\d+) //;
+                   $summary[$i] = $_;
+                   splice (@summary, $i + 1, 0,
+                           "    Test passed with warnings.  "
+                           . "Details at end of file.");
+                   $warnings++;
+               } 
            } else {
                $ploss += $loss;
                $tloss += $loss;
@@ -541,8 +614,10 @@ sub write_grades {
        } elsif (my ($ptotal) = /^Score: \/(\d+)$/) {
            $total += $ptotal;
            $summary[$i] = "Score: " . ($ptotal - $ploss) . "/$ptotal";
-           splice (@summary, $i, 0, "  All tests passed.") if $ploss == 0;
+           splice (@summary, $i, 0, "  All tests passed.")
+               if $ploss == 0 && !$warnings;
            $ploss = 0;
+           $warnings = 0;
            $i++;
        }
     }
@@ -563,8 +638,15 @@ sub write_details {
        my ($details) = $details{$test};
        next if !defined ($details) && ! -e "output/$test/run.out";
 
+       my ($banner);
+       if ($result{$test} ne 'ok') {
+           $banner = "$test failure details"; 
+       } else {
+           $banner = "$test warnings";
+       }
+
        print DETAILS "\n" if $n++;
-       print DETAILS "--- $test details ", '-' x (50 - length ($test));
+       print DETAILS "--- $banner ", '-' x (50 - length ($banner));
        print DETAILS "\n\n";
 
        if (!defined $details) {