From: Ben Pfaff Date: Fri, 29 Oct 2004 01:07:36 +0000 (+0000) Subject: Work on userprog tests. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=68cfbad945e00d12f3ac8f0fa33664ad2caa0eee;p=pintos-anon Work on userprog tests. --- diff --git a/grading/userprog/Makefile b/grading/userprog/Makefile index f5917a6..25ba857 100644 --- a/grading/userprog/Makefile +++ b/grading/userprog/Makefile @@ -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 index 0000000..863785d --- /dev/null +++ b/grading/userprog/args-argc.c @@ -0,0 +1,10 @@ +#include +#include +#include + +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 index 0000000..e9d12a4 --- /dev/null +++ b/grading/userprog/args-argc.exp @@ -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 index 0000000..9220d38 --- /dev/null +++ b/grading/userprog/args-argv0.c @@ -0,0 +1,10 @@ +#include +#include +#include + +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 index 0000000..c674f62 --- /dev/null +++ b/grading/userprog/args-argv0.exp @@ -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 index 0000000..061b31b --- /dev/null +++ b/grading/userprog/args-argvn.c @@ -0,0 +1,9 @@ +#include +#include + +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 index 0000000..719173d --- /dev/null +++ b/grading/userprog/args-argvn.exp @@ -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 index 0000000..ef63912 --- /dev/null +++ b/grading/userprog/args-dbl-space.c @@ -0,0 +1,33 @@ +#include +#include + +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 index 0000000..531bddf --- /dev/null +++ b/grading/userprog/args-dbl-space.exp @@ -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 index 0000000..715deeb --- /dev/null +++ b/grading/userprog/args-multiple.c @@ -0,0 +1,35 @@ +#include +#include + +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 index 0000000..538be6f --- /dev/null +++ b/grading/userprog/args-multiple.exp @@ -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 index 0000000..23e6ec2 --- /dev/null +++ b/grading/userprog/args-single.c @@ -0,0 +1,25 @@ +#include +#include + +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 index 0000000..3a2d321 --- /dev/null +++ b/grading/userprog/args-single.exp @@ -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 index 0000000..514234e --- /dev/null +++ b/grading/userprog/create-bad-ptr.c @@ -0,0 +1,11 @@ +#include +#include + +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 index 0000000..ec8dad6 --- /dev/null +++ b/grading/userprog/create-bad-ptr.exp @@ -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 index 0000000..4f240df --- /dev/null +++ b/grading/userprog/create-bound.c @@ -0,0 +1,23 @@ +#include +#include +#include +#include + +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 index 0000000..0022477 --- /dev/null +++ b/grading/userprog/create-bound.exp @@ -0,0 +1,4 @@ +(create-bound) begin +(create-bound) create(): 1 +(create-bound) end +create-bound: exit(0) diff --git a/grading/userprog/create-empty.exp b/grading/userprog/create-empty.exp index cba6c7a..affc1f8 100644 --- a/grading/userprog/create-empty.exp +++ b/grading/userprog/create-empty.exp @@ -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 index aac55e4..0000000 --- a/grading/userprog/create-empty.exp1 +++ /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 index 0000000..487804d --- /dev/null +++ b/grading/userprog/create-exists.c @@ -0,0 +1,16 @@ +#include +#include + +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 index 0000000..861381d --- /dev/null +++ b/grading/userprog/create-exists.exp @@ -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 index 3b2271b..0000000 --- a/grading/userprog/create-invalid.c +++ /dev/null @@ -1,11 +0,0 @@ -#include -#include - -int -main (void) -{ - printf ("create(0xc0101234):\n"); - printf ("%d\n", create ((char *) 0xc0101234, 0)); - printf ("survived\n"); - return 0; -} diff --git a/grading/userprog/create-long.c b/grading/userprog/create-long.c index 87f788b..81ef507 100644 --- a/grading/userprog/create-long.c +++ b/grading/userprog/create-long.c @@ -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 index 0000000..d1aae6d --- /dev/null +++ b/grading/userprog/create-long.exp @@ -0,0 +1,4 @@ +(create-long) begin +(create-long) create: 0 +(create-long) end +create-long: exit(0) diff --git a/grading/userprog/create-null.exp b/grading/userprog/create-null.exp index 2250356..a853b05 100644 --- a/grading/userprog/create-null.exp +++ b/grading/userprog/create-null.exp @@ -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 index 950d56f..0000000 --- a/grading/userprog/create-null.exp1 +++ /dev/null @@ -1,2 +0,0 @@ -(create-null) begin -create-null: exit(-1) diff --git a/grading/userprog/run-tests b/grading/userprog/run-tests index ddc5b6e..e7a31ac 100755 --- a/grading/userprog/run-tests +++ b/grading/userprog/run-tests @@ -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"; } -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; } diff --git a/grading/userprog/tests.txt b/grading/userprog/tests.txt index 1ba870e..fbebaac 100644 --- a/grading/userprog/tests.txt +++ b/grading/userprog/tests.txt @@ -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