Fix syntax errors.
[pintos-anon] / grading / userprog / run-tests
1 #! /usr/bin/perl
2
3 # Find the directory that contains the grading files.
4 our ($GRADES_DIR);
5
6 # Add our Perl library directory to the include path. 
7 BEGIN {
8     ($GRADES_DIR = $0) =~ s#/[^/]+$##;
9     -d $GRADES_DIR or die "$GRADES_DIR: stat: $!\n";
10     unshift @INC, "$GRADES_DIR/../lib";
11 }
12
13 use warnings;
14 use strict;
15 use Pintos::Grading;
16
17 our ($hw) = "userprog";
18 our (@TESTS);           # Tests to run.
19 our ($test);
20 our (%extra);
21 our ($action);
22
23 parse_cmd_line qw (args-argc args-argv0 args-argvn args-single args-multiple
24                    args-dbl-space
25                    sc-bad-sp sc-bad-arg sc-boundary
26                    halt exit
27                    create-normal create-empty create-null create-bad-ptr 
28                    create-long create-exists create-bound
29                    open-normal open-missing open-boundary open-empty open-null
30                    open-bad-ptr open-twice
31                    close-normal close-twice close-stdin close-stdout
32                    close-bad-fd
33                    read-normal read-bad-ptr read-boundary read-zero read-stdout
34                    read-bad-fd
35                    write-normal write-bad-ptr write-boundary write-zero
36                    write-stdin write-bad-fd
37                    exec-once exec-arg exec-multiple exec-missing exec-bad-ptr
38                    join-simple join-twice join-killed join-bad-pid
39                    multi-recurse multi-oom multi-child-fd);
40
41 clean_dir (), exit if $action eq 'clean';
42
43 extract_sources (); 
44 exit if $action eq 'extract';
45
46 build (); 
47 exit if $action eq 'build';
48
49 run_and_grade_tests (); 
50 write_grades (); 
51 write_details ();
52 exit if $action eq 'test';
53
54 assemble_final_grade ();
55 exit if $action eq 'assemble';
56
57 die "Don't know how to '$action'";
58
59 # Runs $test in directory output/$test.
60 # Returns 'ok' if it went ok, otherwise an explanation.
61 sub run_test {
62     xsystem ("cp $GRADES_DIR/$test.dsk output/$test/fs.dsk",
63              DIE => "cp failed\n");
64
65     my ($args) = "";
66     $args = 'some arguments for you!'
67         if grep ($_ eq $test, qw(args-argc args-argv0
68                                  args-argvn args-multiple));
69     $args = 'onearg' if $test eq 'args-single';
70     $args = 'two  args' if $test eq 'args-dbl-space';
71     $args = '15' if $test eq 'multi-recurse';
72     $args = '0' if $test eq 'multi-oom';
73     $args = " $args" if $args ne '';
74
75     # Run.
76     my ($timeout) = $test !~ /^multi-/ ? 10 : 600;
77     my ($result) = run_pintos ("pintos "
78                                . "--os-disk=pintos/src/userprog/build/os.dsk "
79                                . "--fs-disk=output/$test/fs.dsk "
80                                . "-v run -q -ex \"$test$args\"",
81                                LOG => "$test/run",
82                                TIMEOUT => $timeout);
83     rename "output/$test/fs.dsk", "output/$test/fs.dsk.keep"
84         if $test eq 'write-normal';
85     return $result;
86 }
87 \f
88 sub grade_write_normal {
89     my (@output) = @_;
90     verify_common (@output);
91     compare_output ("$GRADES_DIR/write-normal.exp", @output);
92     my ($test_txt) = "output/$test/test.txt";
93     get_file ("test.txt", $test_txt) if ! -e $test_txt;
94
95     my (@actual) = snarf ($test_txt);
96     my (@expected) = snarf ("$GRADES_DIR/sample.txt");
97
98     my ($eq);
99     if ($#actual == $#expected) {
100         $eq = 1;
101         for my $i (0...$#actual) {
102             $eq = 0 if $actual[$i] ne $expected[$i];
103         }
104     } else {
105         $eq = 0;
106     }
107     if (!$eq) {
108         my ($details);
109         $details = "Expected file content:\n";
110         $details .= join ('', map ("  $_\n", @expected));
111         $details .= "Actual file content:\n";
112         $details .= join ('', map ("  $_\n", @actual));
113         $extra{$test} = $details;
114
115         die "File written didn't have expected content.\n";
116     }
117 }
118
119 sub grade_multi_oom {
120     my (@output) = @_;
121     verify_common (@output);
122
123     @output = canonicalize_exit_codes (get_core_output (@output));
124     my ($n) = 0;
125     while (my ($m) = $output[0] =~ /^\(multi-oom\) begin (\d+)$/) {
126         die "Child process $m started out of order.\n" if $m != $n;
127         $n = $m + 1;
128         shift @output;
129     }
130     die "Only $n child process(es) started.\n" if $n < 15;
131
132     # There could be a death notice for a process that didn't get
133     # fully loaded, and/or notices from the loader.
134     while (@output > 0
135            && ($output[0] =~ /^multi-oom: exit\(-1\)$/
136                || $output[0] =~ /^load: /)) {
137         shift @output;
138     }
139
140     while (--$n >= 0) {
141         die "Output ended unexpectedly before process $n finished.\n"
142             if @output < 2;
143
144         local ($_);
145         chomp ($_ = shift @output);
146         die "Found '$_' expecting 'end' message.\n" if !/^\(multi-oom\) end/;
147         die "Child process $n ended out of order.\n"
148             if !/^\(multi-oom\) end $n$/;
149
150         chomp ($_ = shift @output);
151         die "Kernel didn't print proper exit message for process $n.\n"
152             if !/^multi-oom: exit\($n\)$/;
153     }
154     die "Spurious output at end: '$output[0]'.\n" if @output;
155 }
156
157 sub get_file {
158     my ($guest_fn, $host_fn) = @_;
159     my ($result) = run_pintos ("pintos "
160                                . "--os-disk=pintos/src/userprog/build/os.dsk "
161                                . "--fs-disk=output/$test/fs.dsk.keep "
162                                . "-v get $guest_fn $host_fn",
163                                LOG => "$test/get-$guest_fn",
164                                TIMEOUT => 10,
165                                EXPECT => 0);
166     die "`pintos get $guest_fn' failed - $result\n"
167         if $result ne 'ok';
168 }