Add more tests.
[pintos-anon] / grading / userprog / run-tests
index ddc5b6edcdf0be0a4b7786c2ac813cb514148b0f..37816499814230bb9aceba85fc9721b1e3d8acc4 100755 (executable)
@@ -37,9 +37,25 @@ sub usage {
 }
 
 # Default set of tests.
-@TESTS = qw (create-normal create-empty create-null 
-            create-long)
-    unless @TESTS > 0;
+@TESTS = qw (args-argc args-argv0 args-argvn args-single args-multiple
+            args-dbl-space
+            sc-bad-sp sc-bad-arg sc-boundary
+            halt exit
+            create-normal create-empty create-null create-bad-ptr 
+            create-long create-exists create-bound
+            open-normal open-missing open-boundary open-empty open-null
+            open-bad-ptr open-twice
+            close-normal close-twice close-stdin close-stdout close-bad-fd
+            read-normal read-bad-ptr read-boundary read-zero read-stdout
+            read-bad-fd
+            ) unless @TESTS > 0;
+
+our (%args);
+for my $key ('args-argc', 'args-argv0', 'args-argvn', 'args-multiple') {
+    $args{$key} = "some arguments for you!";
+}
+$args{'args-single'} = "onearg";
+$args{'args-dbl-space'} = "two  args";
 
 # Handle final grade mode.
 if ($grade) {
@@ -238,10 +254,11 @@ sub really_run_test {
 
     # Run.
     my ($timeout) = 10;
+    my ($testargs) = defined ($args{$test}) ? " $args{$test}" : "";
     xsystem ("pintos "
             . "--os-disk=pintos/src/userprog/build/os.dsk "
             . "--fs-disk=output/$test/fs.dsk "
-            . "-v run -q -ex \"$test\"",
+            . "-v run -q -ex \"$test$testargs\"",
             LOG => "$test/run",
             TIMEOUT => $timeout)
        or return "Bochs error";
@@ -271,13 +288,6 @@ sub grade_test {
     return "ok";
 }
 \f
-sub grade_create_empty {
-    my (@output) = @_;
-    verify_common (@_);
-    compare_output (["(create-empty) begin"], @output);
-    
-}
-
 sub grade_alarm_multiple {
     verify_alarm (7, @_);
 }
@@ -552,40 +562,40 @@ sub verify_common {
        if !grep (/Powering off/, @output);
 }
 
-sub eq_lines {
-    my ($actual, $expected) = @_;
-    return $actual eq $expected;
-}
-
-sub compare_output {
-    my ($exp, @actual) = @_;
-    @actual = map ("$_\n", @actual);
+# Get @output without header or trailer.
+sub get_core_output {
+    my (@output) = @_;
 
-    # Trim header and trailer from @actual.
     our ($test);
     my ($first);
-    for ($first = 0; $first <= $#actual; $first++) {
-       $first++, last if $actual[$first] =~ /^Executing '$test':$/;
+    for ($first = 0; $first <= $#output; $first++) {
+       $first++, last if $output[$first] =~ /^Executing '$test.*':$/;
     }
 
     my ($last);
-    for ($last = $#actual; $last >= 0; $last--) {
-       $last--, last if $actual[$last] =~ /^Timer: \d+ ticks$/;
+    for ($last = $#output; $last >= 0; $last--) {
+       $last--, last if $output[$last] =~ /^Timer: \d+ ticks$/;
     }
 
     if ($last < $first) {
-       my ($no_first) = $first > $#actual;
-       my ($no_last) = $last < $#actual;
+       my ($no_first) = $first > $#output;
+       my ($no_last) = $last < $#output;
        die "Couldn't locate output.\n";
     }
 
-    @actual = @actual[$first ... $last];
+    return @output[$first ... $last];
+}
+
+sub compare_output {
+    my ($exp, @actual) = @_;
+    @actual = get_core_output (map ("$_\n", @actual));
 
     # Fix up lines that look like exit codes.
     for my $i (0...$#actual) {
        if (my ($process, $code)
            = $actual[$i] =~ /^([-a-zA-Z0-9 ]+):.*[ \(](-?\d+)\b\)?$/) {
            $process = substr ($process, 0, 15);
+           $process =~ s/\s.*//;
            $actual[$i] = "$process: exit($code)\n";
        }
     }
@@ -594,15 +604,16 @@ sub compare_output {
     $details .= "$test actual output:\n";
     $details .= join ('', map ("  $_", @actual));
 
+    my (@exp) = map ("$_\n", snarf ($exp));
+
     my ($fuzzy_match) = 0;
-    for (my ($i) = 0; ; $i++) {
-       my ($fn) = $exp;
-       $fn .= $i if $i;
-       if (! -e $fn) {
-           die "$exp: stat: $!\n" if !$i;
-           last;
+    while (@exp != 0) {
+       my (@expected);
+       while (@exp != 0) {
+           my ($s) = shift (@exp);
+           last if $s eq "--OR--\n";
+           push (@expected, $s);
        }
-       my (@expected) = map ("$_\n", snarf ($fn));
 
        $details .= "\n$test acceptable output:\n";
        $details .= join ('', map ("  $_", @expected));
@@ -611,7 +622,7 @@ sub compare_output {
        if ($#actual == $#expected) {
            my ($eq) = 1;
            for (my ($i) = 0; $i <= $#expected; $i++) {
-               $eq = 0 if !eq_lines ($actual[$i], $expected[$i]);
+               $eq = 0 if $actual[$i] ne $expected[$i];
            }
            return if $eq;
        }
@@ -619,7 +630,7 @@ sub compare_output {
        # They differ.  Output a diff.
        my (@diff) = "";
        my ($d) = Algorithm::Diff->new (\@expected, \@actual);
-       my ($all_additions) = 1;
+       my ($not_fuzzy_match) = 0;
        while ($d->Next ()) {
            my ($ef, $el, $af, $al) = $d->Get (qw (min1 max1 min2 max2));
            if ($d->Same ()) {
@@ -627,11 +638,13 @@ sub compare_output {
            } else {
                push (@diff, map ("- $_", $d->Items (1))) if $d->Items (1);
                push (@diff, map ("+ $_", $d->Items (2))) if $d->Items (2);
-               $all_additions = 0 if $d->Items (1);
+               if ($d->Items (1)
+                   || grep (/\($test\)|exit\(-?\d+\)/, $d->Items (2))) {
+                   $not_fuzzy_match = 1;
+               }
            }
        }
-
-       $fuzzy_match = 1 if $all_additions;
+       $fuzzy_match = 1 if !$not_fuzzy_match;
 
        $details .= "Differences in `diff -u' format:\n";
        $details .= join ('', @diff);