#! /usr/bin/perl # Find the directory that contains the grading files. our ($GRADES_DIR); # Add our Perl library directory to the include path. BEGIN { ($GRADES_DIR = $0) =~ s#/[^/]+$##; -d $GRADES_DIR or die "$GRADES_DIR: stat: $!\n"; unshift @INC, "$GRADES_DIR/../lib"; } use warnings; use strict; use Pintos::Grading; our ($hw) = "filesys"; our (@TESTS); # Tests to run. our ($test); our ($action); parse_cmd_line qw (sm-create sm-full sm-seq-block sm-seq-random sm-random lg-create lg-full lg-seq-block lg-seq-random lg-random grow-create grow-seq-sm grow-seq-lg grow-file-size grow-tell grow-sparse grow-too-big grow-root-sm grow-root-lg grow-dir-lg grow-two-files dir-mkdir dir-rmdir dir-mk-vine dir-rm-vine dir-mk-tree dir-rm-tree dir-lsdir dir-rm-cwd dir-rm-cwd-cd dir-rm-parent dir-rm-root dir-over-file dir-under-file dir-empty-name dir-open syn-remove syn-read syn-write syn-rw); clean_dir (), exit if $action eq 'clean'; extract_sources (); exit if $action eq 'extract'; build (); exit if $action eq 'build'; run_and_grade_tests (); write_grades (); write_details (); exit if $action eq 'test'; assemble_final_grade (); exit if $action eq 'assemble'; die "Don't know how to '$action'"; # Runs $test in directory output/$test. # Returns 'ok' if it went ok, otherwise an explanation. sub run_test { my ($result); my ($fs_size) = $test ne 'grow-too-big' ? 2 : .25; xsystem ("pintos make-disk output/$test/fs.dsk $fs_size >/dev/null 2>&1", DIE => "failed to create file system disk"); xsystem ("pintos make-disk output/$test/swap.dsk 2 >/dev/null 2>&1", DIE => "failed to create swap disk"); # Format disk, install test. my ($pintos_base_cmd) = "pintos " . "--os-disk=pintos/src/$hw/build/os.dsk " . "--fs-disk=output/$test/fs.dsk " . "--swap-disk=output/$test/swap.dsk " . "-v"; $result = run_pintos ("$pintos_base_cmd put -f $GRADES_DIR/$test $test", LOG => "$test/put", TIMEOUT => 60); return $result if $result ne 'ok'; my (@extra_files); push (@extra_files, "child-syn-read") if $test eq 'syn-read'; push (@extra_files, "child-syn-wrt") if $test eq 'syn-write'; push (@extra_files, "child-syn-rw") if $test eq 'syn-rw'; for my $fn (@extra_files) { $result = run_pintos ("$pintos_base_cmd put $GRADES_DIR/$fn $fn", LOG => "$test/put-$fn", TIMEOUT => 60); return "Error running `put $fn': $result" if $result ne 'ok'; } # Run. return run_pintos ("$pintos_base_cmd run -q -ex \"$test\"", LOG => "$test/run", TIMEOUT => 120); } sub grade_dir_lsdir { my (@output) = @_; verify_common (@output); @output = get_core_output (@output); my ($begin); for my $i (0...$#output) { $begin = $i, last if $output[$i] eq '(dir-lsdir) begin'; } die "\"(dir-lsdir) begin\" does not appear in output\n" if !defined $begin; my ($end); for my $i (0...$#output) { $end = $i, last if $output[$i] eq '(dir-lsdir) end'; } die "\"(dir-lsdir) end\" does not appear in output\n" if !defined $end; die "\"begin\" follows \"end\" in output\n" if $begin > $end; my (%count); for my $fn (@output[$begin + 1...$end - 1]) { $fn =~ s/\s+$//; die "Unexpected file \"$fn\" in lsdir output\n" unless grep ($_ eq $fn, qw (. .. dir-lsdir)); die "File \"$fn\" listed twice in lsdir output\n" if $count{$fn}; $count{$fn}++; } die "No files in lsdir output\n" if scalar (keys (%count)) == 0; die "File \"dir-lsdir\" missing from lsdir output\n" if !$count{"dir-lsdir"}; } # This should be improved, but none of the fall 2004 submissions # survived the test! # I suppose it could be a bug in the test but a lot of the submissions # had kernel panics, etc. sub grade_syn_rw { verify_common (@_); }