Work on userprog tests.
authorBen Pfaff <blp@cs.stanford.edu>
Fri, 29 Oct 2004 01:07:36 +0000 (01:07 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Fri, 29 Oct 2004 01:07:36 +0000 (01:07 +0000)
28 files changed:
grading/userprog/Makefile
grading/userprog/args-argc.c [new file with mode: 0644]
grading/userprog/args-argc.exp [new file with mode: 0644]
grading/userprog/args-argv0.c [new file with mode: 0644]
grading/userprog/args-argv0.exp [new file with mode: 0644]
grading/userprog/args-argvn.c [new file with mode: 0644]
grading/userprog/args-argvn.exp [new file with mode: 0644]
grading/userprog/args-dbl-space.c [new file with mode: 0644]
grading/userprog/args-dbl-space.exp [new file with mode: 0644]
grading/userprog/args-multiple.c [new file with mode: 0644]
grading/userprog/args-multiple.exp [new file with mode: 0644]
grading/userprog/args-single.c [new file with mode: 0644]
grading/userprog/args-single.exp [new file with mode: 0644]
grading/userprog/create-bad-ptr.c [new file with mode: 0644]
grading/userprog/create-bad-ptr.exp [new file with mode: 0644]
grading/userprog/create-bound.c [new file with mode: 0644]
grading/userprog/create-bound.exp [new file with mode: 0644]
grading/userprog/create-empty.exp
grading/userprog/create-empty.exp1 [deleted file]
grading/userprog/create-exists.c [new file with mode: 0644]
grading/userprog/create-exists.exp [new file with mode: 0644]
grading/userprog/create-invalid.c [deleted file]
grading/userprog/create-long.c
grading/userprog/create-long.exp [new file with mode: 0644]
grading/userprog/create-null.exp
grading/userprog/create-null.exp1 [deleted file]
grading/userprog/run-tests
grading/userprog/tests.txt

index f5917a689e3b3e690f58cc263e1bf1f30518e633..25ba85759b7e0bbfab6354f8f4eb72adbd67950b 100644 (file)
@@ -1,6 +1,8 @@
 SRCDIR = ../../src
 
-SINGLETONS = create-normal create-empty create-null create-invalid create-long 
+SINGLETONS = \
+       $(addprefix create-, normal empty null bad-ptr long exists bound) \
+       $(addprefix args-, argc argv0 argvn single multiple dbl-space)
 
 define SINGLETON_PROG
 PROGS += $(1)
@@ -25,3 +27,5 @@ clean::
        rm -f $(DISKS)
 
 include $(SRCDIR)/Makefile.userprog
+
+CFLAGS += -Werror
diff --git a/grading/userprog/args-argc.c b/grading/userprog/args-argc.c
new file mode 100644 (file)
index 0000000..863785d
--- /dev/null
@@ -0,0 +1,10 @@
+#include <debug.h>
+#include <stdio.h>
+#include <syscall.h>
+
+int
+main (int argc, char *argv[] UNUSED) 
+{
+  printf ("(args-argc) argc=%d\n", argc);
+  return 0;
+}
diff --git a/grading/userprog/args-argc.exp b/grading/userprog/args-argc.exp
new file mode 100644 (file)
index 0000000..e9d12a4
--- /dev/null
@@ -0,0 +1,2 @@
+(args-argc) argc=5
+args-argc: exit(0)
diff --git a/grading/userprog/args-argv0.c b/grading/userprog/args-argv0.c
new file mode 100644 (file)
index 0000000..9220d38
--- /dev/null
@@ -0,0 +1,10 @@
+#include <debug.h>
+#include <stdio.h>
+#include <syscall.h>
+
+int
+main (int argc UNUSED, char *argv[]) 
+{
+  printf ("(args-argv0) argv[0] = '%s'\n", argv[0]);
+  return 0;
+}
diff --git a/grading/userprog/args-argv0.exp b/grading/userprog/args-argv0.exp
new file mode 100644 (file)
index 0000000..c674f62
--- /dev/null
@@ -0,0 +1,2 @@
+(args-argv0) argv[0] = 'args-argv0'
+args-argv0: exit(0)
diff --git a/grading/userprog/args-argvn.c b/grading/userprog/args-argvn.c
new file mode 100644 (file)
index 0000000..061b31b
--- /dev/null
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include <syscall.h>
+
+int
+main (int argc, char *argv[]) 
+{
+  printf ("(args-argvn) argv[argc] = %p\n", argv[argc]);
+  return 0;
+}
diff --git a/grading/userprog/args-argvn.exp b/grading/userprog/args-argvn.exp
new file mode 100644 (file)
index 0000000..719173d
--- /dev/null
@@ -0,0 +1,2 @@
+(args-argvn) argv[argc] = 0x0
+args-argvn: exit(0)
diff --git a/grading/userprog/args-dbl-space.c b/grading/userprog/args-dbl-space.c
new file mode 100644 (file)
index 0000000..ef63912
--- /dev/null
@@ -0,0 +1,33 @@
+#include <stdio.h>
+#include <string.h>
+
+int
+main (int argc, char *argv[]) 
+{
+  int i;
+
+  for (i = 0; i < argc; i++)
+    {
+      int j;
+
+      for (j = i; j < i + 2; j++)
+        if (argv[j] == NULL)
+          goto error;
+      if (!strcmp (argv[i], "two")
+          && !strcmp (argv[i + 1], "args"))
+        {
+          printf ("(args-dbl-space) success\n");
+          return 0;
+        }
+    error:;
+    }
+  
+  printf ("(args-dbl-space) failure\n");
+  printf ("(args-dbl-space) argc=%d\n", argc);
+  for (i = 0; i <= argc; i++)
+    if (argv[i] >= (char *) 0xbffff000 && argv[i] < (char *) 0xc0000000)
+      printf ("(args-dbl-space) argv[%d]='%s'\n", i, argv[i]);
+    else
+      printf ("(args-dbl-space) argv[%d]=%p\n", i, argv[i]);
+  return 1;
+}
diff --git a/grading/userprog/args-dbl-space.exp b/grading/userprog/args-dbl-space.exp
new file mode 100644 (file)
index 0000000..531bddf
--- /dev/null
@@ -0,0 +1,2 @@
+(args-dbl-space) success
+args-dbl-space: exit(0)
diff --git a/grading/userprog/args-multiple.c b/grading/userprog/args-multiple.c
new file mode 100644 (file)
index 0000000..715deeb
--- /dev/null
@@ -0,0 +1,35 @@
+#include <stdio.h>
+#include <string.h>
+
+int
+main (int argc, char *argv[]) 
+{
+  int i;
+
+  for (i = 0; i < argc - 2; i++)
+    {
+      int j;
+
+      for (j = i; j < i + 4; j++)
+        if (argv[j] == NULL)
+          goto error;
+      if (!strcmp (argv[i], "some")
+          && !strcmp (argv[i + 1], "arguments")
+          && !strcmp (argv[i + 2], "for")
+          && !strcmp (argv[i + 3], "you!"))
+        {
+          printf ("(args-multiple) success\n");
+          return 0;
+        }
+    error:;
+    }
+  
+  printf ("(args-multiple) failure\n");
+  printf ("(args-multiple) argc=%d\n", argc);
+  for (i = 0; i <= argc; i++)
+    if (argv[i] >= (char *) 0xbffff000 && argv[i] < (char *) 0xc0000000)
+      printf ("(args-multiple) argv[%d]='%s'\n", i, argv[i]);
+    else
+      printf ("(args-multiple) argv[%d]=%p\n", i, argv[i]);
+  return 1;
+}
diff --git a/grading/userprog/args-multiple.exp b/grading/userprog/args-multiple.exp
new file mode 100644 (file)
index 0000000..538be6f
--- /dev/null
@@ -0,0 +1,2 @@
+(args-multiple) success
+args-multiple: exit(0)
diff --git a/grading/userprog/args-single.c b/grading/userprog/args-single.c
new file mode 100644 (file)
index 0000000..23e6ec2
--- /dev/null
@@ -0,0 +1,25 @@
+#include <stdio.h>
+#include <string.h>
+
+int
+main (int argc, char *argv[]) 
+{
+  if (!strcmp (argv[0], "onearg") || !strcmp (argv[1], "onearg")) 
+    {
+      printf ("(args-single) success\n");
+      return 0; 
+    }
+  else 
+    {
+      int i;
+
+      printf ("(args-single) failure\n");
+      printf ("(args-single) argc=%d\n", argc);
+      for (i = 0; i <= argc; i++)
+        if (argv[i] >= (char *) 0xbffff000 && argv[i] < (char *) 0xc0000000)
+          printf ("(args-single) argv[%d]='%s'\n", i, argv[i]);
+        else
+          printf ("(args-single) argv[%d]=%p\n", i, argv[i]);
+      return 1;
+    }
+}
diff --git a/grading/userprog/args-single.exp b/grading/userprog/args-single.exp
new file mode 100644 (file)
index 0000000..3a2d321
--- /dev/null
@@ -0,0 +1,2 @@
+(args-single) success
+args-single: exit(0)
diff --git a/grading/userprog/create-bad-ptr.c b/grading/userprog/create-bad-ptr.c
new file mode 100644 (file)
index 0000000..514234e
--- /dev/null
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include <syscall.h>
+
+int
+main (void) 
+{
+  printf ("(create-bad-ptr) begin\n");
+  create ((char *) 0xc0101234, 0);
+  printf ("(create-bad-ptr) end\n");
+  return 0;
+}
diff --git a/grading/userprog/create-bad-ptr.exp b/grading/userprog/create-bad-ptr.exp
new file mode 100644 (file)
index 0000000..ec8dad6
--- /dev/null
@@ -0,0 +1,6 @@
+(create-bad-ptr) begin
+(create-bad-ptr) end
+create-bad-ptr: exit(0)
+--OR--
+(create-bad-ptr) begin
+create-bad-ptr: exit(-1)
diff --git a/grading/userprog/create-bound.c b/grading/userprog/create-bound.c
new file mode 100644 (file)
index 0000000..4f240df
--- /dev/null
@@ -0,0 +1,23 @@
+#include <inttypes.h>
+#include <stdio.h>
+#include <string.h>
+#include <syscall.h>
+
+static char *
+mk_boundary_string (const char *src) 
+{
+  static char dst[8192];
+  char *p = dst + (4096 - (uintptr_t) dst % 4096 - strlen (src) / 2);
+  strlcpy (p, src, 4096);
+  return p;
+}
+
+int
+main (void) 
+{
+  printf ("(create-bound) begin\n");
+  printf ("(create-bound) create(): %d\n",
+          create (mk_boundary_string ("quux.dat"), 0));
+  printf ("(create-bound) end\n");
+  return 0;
+}
diff --git a/grading/userprog/create-bound.exp b/grading/userprog/create-bound.exp
new file mode 100644 (file)
index 0000000..0022477
--- /dev/null
@@ -0,0 +1,4 @@
+(create-bound) begin
+(create-bound) create(): 1
+(create-bound) end
+create-bound: exit(0)
index cba6c7ade0170890bf72b0ac449039f6b7e76b02..affc1f8443ea61aa84d73409e76d0f9699322205 100644 (file)
@@ -1,3 +1,6 @@
 (create-empty) begin
 (create-empty) end
 create-empty: exit(0)
+--OR--
+(create-empty) begin
+create-empty: exit(-1)
diff --git a/grading/userprog/create-empty.exp1 b/grading/userprog/create-empty.exp1
deleted file mode 100644 (file)
index aac55e4..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-(create-empty) begin
-create-empty: exit(-1)
diff --git a/grading/userprog/create-exists.c b/grading/userprog/create-exists.c
new file mode 100644 (file)
index 0000000..487804d
--- /dev/null
@@ -0,0 +1,16 @@
+#include <stdio.h>
+#include <syscall.h>
+
+int
+main (void) 
+{
+  printf ("(create-exists) begin\n");
+  printf ("(create-exists) create(\"quux.dat\"): %d\n",
+          create ("quux.dat", 0));
+  printf ("(create-exists) create(\"warble.dat\"): %d\n",
+          create ("warble.dat", 0));
+  printf ("(create-exists) create(\"quux.dat\"): %d\n",
+          create ("quux.dat", 0));
+  printf ("(create-exists) end\n");
+  return 0;
+}
diff --git a/grading/userprog/create-exists.exp b/grading/userprog/create-exists.exp
new file mode 100644 (file)
index 0000000..861381d
--- /dev/null
@@ -0,0 +1,6 @@
+(create-exists) begin
+(create-exists) create("quux.dat"): 1
+(create-exists) create("warble.dat"): 1
+(create-exists) create("quux.dat"): 0
+(create-exists) end
+create-exists: exit(0)
diff --git a/grading/userprog/create-invalid.c b/grading/userprog/create-invalid.c
deleted file mode 100644 (file)
index 3b2271b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-#include <stdio.h>
-#include <syscall.h>
-
-int
-main (void) 
-{
-  printf ("create(0xc0101234):\n");
-  printf ("%d\n", create ((char *) 0xc0101234, 0));
-  printf ("survived\n");
-  return 0;
-}
index 87f788bae9f4fdf826ec3394ef443137fba4b2b7..81ef5070f722ea5249f39f87ef5163f8dc3e9297 100644 (file)
@@ -9,9 +9,9 @@ main (void)
   memset (name, 'x', sizeof name);
   name[sizeof name - 1] = '\0';
   
-  printf ("create(\"%s\"):\n", name);
-  printf ("%d\n", create (name, 0));
-  printf ("survived\n");
+  printf ("(create-long) begin\n");
+  printf ("(create-long) create: %d\n", create (name, 0));
+  printf ("(create-long) end\n");
 
   return 0;
 }
diff --git a/grading/userprog/create-long.exp b/grading/userprog/create-long.exp
new file mode 100644 (file)
index 0000000..d1aae6d
--- /dev/null
@@ -0,0 +1,4 @@
+(create-long) begin
+(create-long) create: 0
+(create-long) end
+create-long: exit(0)
index 2250356a3c2bde1d33d2c71b0f4a63d2f8a3de4e..a853b05d525c8ab5de7fb50bf30db3fd656303c4 100644 (file)
@@ -1,3 +1,6 @@
 (create-null) begin
 (create-null) end
 create-null: exit(0)
+--OR--
+(create-null) begin
+create-null: exit(-1)
diff --git a/grading/userprog/create-null.exp1 b/grading/userprog/create-null.exp1
deleted file mode 100644 (file)
index 950d56f..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-(create-null) begin
-create-null: exit(-1)
index ddc5b6edcdf0be0a4b7786c2ac813cb514148b0f..e7a31acb5f06190369f9329b880a4e5623282da8 100755 (executable)
@@ -37,10 +37,19 @@ sub usage {
 }
 
 # Default set of tests.
-@TESTS = qw (create-normal create-empty create-null 
-            create-long)
+@TESTS = qw (create-normal create-empty create-null create-bad-ptr 
+            create-long create-exists create-bound
+            args-argc args-argv0 args-argvn args-single args-multiple
+            args-dbl-space)
     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) {
     open (OUT, ">grade.out") or die "grade.out: create: $!\n";
@@ -238,10 +247,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 +281,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 +555,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 +597,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 +615,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;
        }
index 1ba870e96eb1daa71d2ac4055a421dd756dc9805..fbebaac6db1b7857a50f0da2de038e95eaaa6a00 100644 (file)
@@ -4,14 +4,16 @@ CORRECTNESS [[total]]
 Argument passing
   -3 args-argc: argc is not set correctly
   -3 args-argv0: executable name not passed as argv[0]
+  -3 args-argvn: argv[argc] is not a null pointer
+  -3 args-single: passing single argument fails
   -3 args-multiple: passing multiple arguments fails
-  -3 args-dblspace: using multiple spaces between arguments fails
-Score: /12
+  -3 args-dbl-space: using multiple spaces between arguments fails
+Score: /18
 
 System calls
-  -3 syscall-bad-sp: system call with a bad stack pointer must not crash OS
-  -3 syscall-bad-arg: syscall with argument off top of stack must not crash OS
-  -3 syscall-boundary: syscall with args across page boundary must work
+  -3 sc-bad-sp: system call with a bad stack pointer must not crash OS
+  -3 sc-bad-arg: syscall with argument off top of stack must not crash OS
+  -3 sc-boundary: syscall with args across page boundary must work
 Score: /9
 
 System calls: halt, exec 
@@ -26,7 +28,7 @@ System calls: create
   -1 create-bad-ptr: pass invalid pointer to create system call
   -1 create-long: pass long file name to create system call
   -1 create-exists: pass name of an existing file to create system call
-  -1 create-boundary: pass name of file crossing page boundary
+  -1 create-bound: pass name of file crossing page boundary
 Score: /7
 
 System calls: open