From: Ben Pfaff Date: Sat, 27 May 2006 00:06:54 +0000 (+0000) Subject: Add file system persistence tests: X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ef3fb564a37566ab3eca293e279ce441a78e85e5;p=pintos-anon Add file system persistence tests: Change Make.tests to invoke pintos a second time for the extended filesys tests, and in that run to tar up the file system contents and copy it out. Update grading scripts to check the generated tarballs. Update documentation. Update documented requirements for remove() of a directory to give basically the options offered by POSIX, and update the tests to check for these behaviors. Remove dir-lsdir test, which no longer made sense given that readdir is used so heavily in other tests. Merge dir-mk-vine and dir-rm-vine tests into a single dir-vine test, which is now much more stringent. Merge dir-rm-cwd-cd and dir-rm-cwd into a single dir-rm-cwd test, which is now much more stringent. Check that a non-empty directory cannot be removed. Update scoring rubrics. --- diff --git a/TODO b/TODO index 68837f7..463cb88 100644 --- a/TODO +++ b/TODO @@ -224,18 +224,17 @@ (Perhaps we should count disk reads and writes, not time.) - - Do we check that non-empty directories cannot be removed? - - Need lots more tests. - - Add FS persistence test(s). - - Detect implementations that represent the cwd as a string, by removing a directory that is the cwd of another process, then creating a new directory of the same name and putting some files in it, then checking whether the process that had it as cwd sees them. + - dir-rm-cwd should have a related test that uses a separate process + to try to pin the directory as its cwd. + - Godmar: I'm not sure if I mentioned that already, but I passed all tests for the filesys project without having implemented inode deallocation. A test is needed that checks that blocks are diff --git a/doc/filesys.texi b/doc/filesys.texi index a93481c..db4d948 100644 --- a/doc/filesys.texi +++ b/doc/filesys.texi @@ -25,6 +25,7 @@ to 5% extra credit if you do enable VM. @menu * File System New Code:: +* Testing File System Persistence:: @end menu @node File System New Code @@ -78,6 +79,35 @@ which you will remove. While most of your work will be in @file{filesys}, you should be prepared for interactions with all previous parts. +@node Testing File System Persistence +@subsection Testing File System Persistence + +By now, you should be familiar with the basic process of running the +Pintos tests. @xref{Testing}, for review, if necessary. + +Until now, each test invoked Pintos just once. However, an important +purpose of a file system is to ensure that data remains accessible from +one boot to another. Thus, the tests that are part of the file system +project invoke Pintos a second time. The second run combines all the +files and directories in the file system into a single file, then copies +that file out of the Pintos file system into the host (Unix) file +system. + +The grading scripts check the file system's correctness based on the +contents of the file copied out in the second run. This means that your +project will not pass any of the extended file system tests until the +file system is implemented well enough to support @program{tar}, the +Pintos user program that produces the file that is copied out. The +@program{tar} program is fairly demanding (it requires both extensible +file and subdirectory support), so this will take some work. Until +then, you can ignore errors from @command{make check} regarding the +extracted file system. + +Incidentally, as you may have surmised, the file format used for copying +out the file system contents is the standard Unix ``tar'' format. You +can use the Unix @command{tar} program to examine them. The tar file +for test @var{t} is named @file{@var{t}.tar}. + @node Project 4 Requirements @section Requirements @@ -175,15 +205,19 @@ The directory separator character is forward slash (@samp{/}). You must also support special file names @file{.} and @file{..}, which have the same meanings as they do in Unix. -Update the @code{remove} system call so that it can delete empty -directories in addition to regular files. Directories may only be -deleted if they do not contain any files or subdirectories (other than -@file{.} and @file{..}). - Update the @code{open} system call so that it can also open directories. Of the existing system calls, only @code{close} needs to accept a file descriptor for a directory. +Update the @code{remove} system call so that it can delete empty +directories (other than the root) in addition to regular files. +Directories may only be deleted if they do not contain any files or +subdirectories (other than @file{.} and @file{..}). You may decide +whether to allow deletion of a directory that is open by a process or in +use as a process's current working directory. If it is allowed, then +attempts to open files (including @file{.} and @file{..}) or create new +files in a deleted directory must be disallowed. + Implement the following new system calls: @deftypefn {System Call} bool chdir (const char *@var{dir}) diff --git a/src/tests/Make.tests b/src/tests/Make.tests index 9cb992b..b98a75d 100644 --- a/src/tests/Make.tests +++ b/src/tests/Make.tests @@ -5,19 +5,16 @@ include $(patsubst %,$(SRCDIR)/%/Make.tests,$(TEST_SUBDIRS)) PROGS = $(foreach subdir,$(TEST_SUBDIRS),$($(subdir)_PROGS)) TESTS = $(foreach subdir,$(TEST_SUBDIRS),$($(subdir)_TESTS)) -include ../../Makefile.userprog - -TIMEOUT = 60 -PINTOSFLAGS += -v -T $(TIMEOUT) \ - $(foreach file,$(PUTFILES),-p $(file) -a $(notdir $(file))) -KERNELFLAGS += -q - -PINTOS = pintos $(SIMULATOR) $(PINTOSOPTS) $(PINTOSFLAGS) -- $(KERNELFLAGS) - OUTPUTS = $(addsuffix .output,$(TESTS)) ERRORS = $(addsuffix .errors,$(TESTS)) RESULTS = $(addsuffix .result,$(TESTS)) +ifdef PROGS +include ../../Makefile.userprog +endif + +TIMEOUT = 60 + clean:: rm -f $(OUTPUTS) $(ERRORS) $(RESULTS) @@ -48,11 +45,27 @@ outputs:: $(OUTPUTS) $(foreach prog,$(PROGS),$(eval $(prog).output: $(prog))) $(foreach test,$(TESTS),$(eval $(test).output: $($(test)_PUTFILES))) -tests/%.output: RUNCMD = $(if $($*_ARGS),run '$(*F) $($*_ARGS)',run $(*F)) -tests/%.output: RUNREDIR = 2>$*.errors $(if $(VERBOSE),|tee,>) $*.output -tests/%.output: RUNTEST = $(PINTOS) $(RUNCMD) $(RUNREDIR) +$(foreach test,$(TESTS),$(eval $(test).output: TEST = $(test))) + +TESTCMD = pintos -v -T $(TIMEOUT) +TESTCMD += $(SIMULATOR) +TESTCMD += $(PINTOSOPTS) +ifeq ($(filter userprog, $(KERNEL_SUBDIRS)), userprog) +TESTCMD += --fs-disk=$(FSDISK) +TESTCMD += $(foreach file,$(PUTFILES),-p $(file) -a $(notdir $(file))) +endif +ifeq ($(filter vm, $(KERNEL_SUBDIRS)), vm) +TESTCMD += --swap-disk=4 +endif +TESTCMD += -- -q +TESTCMD += $(KERNELFLAGS) +ifeq ($(filter userprog, $(KERNEL_SUBDIRS)), userprog) +TESTCMD += -f +endif +TESTCMD += $(if $($(TEST)_ARGS),run '$(*F) $($(TEST)_ARGS)',run $(*F)) +TESTCMD += 2> $(TEST).errors $(if $(VERBOSE),|tee,>) $(TEST).output %.output: os.dsk - $(RUNTEST) + $(TESTCMD) %.result: %.ck %.output perl -I$(SRCDIR) $< $* $@ diff --git a/src/tests/filesys/base/lg-create.ck b/src/tests/filesys/base/lg-create.ck index 10f3097..86b2c51 100644 --- a/src/tests/filesys/base/lg-create.ck +++ b/src/tests/filesys/base/lg-create.ck @@ -10,3 +10,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (lg-create) close "blargle" (lg-create) end EOF +pass; diff --git a/src/tests/filesys/base/lg-full.ck b/src/tests/filesys/base/lg-full.ck index a380594..ee6c7f9 100644 --- a/src/tests/filesys/base/lg-full.ck +++ b/src/tests/filesys/base/lg-full.ck @@ -13,3 +13,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (lg-full) close "quux" (lg-full) end EOF +pass; diff --git a/src/tests/filesys/base/lg-random.ck b/src/tests/filesys/base/lg-random.ck index 4d6d752..dd9f1dd 100644 --- a/src/tests/filesys/base/lg-random.ck +++ b/src/tests/filesys/base/lg-random.ck @@ -11,3 +11,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (lg-random) close "bazzle" (lg-random) end EOF +pass; diff --git a/src/tests/filesys/base/lg-seq-block.ck b/src/tests/filesys/base/lg-seq-block.ck index 8c979c7..b789081 100644 --- a/src/tests/filesys/base/lg-seq-block.ck +++ b/src/tests/filesys/base/lg-seq-block.ck @@ -13,3 +13,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (lg-seq-block) close "noodle" (lg-seq-block) end EOF +pass; diff --git a/src/tests/filesys/base/lg-seq-random.ck b/src/tests/filesys/base/lg-seq-random.ck index 56fd998..6b2dc82 100644 --- a/src/tests/filesys/base/lg-seq-random.ck +++ b/src/tests/filesys/base/lg-seq-random.ck @@ -13,3 +13,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (lg-seq-random) close "nibble" (lg-seq-random) end EOF +pass; diff --git a/src/tests/filesys/base/sm-create.ck b/src/tests/filesys/base/sm-create.ck index d4a6317..8ca80dc 100644 --- a/src/tests/filesys/base/sm-create.ck +++ b/src/tests/filesys/base/sm-create.ck @@ -10,3 +10,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (sm-create) close "blargle" (sm-create) end EOF +pass; diff --git a/src/tests/filesys/base/sm-full.ck b/src/tests/filesys/base/sm-full.ck index 6fa4805..2e0eb36 100644 --- a/src/tests/filesys/base/sm-full.ck +++ b/src/tests/filesys/base/sm-full.ck @@ -13,3 +13,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (sm-full) close "quux" (sm-full) end EOF +pass; diff --git a/src/tests/filesys/base/sm-random.ck b/src/tests/filesys/base/sm-random.ck index 29b2fb7..bda049d 100644 --- a/src/tests/filesys/base/sm-random.ck +++ b/src/tests/filesys/base/sm-random.ck @@ -11,3 +11,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (sm-random) close "bazzle" (sm-random) end EOF +pass; diff --git a/src/tests/filesys/base/sm-seq-block.ck b/src/tests/filesys/base/sm-seq-block.ck index 1556668..0e2939d 100644 --- a/src/tests/filesys/base/sm-seq-block.ck +++ b/src/tests/filesys/base/sm-seq-block.ck @@ -13,3 +13,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (sm-seq-block) close "noodle" (sm-seq-block) end EOF +pass; diff --git a/src/tests/filesys/base/sm-seq-random.ck b/src/tests/filesys/base/sm-seq-random.ck index 47f9d88..2fb368b 100644 --- a/src/tests/filesys/base/sm-seq-random.ck +++ b/src/tests/filesys/base/sm-seq-random.ck @@ -13,3 +13,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (sm-seq-random) close "nibble" (sm-seq-random) end EOF +pass; diff --git a/src/tests/filesys/base/syn-read.ck b/src/tests/filesys/base/syn-read.ck index 7bda1aa..e2f68e8 100644 --- a/src/tests/filesys/base/syn-read.ck +++ b/src/tests/filesys/base/syn-read.ck @@ -30,3 +30,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (syn-read) wait for child 10 of 10 returned 9 (expected 9) (syn-read) end EOF +pass; diff --git a/src/tests/filesys/base/syn-remove.ck b/src/tests/filesys/base/syn-remove.ck index 79a5cb7..16ff11e 100644 --- a/src/tests/filesys/base/syn-remove.ck +++ b/src/tests/filesys/base/syn-remove.ck @@ -13,3 +13,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (syn-remove) close "deleteme" (syn-remove) end EOF +pass; diff --git a/src/tests/filesys/base/syn-write.ck b/src/tests/filesys/base/syn-write.ck index da52dd8..629a7a2 100644 --- a/src/tests/filesys/base/syn-write.ck +++ b/src/tests/filesys/base/syn-write.ck @@ -29,3 +29,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (syn-write) read "stuff" (syn-write) end EOF +pass; diff --git a/src/tests/filesys/extended/Make.tests b/src/tests/filesys/extended/Make.tests index 9f03c6e..1aeb8dd 100644 --- a/src/tests/filesys/extended/Make.tests +++ b/src/tests/filesys/extended/Make.tests @@ -1,21 +1,49 @@ # -*- makefile -*- tests/filesys/extended_TESTS = $(addprefix \ -tests/filesys/extended/,dir-empty-name dir-lsdir dir-mk-tree \ -dir-mk-vine dir-mkdir dir-open dir-over-file dir-rm-cwd-cd dir-rm-cwd \ -dir-rm-parent dir-rm-root dir-rm-tree dir-rm-vine dir-rmdir \ -dir-under-file grow-create grow-dir-lg grow-file-size grow-root-lg \ -grow-root-sm grow-seq-lg grow-seq-sm grow-sparse grow-tell \ -grow-too-big grow-two-files syn-rw) +tests/filesys/extended/,dir-empty-name dir-mk-tree dir-mkdir dir-open \ +dir-over-file dir-rm-cwd dir-rm-parent dir-rm-root dir-rm-tree \ +dir-rmdir dir-under-file dir-vine grow-create grow-dir-lg \ +grow-file-size grow-root-lg grow-root-sm grow-seq-lg grow-seq-sm \ +grow-sparse grow-tell grow-two-files syn-rw) tests/filesys/extended_PROGS = $(tests/filesys/extended_TESTS) \ -tests/filesys/extended/child-syn-rw +tests/filesys/extended/child-syn-rw tests/filesys/extended/tar $(foreach prog,$(tests/filesys/extended_PROGS), \ $(eval $(prog)_SRC += $(prog).c tests/lib.c tests/filesys/seq-test.c)) $(foreach prog,$(tests/filesys/extended_TESTS), \ $(eval $(prog)_SRC += tests/main.c)) +$(foreach prog,$(tests/filesys/extended_TESTS), \ + $(eval $(prog)_PUTFILES += tests/filesys/extended/tar)) +$(foreach test,$(tests/filesys/extended_TESTS), \ + $(eval $(test).output: FSDISK = tmp.dsk)) + tests/filesys/extended/dir-mk-tree_SRC += tests/filesys/extended/mk-tree.c tests/filesys/extended/dir-rm-tree_SRC += tests/filesys/extended/mk-tree.c -tests/filesys/extended/syn-rw_PUTFILES = tests/filesys/extended/child-syn-rw +tests/filesys/extended/syn-rw_PUTFILES += tests/filesys/extended/child-syn-rw + + +GETTIMEOUT = 60 + +GETCMD = pintos -v -T $(GETTIMEOUT) +GETCMD += $(PINTOSOPTS) +GETCMD += $(SIMULATOR) +GETCMD += --fs-disk=$(FSDISK) +GETCMD += -g fs.tar -a $(TEST).tar +ifeq ($(filter vm, $(KERNEL_SUBDIRS)), vm) +GETCMD += --swap-disk=4 +endif +GETCMD += -- -q +GETCMD += $(KERNELFLAGS) +GETCMD += run 'tar fs.tar /' +GETCMD += 2>> $(TEST).get-errors +GETCMD += $(if $(VERBOSE),|tee -a,>>) $(TEST).get-output + +tests/filesys/extended/%.output: os.dsk + rm -f tmp.dsk + pintos-mkdisk tmp.dsk 2 + $(TESTCMD) + $(GETCMD) + rm -f tmp.dsk diff --git a/src/tests/filesys/extended/Rubric.functionality b/src/tests/filesys/extended/Rubric.functionality index 0e36889..94f7c2c 100644 --- a/src/tests/filesys/extended/Rubric.functionality +++ b/src/tests/filesys/extended/Rubric.functionality @@ -1,14 +1,12 @@ Functionality of extended file system: - Test directory support. 1 dir-mkdir -2 dir-mk-vine 3 dir-mk-tree 1 dir-rmdir -2 dir-rm-vine 3 dir-rm-tree -1 dir-lsdir +5 dir-vine - Test file growth. 1 grow-create diff --git a/src/tests/filesys/extended/Rubric.robustness b/src/tests/filesys/extended/Rubric.robustness index 2f58ca8..fb9f32f 100644 --- a/src/tests/filesys/extended/Rubric.robustness +++ b/src/tests/filesys/extended/Rubric.robustness @@ -4,9 +4,6 @@ Robustness of file system: 1 dir-over-file 1 dir-under-file -1 dir-rm-cwd -2 dir-rm-cwd-cd +3 dir-rm-cwd 2 dir-rm-parent 1 dir-rm-root - -1 grow-too-big diff --git a/src/tests/filesys/extended/dir-empty-name.ck b/src/tests/filesys/extended/dir-empty-name.ck index c2d87f8..c4cbc6b 100644 --- a/src/tests/filesys/extended/dir-empty-name.ck +++ b/src/tests/filesys/extended/dir-empty-name.ck @@ -7,3 +7,5 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (dir-empty-name) create "" (must return false) (dir-empty-name) end EOF +check_archive ({}); +pass; diff --git a/src/tests/filesys/extended/dir-lsdir.c b/src/tests/filesys/extended/dir-lsdir.c deleted file mode 100644 index 254e595..0000000 --- a/src/tests/filesys/extended/dir-lsdir.c +++ /dev/null @@ -1,21 +0,0 @@ -/* Lists the contents of a directory using readdir. */ - -#include -#include "tests/lib.h" -#include "tests/main.h" - -void -test_main (void) -{ - int fd; - char name[READDIR_MAX_LEN + 1]; - - CHECK ((fd = open (".")) > 1, "open ."); - CHECK (isdir (fd), "isdir(.)"); - - while (readdir (fd, name)) - msg ("readdir: \"%s\"", name); - - msg ("close ."); - close (fd); -} diff --git a/src/tests/filesys/extended/dir-lsdir.ck b/src/tests/filesys/extended/dir-lsdir.ck deleted file mode 100644 index 36a4e52..0000000 --- a/src/tests/filesys/extended/dir-lsdir.ck +++ /dev/null @@ -1,46 +0,0 @@ -# -*- perl -*- -use strict; -use warnings; -use tests::tests; - -our ($test); -my (@output) = read_text_file ("$test.output"); - -common_checks (@output); -@output = get_core_output (@output); - -must_contain_in_order (\@output, - '(dir-lsdir) open .', - '(dir-lsdir) isdir(.)', - '(dir-lsdir) close .'); - -sub must_contain_in_order { - my ($output, @lines) = @_; - my (@line_numbers) = map (find_line ($_, @$output), @lines); - for my $i (0...$#lines - 1) { - fail "\"$lines[$i]\" follows \"$lines[$i + 1]\" in output\n" - if $line_numbers[$i] > $line_numbers[$i + 1]; - } -} - -sub find_line { - my ($line, @output) = @_; - for my $i (0...$#output) { - return $i if $line eq $output[$i]; - } - fail "\"$line\" does not appear in output\n"; -} - -my (%count); -for my $fn (map (/readdir: \"([^"]+)\"/, @output)) { - fail "Unexpected file \"$fn\" in lsdir output\n" - unless grep ($_ eq $fn, qw (dir-lsdir)); - fail "File \"$fn\" listed twice in lsdir output\n" - if $count{$fn}; - $count{$fn}++; -} -fail "No files in lsdir output\n" if scalar (keys (%count)) == 0; -fail "File \"dir-lsdir\" missing from lsdir output\n" - if !$count{"dir-lsdir"}; - -pass; diff --git a/src/tests/filesys/extended/dir-mk-tree.ck b/src/tests/filesys/extended/dir-mk-tree.ck index 8d77145..046e509 100644 --- a/src/tests/filesys/extended/dir-mk-tree.ck +++ b/src/tests/filesys/extended/dir-mk-tree.ck @@ -9,3 +9,15 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (dir-mk-tree) close "/0/2/0/3" (dir-mk-tree) end EOF +my ($tree); +for my $a (0...3) { + for my $b (0...2) { + for my $c (0...2) { + for my $d (0...3) { + $tree->{$a}{$b}{$c}{$d} = ['']; + } + } + } +} +check_archive ($tree); +pass; diff --git a/src/tests/filesys/extended/dir-mk-vine.c b/src/tests/filesys/extended/dir-mk-vine.c deleted file mode 100644 index 444727a..0000000 --- a/src/tests/filesys/extended/dir-mk-vine.c +++ /dev/null @@ -1,26 +0,0 @@ -/* Creates a "vine" of directories /0/1/2/3/4/5/6/7/8/9 - and changes directory into each of them, - then creates a test file in the bottommost - and verifies that it can be opened by absolute name. */ - -#include -#include "tests/lib.h" -#include "tests/main.h" - -void -test_main (void) -{ - const char *file_name = "/0/1/2/3/4/5/6/7/8/9/test"; - char dir[2]; - - dir[1] = '\0'; - for (dir[0] = '0'; dir[0] <= '9'; dir[0]++) - { - CHECK (mkdir (dir), "mkdir \"%s\"", dir); - CHECK (chdir (dir), "chdir \"%s\"", dir); - } - CHECK (create ("test", 512), "create \"test\""); - CHECK (chdir ("/"), "chdir \"/\""); - CHECK (open (file_name) > 1, "open \"%s\"", file_name); -} - diff --git a/src/tests/filesys/extended/dir-mk-vine.ck b/src/tests/filesys/extended/dir-mk-vine.ck deleted file mode 100644 index 1f9db74..0000000 --- a/src/tests/filesys/extended/dir-mk-vine.ck +++ /dev/null @@ -1,31 +0,0 @@ -# -*- perl -*- -use strict; -use warnings; -use tests::tests; -check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); -(dir-mk-vine) begin -(dir-mk-vine) mkdir "0" -(dir-mk-vine) chdir "0" -(dir-mk-vine) mkdir "1" -(dir-mk-vine) chdir "1" -(dir-mk-vine) mkdir "2" -(dir-mk-vine) chdir "2" -(dir-mk-vine) mkdir "3" -(dir-mk-vine) chdir "3" -(dir-mk-vine) mkdir "4" -(dir-mk-vine) chdir "4" -(dir-mk-vine) mkdir "5" -(dir-mk-vine) chdir "5" -(dir-mk-vine) mkdir "6" -(dir-mk-vine) chdir "6" -(dir-mk-vine) mkdir "7" -(dir-mk-vine) chdir "7" -(dir-mk-vine) mkdir "8" -(dir-mk-vine) chdir "8" -(dir-mk-vine) mkdir "9" -(dir-mk-vine) chdir "9" -(dir-mk-vine) create "test" -(dir-mk-vine) chdir "/" -(dir-mk-vine) open "/0/1/2/3/4/5/6/7/8/9/test" -(dir-mk-vine) end -EOF diff --git a/src/tests/filesys/extended/dir-mkdir.ck b/src/tests/filesys/extended/dir-mkdir.ck index d4e062b..7cde055 100644 --- a/src/tests/filesys/extended/dir-mkdir.ck +++ b/src/tests/filesys/extended/dir-mkdir.ck @@ -10,3 +10,5 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (dir-mkdir) open "b" (dir-mkdir) end EOF +check_archive ({'a' => {'b' => ["\0" x 512]}}); +pass; diff --git a/src/tests/filesys/extended/dir-open.ck b/src/tests/filesys/extended/dir-open.ck index e16e9a0..01eccba 100644 --- a/src/tests/filesys/extended/dir-open.ck +++ b/src/tests/filesys/extended/dir-open.ck @@ -17,3 +17,5 @@ EOF (dir-open) write "xyzzy" dir-open: exit(-1) EOF +check_archive ({"xyzzy" => {}}); +pass; diff --git a/src/tests/filesys/extended/dir-over-file.ck b/src/tests/filesys/extended/dir-over-file.ck index 208fd9f..5208429 100644 --- a/src/tests/filesys/extended/dir-over-file.ck +++ b/src/tests/filesys/extended/dir-over-file.ck @@ -8,3 +8,5 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (dir-over-file) create "abc" (must return false) (dir-over-file) end EOF +check_archive ({"abc" => {}}); +pass; diff --git a/src/tests/filesys/extended/dir-rm-cwd-cd.c b/src/tests/filesys/extended/dir-rm-cwd-cd.c deleted file mode 100644 index c9a6e61..0000000 --- a/src/tests/filesys/extended/dir-rm-cwd-cd.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Tries to remove the current directory. - This is allowed to succeed or fail. - If it succeeds, then it must not be possible to chdir back to - the current directory by name (because it's been deleted). - If it fails, then it must be possible to chdir back to the - current directory by name (because it still exists). */ - -#include -#include "tests/lib.h" -#include "tests/main.h" - -void -test_main (void) -{ - CHECK (mkdir ("a"), "mkdir \"a\""); - CHECK (chdir ("a"), "chdir \"a\""); - msg ("remove \"/a\" (must not crash)"); - if (remove ("/a")) - CHECK (!chdir ("/a"), - "chdir \"/a\" (remove succeeded so this must return false)"); - else - CHECK (chdir ("/a"), "chdir \"/a\" (remove failed so this must succeed)"); -} diff --git a/src/tests/filesys/extended/dir-rm-cwd-cd.ck b/src/tests/filesys/extended/dir-rm-cwd-cd.ck deleted file mode 100644 index fc49668..0000000 --- a/src/tests/filesys/extended/dir-rm-cwd-cd.ck +++ /dev/null @@ -1,19 +0,0 @@ -# -*- perl -*- -use strict; -use warnings; -use tests::tests; -check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF', <<'EOF']); -(dir-rm-cwd-cd) begin -(dir-rm-cwd-cd) mkdir "a" -(dir-rm-cwd-cd) chdir "a" -(dir-rm-cwd-cd) remove "/a" (must not crash) -(dir-rm-cwd-cd) chdir "/a" (remove succeeded so this must return false) -(dir-rm-cwd-cd) end -EOF -(dir-rm-cwd-cd) begin -(dir-rm-cwd-cd) mkdir "a" -(dir-rm-cwd-cd) chdir "a" -(dir-rm-cwd-cd) remove "/a" (must not crash) -(dir-rm-cwd-cd) chdir "/a" (remove failed so this must succeed) -(dir-rm-cwd-cd) end -EOF diff --git a/src/tests/filesys/extended/dir-rm-cwd.c b/src/tests/filesys/extended/dir-rm-cwd.c index 7f81a0b..78e13de 100644 --- a/src/tests/filesys/extended/dir-rm-cwd.c +++ b/src/tests/filesys/extended/dir-rm-cwd.c @@ -1,19 +1,75 @@ -/* Tries to remove the current directory. - This is allowed to succeed or fail. - Then creates a file in the root to make sure that we haven't - corrupted any directory state. */ +/* Tries to remove the current directory, which may succeed or + fail. The requirements in each case are different; refer to + the assignment for details. */ #include #include "tests/lib.h" #include "tests/main.h" +static int +wrap_open (const char *name) +{ + static int fds[8], fd_cnt; + int fd, i; + + CHECK ((fd = open (name)) > 1, "open \"%s\"", name); + for (i = 0; i < fd_cnt; i++) + if (fds[i] == fd) + fail ("fd returned is not unique"); + fds[fd_cnt++] = fd; + return fd; +} + void test_main (void) { + int root_fd, a_fd0; + char name[READDIR_MAX_LEN + 1]; + + root_fd = wrap_open ("/"); CHECK (mkdir ("a"), "mkdir \"a\""); + + a_fd0 = wrap_open ("/a"); + CHECK (!readdir (a_fd0, name), "verify \"/a\" is empty"); + CHECK (inumber (root_fd) != inumber (a_fd0), + "\"/\" and \"/a\" must have different inumbers"); + CHECK (chdir ("a"), "chdir \"a\""); - msg ("remove \"/a\" (must not crash)"); - remove ("/a"); - msg ("create \"b\" (must not crash)"); - create ("b", 123); + + msg ("try to remove \"/a\""); + if (remove ("/a")) + { + msg ("remove successful"); + + CHECK (open ("/a") == -1, "open \"/a\" (must fail)"); + CHECK (open (".") == -1, "open \".\" (must fail)"); + CHECK (open ("..") == -1, "open \"..\" (must fail)"); + CHECK (!create ("x", 512), "create \"x\" (must fail)"); + } + else + { + int a_fd1, a_fd2, a_fd3; + + msg ("remove failed"); + + CHECK (!remove ("../a"), "try to remove \"../a\" (must fail)"); + CHECK (!remove (".././a"), "try to remove \".././a\" (must fail)"); + CHECK (!remove ("/./a"), "try to remove \"/./a\" (must fail)"); + + a_fd1 = wrap_open ("/a"); + a_fd2 = wrap_open ("."); + CHECK (inumber (a_fd1) == inumber (a_fd2), + "\"/a\" and \".\" must have same inumber"); + CHECK (inumber (root_fd) != inumber (a_fd1), + "\"/\" and \"/a\" must have different inumbers"); + + CHECK (chdir ("/a"), "chdir \"/a\""); + a_fd3 = wrap_open ("."); + CHECK (inumber (a_fd3) == inumber (a_fd1), + "\".\" must have same inumber as before"); + + CHECK (chdir ("/"), "chdir \"/\""); + CHECK (!remove ("a"), "try to remove \"a\" (must fail: still open)"); + } + CHECK (!readdir (a_fd0, name), "verify \"/a\" is empty"); } diff --git a/src/tests/filesys/extended/dir-rm-cwd.ck b/src/tests/filesys/extended/dir-rm-cwd.ck index 91e7c0f..8821f0d 100644 --- a/src/tests/filesys/extended/dir-rm-cwd.ck +++ b/src/tests/filesys/extended/dir-rm-cwd.ck @@ -2,11 +2,48 @@ use strict; use warnings; use tests::tests; -check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); +my ($cwd_removable) = check_expected (IGNORE_EXIT_CODES => 1, + {NO => <<'EOF', YES => <<'EOF'}); (dir-rm-cwd) begin +(dir-rm-cwd) open "/" (dir-rm-cwd) mkdir "a" +(dir-rm-cwd) open "/a" +(dir-rm-cwd) verify "/a" is empty +(dir-rm-cwd) "/" and "/a" must have different inumbers (dir-rm-cwd) chdir "a" -(dir-rm-cwd) remove "/a" (must not crash) -(dir-rm-cwd) create "b" (must not crash) +(dir-rm-cwd) try to remove "/a" +(dir-rm-cwd) remove failed +(dir-rm-cwd) try to remove "../a" (must fail) +(dir-rm-cwd) try to remove ".././a" (must fail) +(dir-rm-cwd) try to remove "/./a" (must fail) +(dir-rm-cwd) open "/a" +(dir-rm-cwd) open "." +(dir-rm-cwd) "/a" and "." must have same inumber +(dir-rm-cwd) "/" and "/a" must have different inumbers +(dir-rm-cwd) chdir "/a" +(dir-rm-cwd) open "." +(dir-rm-cwd) "." must have same inumber as before +(dir-rm-cwd) chdir "/" +(dir-rm-cwd) try to remove "a" (must fail: still open) +(dir-rm-cwd) verify "/a" is empty (dir-rm-cwd) end EOF +(dir-rm-cwd) begin +(dir-rm-cwd) open "/" +(dir-rm-cwd) mkdir "a" +(dir-rm-cwd) open "/a" +(dir-rm-cwd) verify "/a" is empty +(dir-rm-cwd) "/" and "/a" must have different inumbers +(dir-rm-cwd) chdir "a" +(dir-rm-cwd) try to remove "/a" +(dir-rm-cwd) remove successful +(dir-rm-cwd) open "/a" (must fail) +(dir-rm-cwd) open "." (must fail) +(dir-rm-cwd) open ".." (must fail) +(dir-rm-cwd) create "x" (must fail) +(dir-rm-cwd) verify "/a" is empty +(dir-rm-cwd) end +EOF + +check_archive ($cwd_removable eq 'YES' ? {} : {"a" => {}}); +pass; diff --git a/src/tests/filesys/extended/dir-rm-parent.c b/src/tests/filesys/extended/dir-rm-parent.c index 78e84b1..eb43f5b 100644 --- a/src/tests/filesys/extended/dir-rm-parent.c +++ b/src/tests/filesys/extended/dir-rm-parent.c @@ -1,6 +1,5 @@ -/* Tries to remove the change of parents of the current - directory. - This can succeed or fail as long as it doesn't crash. */ +/* Tries to remove a parent of the current directory. This must + fail, because that directory is non-empty. */ #include #include "tests/lib.h" @@ -13,8 +12,5 @@ test_main (void) CHECK (chdir ("a"), "chdir \"a\""); CHECK (mkdir ("b"), "mkdir \"b\""); CHECK (chdir ("b"), "chdir \"b\""); - msg ("remove \"/b\" (must not crash)"); - remove ("/b"); - msg ("remove \"/a\" (must not crash)"); - remove ("/a"); + CHECK (!remove ("/a"), "remove \"/a\" (must fail)"); } diff --git a/src/tests/filesys/extended/dir-rm-parent.ck b/src/tests/filesys/extended/dir-rm-parent.ck index 92301a5..acbacc1 100644 --- a/src/tests/filesys/extended/dir-rm-parent.ck +++ b/src/tests/filesys/extended/dir-rm-parent.ck @@ -8,7 +8,8 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (dir-rm-parent) chdir "a" (dir-rm-parent) mkdir "b" (dir-rm-parent) chdir "b" -(dir-rm-parent) remove "/b" (must not crash) -(dir-rm-parent) remove "/a" (must not crash) +(dir-rm-parent) remove "/a" (must fail) (dir-rm-parent) end EOF +check_archive ({"a" => {"b" => {}}}); +pass; diff --git a/src/tests/filesys/extended/dir-rm-root.c b/src/tests/filesys/extended/dir-rm-root.c index 5f9cb61..c47f1eb 100644 --- a/src/tests/filesys/extended/dir-rm-root.c +++ b/src/tests/filesys/extended/dir-rm-root.c @@ -1,5 +1,5 @@ /* Try to remove the root directory. - This must return failure. */ + This must fail. */ #include #include "tests/lib.h" @@ -8,6 +8,6 @@ void test_main (void) { - CHECK (!remove ("/"), "remove \"/\" (must return false)"); + CHECK (!remove ("/"), "remove \"/\" (must fail)"); CHECK (create ("/a", 243), "create \"/a\""); } diff --git a/src/tests/filesys/extended/dir-rm-root.ck b/src/tests/filesys/extended/dir-rm-root.ck index 38894dd..b203cc6 100644 --- a/src/tests/filesys/extended/dir-rm-root.ck +++ b/src/tests/filesys/extended/dir-rm-root.ck @@ -4,7 +4,9 @@ use warnings; use tests::tests; check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (dir-rm-root) begin -(dir-rm-root) remove "/" (must return false) +(dir-rm-root) remove "/" (must fail) (dir-rm-root) create "/a" (dir-rm-root) end EOF +check_archive ({"a" => ["\0" x 243]}); +pass; diff --git a/src/tests/filesys/extended/dir-rm-tree.ck b/src/tests/filesys/extended/dir-rm-tree.ck index 519eff0..7e3ae6e 100644 --- a/src/tests/filesys/extended/dir-rm-tree.ck +++ b/src/tests/filesys/extended/dir-rm-tree.ck @@ -11,3 +11,5 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (dir-rm-tree) open "/3/0/2/0" (must return -1) (dir-rm-tree) end EOF +check_archive ({}); +pass; diff --git a/src/tests/filesys/extended/dir-rm-vine.c b/src/tests/filesys/extended/dir-rm-vine.c deleted file mode 100644 index e01ff49..0000000 --- a/src/tests/filesys/extended/dir-rm-vine.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Creates a "vine" of directories /0/1/2/3/4/5/6/7/8/9 - and changes directory into each of them, - then remove them. */ - -#include -#include -#include "tests/lib.h" -#include "tests/main.h" - -void -test_main (void) -{ - const char *file_name = "/0/1/2/3/4/5/6/7/8/9/test"; - int fd; - char tmp[128]; - - tmp[1] = '\0'; - for (tmp[0] = '0'; tmp[0] <= '9'; tmp[0]++) - { - CHECK (mkdir (tmp), "mkdir \"%s\"", tmp); - CHECK (chdir (tmp), "chdir \"%s\"", tmp); - } - CHECK (create ("test", 512), "create \"test\""); - - CHECK (chdir ("/"), "chdir \"/\""); - CHECK ((fd = open (file_name)) > 1, "open \"%s\"", file_name); - msg ("close \"%s\"", file_name); - close (fd); - - strlcpy (tmp, file_name, sizeof tmp); - while (strlen (tmp) > 0) - { - CHECK (remove (tmp), "remove \"%s\"", tmp); - *strrchr (tmp, '/') = 0; - } - - CHECK (open (file_name) == -1, "open \"%s\" (must return -1)", file_name); -} diff --git a/src/tests/filesys/extended/dir-rm-vine.ck b/src/tests/filesys/extended/dir-rm-vine.ck deleted file mode 100644 index d8e3638..0000000 --- a/src/tests/filesys/extended/dir-rm-vine.ck +++ /dev/null @@ -1,44 +0,0 @@ -# -*- perl -*- -use strict; -use warnings; -use tests::tests; -check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); -(dir-rm-vine) begin -(dir-rm-vine) mkdir "0" -(dir-rm-vine) chdir "0" -(dir-rm-vine) mkdir "1" -(dir-rm-vine) chdir "1" -(dir-rm-vine) mkdir "2" -(dir-rm-vine) chdir "2" -(dir-rm-vine) mkdir "3" -(dir-rm-vine) chdir "3" -(dir-rm-vine) mkdir "4" -(dir-rm-vine) chdir "4" -(dir-rm-vine) mkdir "5" -(dir-rm-vine) chdir "5" -(dir-rm-vine) mkdir "6" -(dir-rm-vine) chdir "6" -(dir-rm-vine) mkdir "7" -(dir-rm-vine) chdir "7" -(dir-rm-vine) mkdir "8" -(dir-rm-vine) chdir "8" -(dir-rm-vine) mkdir "9" -(dir-rm-vine) chdir "9" -(dir-rm-vine) create "test" -(dir-rm-vine) chdir "/" -(dir-rm-vine) open "/0/1/2/3/4/5/6/7/8/9/test" -(dir-rm-vine) close "/0/1/2/3/4/5/6/7/8/9/test" -(dir-rm-vine) remove "/0/1/2/3/4/5/6/7/8/9/test" -(dir-rm-vine) remove "/0/1/2/3/4/5/6/7/8/9" -(dir-rm-vine) remove "/0/1/2/3/4/5/6/7/8" -(dir-rm-vine) remove "/0/1/2/3/4/5/6/7" -(dir-rm-vine) remove "/0/1/2/3/4/5/6" -(dir-rm-vine) remove "/0/1/2/3/4/5" -(dir-rm-vine) remove "/0/1/2/3/4" -(dir-rm-vine) remove "/0/1/2/3" -(dir-rm-vine) remove "/0/1/2" -(dir-rm-vine) remove "/0/1" -(dir-rm-vine) remove "/0" -(dir-rm-vine) open "/0/1/2/3/4/5/6/7/8/9/test" (must return -1) -(dir-rm-vine) end -EOF diff --git a/src/tests/filesys/extended/dir-rmdir.ck b/src/tests/filesys/extended/dir-rmdir.ck index f8f00e6..e1c8916 100644 --- a/src/tests/filesys/extended/dir-rmdir.ck +++ b/src/tests/filesys/extended/dir-rmdir.ck @@ -9,3 +9,5 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (dir-rmdir) chdir "a" (must return false) (dir-rmdir) end EOF +check_archive ({}); +pass; diff --git a/src/tests/filesys/extended/dir-under-file.ck b/src/tests/filesys/extended/dir-under-file.ck index 8b5cffd..8123d19 100644 --- a/src/tests/filesys/extended/dir-under-file.ck +++ b/src/tests/filesys/extended/dir-under-file.ck @@ -8,3 +8,5 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (dir-under-file) mkdir "abc" (must return false) (dir-under-file) end EOF +check_archive ({"abc" => ['']}); +pass; diff --git a/src/tests/filesys/extended/dir-vine.c b/src/tests/filesys/extended/dir-vine.c new file mode 100644 index 0000000..8a31c38 --- /dev/null +++ b/src/tests/filesys/extended/dir-vine.c @@ -0,0 +1,85 @@ +/* Create a very deep "vine" of directories: /dir0/dir1/dir2/... + and an ordinary file in each of them, until we fill up the + disk. + + Then delete most of them, for two reasons. First, "tar" + limits file names to 100 characters (which could be extended + to 256 without much trouble). Second, a full disk has no room + for the tar archive. */ + +#include +#include +#include +#include "tests/lib.h" +#include "tests/main.h" + +void +test_main (void) +{ + int i; + + msg ("creating many levels of files and directories..."); + quiet = true; + CHECK (mkdir ("start"), "mkdir \"start\""); + CHECK (chdir ("start"), "chdir \"start\""); + for (i = 0; ; i++) + { + char name[3][READDIR_MAX_LEN + 1]; + char file_name[16], dir_name[16]; + char contents[128]; + int fd; + + /* Create file. */ + snprintf (file_name, sizeof file_name, "file%d", i); + if (!create (file_name, 0)) + break; + CHECK ((fd = open (file_name)) > 1, "open \"%s\"", file_name); + snprintf (contents, sizeof contents, "contents %d\n", i); + if (write (fd, contents, strlen (contents)) != (int) strlen (contents)) + { + CHECK (remove (file_name), "remove \"%s\"", file_name); + close (fd); + break; + } + close (fd); + + /* Create directory. */ + snprintf (dir_name, sizeof dir_name, "dir%d", i); + if (!mkdir (dir_name)) + { + CHECK (remove (file_name), "remove \"%s\"", file_name); + break; + } + + /* Check for file and directory. */ + CHECK ((fd = open (".")) > 1, "open \".\""); + CHECK (readdir (fd, name[0]), "readdir \".\""); + CHECK (readdir (fd, name[1]), "readdir \".\""); + CHECK (!readdir (fd, name[2]), "readdir \".\" (should fail)"); + CHECK ((!strcmp (name[0], dir_name) && !strcmp (name[1], file_name)) + || (!strcmp (name[1], dir_name) && !strcmp (name[0], file_name)), + "names should be \"%s\" and \"%s\", " + "actually \"%s\" and \"%s\"", + file_name, dir_name, name[0], name[1]); + close (fd); + + /* Descend into directory. */ + CHECK (chdir (dir_name), "chdir \"%s\"", dir_name); + } + CHECK (i > 200, "created files and directories only to level %d", i); + quiet = false; + + msg ("removing all but top 10 levels of files and directories..."); + quiet = true; + while (i-- > 10) + { + char file_name[16], dir_name[16]; + + snprintf (file_name, sizeof file_name, "file%d", i); + snprintf (dir_name, sizeof dir_name, "dir%d", i); + CHECK (chdir (".."), "chdir \"..\""); + CHECK (remove (dir_name), "remove \"%s\"", dir_name); + CHECK (remove (file_name), "remove \"%s\"", file_name); + } + quiet = false; +} diff --git a/src/tests/filesys/extended/dir-vine.ck b/src/tests/filesys/extended/dir-vine.ck new file mode 100644 index 0000000..d18b664 --- /dev/null +++ b/src/tests/filesys/extended/dir-vine.ck @@ -0,0 +1,44 @@ +# -*- perl -*- +use strict; +use warnings; +use tests::tests; +check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); +(dir-vine) begin +(dir-vine) creating many levels of files and directories... +(dir-vine) removing all but top 10 levels of files and directories... +(dir-vine) end +EOF + +# The archive should look like this: +# +# -rw-r--r-- 0/0 40642 2006-01-01 00:00:00 dir-vine +# -rw-r--r-- 0/0 42479 2006-01-01 00:00:00 tar +# drwxr-xr-x 0/0 0 2006-01-01 00:00:00 start +# -rw-r--r-- 0/0 11 2006-01-01 00:00:00 start/file0 +# drwxr-xr-x 0/0 0 2006-01-01 00:00:00 start/dir0 +# -rw-r--r-- 0/0 11 2006-01-01 00:00:00 start/dir0/file1 +# drwxr-xr-x 0/0 0 2006-01-01 00:00:00 start/dir0/dir1 +# -rw-r--r-- 0/0 11 2006-01-01 00:00:00 start/dir0/dir1/file2 +# drwxr-xr-x 0/0 0 2006-01-01 00:00:00 start/dir0/dir1/dir2 +# -rw-r--r-- 0/0 11 2006-01-01 00:00:00 start/dir0/dir1/dir2/file3 +# drwxr-xr-x 0/0 0 2006-01-01 00:00:00 start/dir0/dir1/dir2/dir3 +# -rw-r--r-- 0/0 11 2006-01-01 00:00:00 start/dir0/dir1/dir2/dir3/file4 +# drwxr-xr-x 0/0 0 2006-01-01 00:00:00 start/dir0/dir1/dir2/dir3/dir4 +# -rw-r--r-- 0/0 11 2006-01-01 00:00:00 start/dir0/dir1/dir2/dir3/dir4/file5 +# drwxr-xr-x 0/0 0 2006-01-01 00:00:00 start/dir0/dir1/dir2/dir3/dir4/dir5 +# -rw-r--r-- 0/0 11 2006-01-01 00:00:00 start/dir0/dir1/dir2/dir3/dir4/dir5/file6 +# drwxr-xr-x 0/0 0 2006-01-01 00:00:00 start/dir0/dir1/dir2/dir3/dir4/dir5/dir6 +# -rw-r--r-- 0/0 11 2006-01-01 00:00:00 start/dir0/dir1/dir2/dir3/dir4/dir5/dir6/file7 +# drwxr-xr-x 0/0 0 2006-01-01 00:00:00 start/dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7 +# -rw-r--r-- 0/0 11 2006-01-01 00:00:00 start/dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/file8 +# drwxr-xr-x 0/0 0 2006-01-01 00:00:00 start/dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8 +# -rw-r--r-- 0/0 11 2006-01-01 00:00:00 start/dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/file9 +# drwxr-xr-x 0/0 0 2006-01-01 00:00:00 start/dir0/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9 +my ($dir) = {}; +my ($root) = {"start" => $dir}; +for (my ($i) = 0; $i < 10; $i++) { + $dir->{"file$i"} = ["contents $i\n"]; + $dir = $dir->{"dir$i"} = {}; +} +check_archive ($root); +pass; diff --git a/src/tests/filesys/extended/grow-create.ck b/src/tests/filesys/extended/grow-create.ck index 54d7f6c..c20ca4c 100644 --- a/src/tests/filesys/extended/grow-create.ck +++ b/src/tests/filesys/extended/grow-create.ck @@ -10,3 +10,5 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-create) close "blargle" (grow-create) end EOF +check_archive ({"blargle" => ['']}); +pass; diff --git a/src/tests/filesys/extended/grow-dir-lg.ck b/src/tests/filesys/extended/grow-dir-lg.ck index 4214eec..635e1be 100644 --- a/src/tests/filesys/extended/grow-dir-lg.ck +++ b/src/tests/filesys/extended/grow-dir-lg.ck @@ -2,6 +2,7 @@ use strict; use warnings; use tests::tests; +use tests::random; check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-dir-lg) begin (grow-dir-lg) mkdir /x @@ -57,3 +58,7 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-dir-lg) creating and checking "/x/file49" (grow-dir-lg) end EOF +my ($fs); +$fs->{'x'}{"file$_"} = [random_bytes (512)] foreach 0...49; +check_archive ($fs); +pass; diff --git a/src/tests/filesys/extended/grow-file-size.ck b/src/tests/filesys/extended/grow-file-size.ck index 0a70837..057bb2e 100644 --- a/src/tests/filesys/extended/grow-file-size.ck +++ b/src/tests/filesys/extended/grow-file-size.ck @@ -2,6 +2,7 @@ use strict; use warnings; use tests::tests; +use tests::random; check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-file-size) begin (grow-file-size) create "testfile" @@ -13,3 +14,6 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-file-size) close "testfile" (grow-file-size) end EOF +my ($string); +check_archive ({"testfile" => [random_bytes (2134)]}); +pass; diff --git a/src/tests/filesys/extended/grow-root-lg.ck b/src/tests/filesys/extended/grow-root-lg.ck index d44b244..2affddd 100644 --- a/src/tests/filesys/extended/grow-root-lg.ck +++ b/src/tests/filesys/extended/grow-root-lg.ck @@ -2,6 +2,7 @@ use strict; use warnings; use tests::tests; +use tests::random; check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-root-lg) begin (grow-root-lg) creating and checking "file0" @@ -56,3 +57,7 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-root-lg) creating and checking "file49" (grow-root-lg) end EOF +my ($fs); +$fs->{"file$_"} = [random_bytes (512)] foreach 0...49; +check_archive ($fs); +pass; diff --git a/src/tests/filesys/extended/grow-root-sm.ck b/src/tests/filesys/extended/grow-root-sm.ck index d9d33ff..8eb59e4 100644 --- a/src/tests/filesys/extended/grow-root-sm.ck +++ b/src/tests/filesys/extended/grow-root-sm.ck @@ -2,6 +2,7 @@ use strict; use warnings; use tests::tests; +use tests::random; check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-root-sm) begin (grow-root-sm) creating and checking "file0" @@ -26,3 +27,7 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-root-sm) creating and checking "file19" (grow-root-sm) end EOF +my ($fs); +$fs->{"file$_"} = [random_bytes (512)] foreach 0...19; +check_archive ($fs); +pass; diff --git a/src/tests/filesys/extended/grow-seq-lg.ck b/src/tests/filesys/extended/grow-seq-lg.ck index 659aeff..6276c79 100644 --- a/src/tests/filesys/extended/grow-seq-lg.ck +++ b/src/tests/filesys/extended/grow-seq-lg.ck @@ -2,6 +2,7 @@ use strict; use warnings; use tests::tests; +use tests::random; check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-seq-lg) begin (grow-seq-lg) create "testme" @@ -13,3 +14,5 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-seq-lg) close "testme" (grow-seq-lg) end EOF +check_archive ({"testme" => [random_bytes (72943)]}); +pass; diff --git a/src/tests/filesys/extended/grow-seq-sm.ck b/src/tests/filesys/extended/grow-seq-sm.ck index 242aa0e..8dd2c26 100644 --- a/src/tests/filesys/extended/grow-seq-sm.ck +++ b/src/tests/filesys/extended/grow-seq-sm.ck @@ -2,6 +2,7 @@ use strict; use warnings; use tests::tests; +use tests::random; check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-seq-sm) begin (grow-seq-sm) create "testme" @@ -13,3 +14,5 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-seq-sm) close "testme" (grow-seq-sm) end EOF +check_archive ({"testme" => [random_bytes (5678)]}); +pass; diff --git a/src/tests/filesys/extended/grow-sparse.ck b/src/tests/filesys/extended/grow-sparse.ck index 2b2d950..9c6315f 100644 --- a/src/tests/filesys/extended/grow-sparse.ck +++ b/src/tests/filesys/extended/grow-sparse.ck @@ -14,3 +14,5 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-sparse) close "testfile" (grow-sparse) end EOF +check_archive ({"testfile" => ["\0" x 76543]}); +pass; diff --git a/src/tests/filesys/extended/grow-tell.ck b/src/tests/filesys/extended/grow-tell.ck index 3e8abcf..cd03efb 100644 --- a/src/tests/filesys/extended/grow-tell.ck +++ b/src/tests/filesys/extended/grow-tell.ck @@ -2,6 +2,7 @@ use strict; use warnings; use tests::tests; +use tests::random; check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-tell) begin (grow-tell) create "foobar" @@ -13,3 +14,5 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-tell) close "foobar" (grow-tell) end EOF +check_archive ({"foobar" => [random_bytes (2134)]}); +pass; diff --git a/src/tests/filesys/extended/grow-too-big.c b/src/tests/filesys/extended/grow-too-big.c deleted file mode 100644 index a908e45..0000000 --- a/src/tests/filesys/extended/grow-too-big.c +++ /dev/null @@ -1,24 +0,0 @@ -/* Checks that trying to grow a file beyond the capacity of the - file system behaves reasonably (does not crash). */ - -#include -#include -#include "tests/lib.h" -#include "tests/main.h" - -void -test_main (void) -{ - const char *file_name = "fumble"; - char zero = 0; - int fd; - - CHECK (create (file_name, 0), "create \"%s\"", file_name); - CHECK ((fd = open (file_name)) > 1, "open \"%s\"", file_name); - msg ("seek \"%s\"", file_name); - seek (fd, UINT_MAX); - msg ("write \"%s\"", file_name); - write (fd, &zero, 1); - msg ("close \"%s\"", file_name); - close (fd); -} diff --git a/src/tests/filesys/extended/grow-too-big.ck b/src/tests/filesys/extended/grow-too-big.ck deleted file mode 100644 index 9a4027c..0000000 --- a/src/tests/filesys/extended/grow-too-big.ck +++ /dev/null @@ -1,13 +0,0 @@ -# -*- perl -*- -use strict; -use warnings; -use tests::tests; -check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); -(grow-too-big) begin -(grow-too-big) create "fumble" -(grow-too-big) open "fumble" -(grow-too-big) seek "fumble" -(grow-too-big) write "fumble" -(grow-too-big) close "fumble" -(grow-too-big) end -EOF diff --git a/src/tests/filesys/extended/grow-two-files.ck b/src/tests/filesys/extended/grow-two-files.ck index d62d9fa..b238d80 100644 --- a/src/tests/filesys/extended/grow-two-files.ck +++ b/src/tests/filesys/extended/grow-two-files.ck @@ -2,6 +2,7 @@ use strict; use warnings; use tests::tests; +use tests::random; check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-two-files) begin (grow-two-files) create "a" @@ -19,3 +20,7 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (grow-two-files) close "b" (grow-two-files) end EOF +my ($a) = random_bytes (8143); +my ($b) = random_bytes (8143); +check_archive ({"a" => [$a], "b" => [$b]}); +pass; diff --git a/src/tests/filesys/extended/syn-rw.ck b/src/tests/filesys/extended/syn-rw.ck index 41b6e8a..7a70299 100644 --- a/src/tests/filesys/extended/syn-rw.ck +++ b/src/tests/filesys/extended/syn-rw.ck @@ -2,6 +2,7 @@ use strict; use warnings; use tests::tests; +use tests::random; check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (syn-rw) begin (syn-rw) create "logfile" @@ -16,3 +17,6 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (syn-rw) wait for child 4 of 4 returned 3 (expected 3) (syn-rw) end EOF +check_archive ({"child-syn-rw" => "tests/filesys/extended/child-syn-rw", + "logfile" => [random_bytes (8 * 512)]}); +pass; diff --git a/src/tests/filesys/extended/tar.c b/src/tests/filesys/extended/tar.c new file mode 100644 index 0000000..193c373 --- /dev/null +++ b/src/tests/filesys/extended/tar.c @@ -0,0 +1,250 @@ +/* tar.c + + Creates a tar archive. */ + +#include +#include +#include + +static void usage (void); +static bool make_tar_archive (const char *archive_name, + char *files[], size_t file_cnt); + +int +main (int argc, char *argv[]) +{ + if (argc < 3) + usage (); + + return (make_tar_archive (argv[1], argv + 2, argc - 2) + ? EXIT_SUCCESS : EXIT_FAILURE); +} + +static void +usage (void) +{ + printf ("tar, tar archive creator\n" + "Usage: tar ARCHIVE FILE...\n" + "where ARCHIVE is the tar archive to create\n" + " and FILE... is a list of files or directories to put into it.\n" + "(ARCHIVE itself will not be included in the archive, even if it\n" + "is in a directory to be archived.)\n"); + exit (EXIT_FAILURE); +} + +static bool archive_file (char file_name[], size_t file_name_size, + int archive_fd, bool *write_error); + +static bool archive_ordinary_file (const char *file_name, int file_fd, + int archive_fd, bool *write_error); +static bool archive_directory (char file_name[], size_t file_name_size, + int file_fd, int archive_fd, bool *write_error); +static bool write_header (const char *file_name, + char type_flag, int size, unsigned mode, + int archive_fd, bool *write_error); + +static bool do_write (int fd, const char *buffer, int size, bool *write_error); + +static bool +make_tar_archive (const char *archive_name, char *files[], size_t file_cnt) +{ + static const char zeros[512]; + int archive_fd; + bool success; + bool write_error = false; + size_t i; + + if (!create (archive_name, 0)) + { + printf ("%s: create failed\n", archive_name); + return false; + } + archive_fd = open (archive_name); + if (archive_fd < 0) + { + printf ("%s: open failed\n", archive_name); + return false; + } + + for (i = 0; i < file_cnt; i++) + { + char file_name[128]; + + strlcpy (file_name, files[i], sizeof file_name); + if (!archive_file (file_name, sizeof file_name, + archive_fd, &write_error)) + success = false; + } + + if (!do_write (archive_fd, zeros, 512, &write_error) + || !do_write (archive_fd, zeros, 512, &write_error)) + success = false; + + close (archive_fd); + + return success; +} + +static bool +archive_file (char file_name[], size_t file_name_size, + int archive_fd, bool *write_error) +{ + int file_fd = open (file_name); + if (file_fd >= 0) + { + bool success; + + if (inumber (file_fd) != inumber (archive_fd)) + { + if (!isdir (file_fd)) + success = archive_ordinary_file (file_name, file_fd, + archive_fd, write_error); + else + success = archive_directory (file_name, file_name_size, file_fd, + archive_fd, write_error); + } + else + { + /* Nothing to do: don't try to archive the archive file. */ + success = true; + } + + close (file_fd); + + return success; + } + else + { + printf ("%s: open failed\n", file_name); + return false; + } +} + +static bool +archive_ordinary_file (const char *file_name, int file_fd, + int archive_fd, bool *write_error) +{ + bool read_error = false; + bool success = true; + int file_size = filesize (file_fd); + + if (!write_header (file_name, '0', file_size, 0644, archive_fd, write_error)) + return false; + + while (file_size > 0) + { + static char buf[512]; + int chunk_size = file_size > 512 ? 512 : file_size; + int read_retval = read (file_fd, buf, chunk_size); + int bytes_read = read_retval > 0 ? read_retval : 0; + + if (bytes_read != chunk_size && !read_error) + { + printf ("%s: read error\n", file_name); + read_error = true; + success = false; + } + + memset (buf + bytes_read, 0, 512 - bytes_read); + if (!do_write (archive_fd, buf, 512, write_error)) + success = false; + + file_size -= chunk_size; + } + + return success; +} + +static bool +archive_directory (char file_name[], size_t file_name_size, int file_fd, + int archive_fd, bool *write_error) +{ + size_t dir_len; + bool success = true; + + dir_len = strlen (file_name); + if (dir_len + 1 + READDIR_MAX_LEN + 1 > file_name_size) + { + printf ("%s: file name too long\n", file_name); + return false; + } + + if (!write_header (file_name, '5', 0, 0755, archive_fd, write_error)) + return false; + + file_name[dir_len] = '/'; + while (readdir (file_fd, &file_name[dir_len + 1])) + if (!archive_file (file_name, file_name_size, archive_fd, write_error)) + success = false; + file_name[dir_len] = '\0'; + + return success; +} + +static bool +write_header (const char *file_name, + char type_flag, int size, unsigned mode, + int archive_fd, bool *write_error) +{ + static char header[512]; + unsigned chksum; + size_t i; + + memset (header, 0, sizeof header); + +/* Drop confusing and possibly dangerous prefixes from + FILE_NAME. */ + while (*file_name == '/' + || !memcmp (file_name, "./", 2) + || !memcmp (file_name, "../", 3)) + file_name = strchr (file_name, '/') + 1; + if (*file_name == '\0') + { + /* Dropped *everything* from FILE_NAME. + Should only be possible for a directory. */ + ASSERT (type_flag == '5'); + return true; + } + else if (strlen (file_name) > 99) + { + printf ("%s: file name too long\n", file_name); + return false; + } + + /* Fill in header except for final checksum. */ + strlcpy (header, file_name, 100); /* name */ + snprintf (header + 100, 8, "%07o", mode); /* mode */ + strlcpy (header + 108, "0000000", 8); /* uid */ + strlcpy (header + 116, "0000000", 8); /* gid */ + snprintf (header + 124, 12, "%011o", size); /* size */ + snprintf (header + 136, 12, "%011o", 1136102400); /* mtime (2006-01-01) */ + memset (header + 148, ' ', 8); /* chksum */ + header[156] = type_flag; /* typeflag */ + strlcpy (header + 257, "ustar", 6); /* magic */ + strlcpy (header + 263, "00", 3); /* version */ + + /* Compute and fill in final checksum. */ + chksum = 0; + for (i = 0; i < 512; i++) + chksum += (uint8_t) header[i]; + snprintf (header + 148, 8, "%07o", chksum); + + /* Write header. */ + return do_write (archive_fd, header, 512, write_error); +} + +static bool +do_write (int fd, const char *buffer, int size, bool *write_error) +{ + if (write (fd, buffer, size) == size) + return true; + else + { + if (!*write_error) + { + printf ("error writing archive\n"); + *write_error = true; + } + return false; + } +} diff --git a/src/tests/tests.pm b/src/tests/tests.pm index 858d8a4..74b6905 100644 --- a/src/tests/tests.pm +++ b/src/tests/tests.pm @@ -2,6 +2,7 @@ use strict; use warnings; use tests::Algorithm::Diff; use File::Temp 'tempfile'; +use Fcntl qw(SEEK_SET SEEK_CUR); sub fail; sub pass; @@ -11,42 +12,45 @@ our ($test, $src_dir) = @ARGV; my ($msg_file) = tempfile (); select ($msg_file); + +# Generic testing. sub check_expected { my ($expected) = pop @_; my (@options) = @_; my (@output) = read_text_file ("$test.output"); - common_checks (@output); - compare_output (@options, \@output, $expected); + common_checks ("run", @output); + compare_output ("run", @options, \@output, $expected); } sub common_checks { - my (@output) = @_; + my ($run, @output) = @_; - fail "No output at all\n" if @output == 0; + fail "\u$run produced no output at all\n" if @output == 0; - check_for_panic (@output); - check_for_keyword ("FAIL", @output); - check_for_triple_fault (@output); - check_for_keyword ("TIMEOUT", @output); + check_for_panic ($run, @output); + check_for_keyword ($run, "FAIL", @output); + check_for_triple_fault ($run, @output); + check_for_keyword ($run, "TIMEOUT", @output); - fail "Didn't start up properly: no \"Pintos booting\" startup message\n" + fail "\u$run didn't start up properly: no \"Pintos booting\" message\n" if !grep (/Pintos booting with.*kB RAM\.\.\./, @output); - fail "Didn't start up properly: no \"Boot complete\" startup message\n" + fail "\u$run didn't start up properly: no \"Boot complete\" message\n" if !grep (/Boot complete/, @output); - fail "Didn't shut down properly: no \"Timer: # ticks\" shutdown message\n" + fail "\u$run didn't shut down properly: no \"Timer: # ticks\" message\n" if !grep (/Timer: \d+ ticks/, @output); - fail "Didn't shut down properly: no \"Powering off\" shutdown message\n" + fail "\u$run didn't shut down properly: no \"Powering off\" message\n" if !grep (/Powering off/, @output); } sub check_for_panic { - my (@output) = @_; + my ($run, @output) = @_; my ($panic) = grep (/PANIC/, @output); return unless defined $panic; - print "Kernel panic: ", substr ($panic, index ($panic, "PANIC")), "\n"; + print "Kernel panic in $run: ", substr ($panic, index ($panic, "PANIC")), + "\n"; my (@stack_line) = grep (/Call stack:/, @output); if (@stack_line != 0) { @@ -86,7 +90,7 @@ EOF } sub check_for_keyword { - my ($keyword, @output) = @_; + my ($run, $keyword, @output) = @_; my ($kw_line) = grep (/$keyword/, @output); return unless defined $kw_line; @@ -94,18 +98,19 @@ sub check_for_keyword { # Most output lines are prefixed by (test-name). Eliminate this # from our message for brevity. $kw_line =~ s/^\([^\)]+\)\s+//; - print "$kw_line\n"; + print "$run: $kw_line\n"; fail; } sub check_for_triple_fault { - my (@output) = @_; + my ($run, @output) = @_; - return unless grep (/Pintos booting/, @output) > 1; + my ($reboots) = grep (/Pintos booting/, @output) - 1; + return unless $reboots > 0; print < $_), @$expected)}; + } + foreach my $key (keys %$expected) { + my (@expected) = split ("\n", $expected->{$key}); $msg .= "Acceptable output:\n"; $msg .= join ('', map (" $_\n", @expected)); @@ -150,7 +175,7 @@ sub compare_output { for (my ($i) = 0; $i <= $#expected; $i++) { $eq = 0 if $output[$i] ne $expected[$i]; } - pass if $eq; + return $key if $eq; } # They differ. Output a diff. @@ -173,6 +198,354 @@ sub compare_output { # Failed to match. Report failure. fail "Test output failed to match any acceptable form.\n\n$msg"; } + +# File system extraction. + +# check_archive (\%CONTENTS) +# +# Checks that the extracted file system's contents match \%CONTENTS. +# Each key in the hash is a file name. Each value may be: +# +# - $FILE: Name of a host file containing the expected contents. +# +# - [$FILE, $OFFSET, $LENGTH]: An excerpt of host file $FILE +# comprising the $LENGTH bytes starting at $OFFSET. +# +# - [$CONTENTS]: The literal expected file contents, as a string. +# +# - {SUBDIR}: A subdirectory, in the same form described here, +# recursively. +sub check_archive { + my ($expected_hier) = @_; + my (@output) = read_text_file ("$test.get-output"); + common_checks ("file system extraction run", @output); + + @output = get_core_output ("file system extraction run", @output); + @output = grep (!/^[a-zA-Z0-9-_]+: exit\(\d+\)$/, @output); + fail join ("\n", "Error extracting file system:", @output) if @output; + + my ($test_base_name) = $test; + $test_base_name =~ s%.*/%%; + $expected_hier->{$test_base_name} = $test; + $expected_hier->{'tar'} = 'tests/filesys/extended/tar'; + + my (%expected) = normalize_fs (flatten_hierarchy ($expected_hier, "")); + my (%actual) = read_tar ("$test.tar"); + + my ($errors) = 0; + foreach my $name (sort keys %expected) { + if (exists $actual{$name}) { + if (is_dir ($actual{$name}) && !is_dir ($expected{$name})) { + print "$name is a directory but should be an ordinary file.\n"; + $errors++; + } elsif (!is_dir ($actual{$name}) && is_dir ($expected{$name})) { + print "$name is an ordinary file but should be a directory.\n"; + $errors++; + } + } else { + print "$name is missing from the file system.\n"; + $errors++; + } + } + foreach my $name (sort keys %actual) { + if (!exists $expected{$name}) { + if ($name =~ /^[[:print:]]+$/) { + print "$name exists in the file system but it should not.\n"; + } else { + my ($esc_name) = $name; + $esc_name =~ s/[^[:print:]]/./g; + print <[0]); + $file = tempfile (); + syswrite ($file, $value->[0]) == $length + or die "writing temporary file: $!\n"; + sysseek ($file, 0, SEEK_SET); + } elsif (@$value == 3) { + $length = $value->[2]; + open ($file, '<', $value->[0]) or die "$value->[0]: open: $!\n"; + die "$value->[0]: file is smaller than expected\n" + if -s $file < $value->[1] + $length; + sysseek ($file, $value->[1], SEEK_SET); + } else { + die; + } + return ($file, $length); +} + +# compare_files ($A, $A_SIZE, $B, $B_SIZE, $NAME, $VERBOSE) +# +# Compares $A_SIZE bytes in $A to $B_SIZE bytes in $B. +# ($A and $B are handles.) +# If their contents differ, prints a brief message describing +# the differences, using $NAME to identify the file. +# The message contains more detail if $VERBOSE is nonzero. +# Returns 1 if the contents are identical, 0 otherwise. +sub compare_files { + my ($a, $a_size, $b, $b_size, $name, $verbose) = @_; + my ($ofs) = 0; + select(STDOUT); + for (;;) { + my ($a_amt) = $a_size >= 1024 ? 1024 : $a_size; + my ($b_amt) = $b_size >= 1024 ? 1024 : $b_size; + my ($a_data, $b_data); + if (!defined (sysread ($a, $a_data, $a_amt)) + || !defined (sysread ($b, $b_data, $b_amt))) { + die "reading $name: $!\n"; + } + + my ($a_len) = length $a_data; + my ($b_len) = length $b_data; + last if $a_len == 0 && $b_len == 0; + + if ($a_data ne $b_data) { + my ($min_len) = $a_len < $b_len ? $a_len : $b_len; + my ($diff_ofs); + for ($diff_ofs = 0; $diff_ofs < $min_len; $diff_ofs++) { + last if (substr ($a_data, $diff_ofs, 1) + ne substr ($b_data, $diff_ofs, 1)); + } + + printf "\nFile $name differs from expected " + . "starting at offset 0x%x.\n", $ofs + $diff_ofs; + if ($verbose ) { + print "Expected contents:\n"; + hex_dump (substr ($a_data, $diff_ofs, 64), $ofs + $diff_ofs); + print "Actual contents:\n"; + hex_dump (substr ($b_data, $diff_ofs, 64), $ofs + $diff_ofs); + } + return 0; + } + + $ofs += $a_len; + $a_size -= $a_len; + $b_size -= $b_len; + } + return 1; +} + +# hex_dump ($DATA, $OFS) +# +# Prints $DATA in hex and text formats. +# The first byte of $DATA corresponds to logical offset $OFS +# in whatever file the data comes from. +sub hex_dump { + my ($data, $ofs) = @_; + + if ($data eq '') { + printf " (File ends at offset %08x.)\n", $ofs; + return; + } + + my ($per_line) = 16; + while ((my $size = length ($data)) > 0) { + my ($start) = $ofs % $per_line; + my ($end) = $per_line; + $end = $start + $size if $end - $start > $size; + my ($n) = $end - $start; + + printf "0x%08x ", int ($ofs / $per_line) * $per_line; + + # Hex version. + print " " x $start; + for my $i ($start...$end - 1) { + printf "%02x", ord (substr ($data, $i - $start, 1)); + print $i == $per_line / 2 - 1 ? '-' : ' '; + } + print " " x ($per_line - $end); + + # Character version. + my ($esc_data) = substr ($data, 0, $n); + $esc_data =~ s/[^[:print:]]/./g; + print "|", " " x $start, $esc_data, " " x ($per_line - $end), "|"; + + print "\n"; + + $data = substr ($data, $n); + $ofs += $n; + } +} + +# print_fs (%FS) +# +# Prints a list of files in %FS, which must be a file system +# as flattened by flatten_hierarchy() and normalized by +# normalize_fs(). +sub print_fs { + my (%fs) = @_; + foreach my $name (sort keys %fs) { + my ($esc_name) = $name; + $esc_name =~ s/[^[:print:]]/./g; + print "$esc_name: "; + if (!is_dir ($fs{$name})) { + print +file_size ($fs{$name}), "-byte file"; + } else { + print "directory"; + } + print "\n"; + } +} + +# normalize_fs (%FS) +# +# Takes a file system as flattened by flatten_hierarchy(). +# Returns a similar file system in which values of the form $FILE +# are replaced by those of the form [$FILE, $OFFSET, $LENGTH]. +sub normalize_fs { + my (%fs) = @_; + foreach my $name (keys %fs) { + my ($value) = $fs{$name}; + next if is_dir ($value) || ref ($value) ne ''; + die "can't open $value\n" if !stat $value; + $fs{$name} = [$value, 0, -s _]; + } + return %fs; +} + +# is_dir ($VALUE) +# +# Takes a value like one in the hash returned by flatten_hierarchy() +# and returns 1 if it represents a directory, 0 otherwise. +sub is_dir { + my ($value) = @_; + return ref ($value) eq '' && $value eq 'directory'; +} + +# file_size ($VALUE) +# +# Takes a value like one in the hash returned by flatten_hierarchy() +# and returns the size of the file it represents. +sub file_size { + my ($value) = @_; + die if is_dir ($value); + die if ref ($value) ne 'ARRAY'; + return @$value > 1 ? $value->[2] : length ($value->[0]); +} + +# flatten_hierarchy ($HIER_FS, $PREFIX) +# +# Takes a file system in the format expected by check_archive() and +# returns a "flattened" version in which file names include all parent +# directory names and the value of directories is just "directory". +sub flatten_hierarchy { + my (%hier_fs) = %{$_[0]}; + my ($prefix) = $_[1]; + my (%flat_fs); + for my $name (keys %hier_fs) { + my ($value) = $hier_fs{$name}; + if (ref $value eq 'HASH') { + %flat_fs = (%flat_fs, flatten_hierarchy ($value, "$prefix$name/")); + $flat_fs{"$prefix$name"} = 'directory'; + } else { + $flat_fs{"$prefix$name"} = $value; + } + } + return %flat_fs; +} + +# read_tar ($ARCHIVE) +# +# Reads the ustar-format tar file in $ARCHIVE +# and returns a flattened file system for it. +sub read_tar { + my ($archive) = @_; + my (%content); + open (ARCHIVE, '<', $archive) or die "$archive: open: $1\n"; + for (;;) { + my ($header); + if ((my $retval = sysread (ARCHIVE, $header, 512)) != 512) { + die "$archive: unexpected end of file\n" if $retval >= 0; + die "$archive: read: $!\n"; + } + + last if $header eq "\0" x 512; + + # Verify magic numbers. + if (substr ($header, 257, 6) ne "ustar\0" + || substr ($header, 263, 2) ne '00') { + die "$archive: corrupt ustar header\n"; + } + + # Verify checksum. + my ($chksum) = oct (unpack ("Z*", substr ($header, 148, 8, ' ' x 8))); + my ($correct_chksum) = unpack ("%32a*", $header); + die "$archive: bad header checksum\n" if $chksum != $correct_chksum; + + # Get file name. + my ($name) = unpack ("Z100", $header); + my ($prefix) = unpack ("Z*", substr ($header, 345)); + $name = "$prefix/$name" if $prefix ne ''; + die "$archive: contains file with empty name" if $name eq ''; + + # Get type. + my ($typeflag) = substr ($header, 156, 1); + $typeflag = '0' if $typeflag eq "\0"; + die "unknown file type '$typeflag'\n" if $typeflag !~ /[05]/; + + # Get size. + my ($size) = oct (unpack ("Z*", substr ($header, 124, 12))); + die "bad size $size\n" if $size < 0; + $size = 0 if $typeflag eq '5'; + + # Store content. + if (exists $content{$name}) { + die "$archive: contains multiple entries for $name\n"; + } + if ($typeflag eq '5') { + $content{$name} = 'directory'; + } else { + my ($position) = sysseek (ARCHIVE, 0, SEEK_CUR); + $content{$name} = [$archive, $position, $size]; + sysseek (ARCHIVE, int (($size + 511) / 512) * 512, SEEK_CUR); + } + } + close (ARCHIVE); + return %content; +} + +# Utilities. sub fail { finish ("FAIL", @_); @@ -183,18 +556,17 @@ sub pass { } sub finish { - my ($verdict, @rest) = @_; + my ($verdict, @messages) = @_; - my ($messages) = ""; seek ($msg_file, 0, 0); - while (<$msg_file>) { - $messages .= $_; - } + push (@messages, <$msg_file>); close ($msg_file); + chomp (@messages); my ($result_fn) = "$test.result"; open (RESULT, '>', $result_fn) or die "$result_fn: create: $!\n"; - print RESULT "$verdict\n", $messages, @rest; + print RESULT "$verdict\n"; + print RESULT "$_\n" foreach @messages; close (RESULT); if ($verdict eq 'PASS') { @@ -202,7 +574,7 @@ sub finish { } else { print STDOUT "FAIL $test\n"; } - print STDOUT $messages, @rest, "\n"; + print STDOUT "$_\n" foreach @messages; exit 0; } diff --git a/src/tests/threads/alarm-negative.ck b/src/tests/threads/alarm-negative.ck index e40ff30..0d2bab0 100644 --- a/src/tests/threads/alarm-negative.ck +++ b/src/tests/threads/alarm-negative.ck @@ -7,3 +7,4 @@ check_expected ([<<'EOF']); (alarm-negative) PASS (alarm-negative) end EOF +pass; diff --git a/src/tests/threads/alarm-priority.ck b/src/tests/threads/alarm-priority.ck index c62b024..b57c78b 100644 --- a/src/tests/threads/alarm-priority.ck +++ b/src/tests/threads/alarm-priority.ck @@ -16,3 +16,4 @@ check_expected ([<<'EOF']); (alarm-priority) Thread priority 21 woke up. (alarm-priority) end EOF +pass; diff --git a/src/tests/threads/alarm-simultaneous.ck b/src/tests/threads/alarm-simultaneous.ck index 510c07d..7cec517 100644 --- a/src/tests/threads/alarm-simultaneous.ck +++ b/src/tests/threads/alarm-simultaneous.ck @@ -34,3 +34,4 @@ check_expected ([<<'EOF']); (alarm-simultaneous) iteration 4, thread 4: woke up 0 ticks later (alarm-simultaneous) end EOF +pass; diff --git a/src/tests/threads/alarm-zero.ck b/src/tests/threads/alarm-zero.ck index 6a967b4..a6b1a3c 100644 --- a/src/tests/threads/alarm-zero.ck +++ b/src/tests/threads/alarm-zero.ck @@ -7,3 +7,4 @@ check_expected ([<<'EOF']); (alarm-zero) PASS (alarm-zero) end EOF +pass; diff --git a/src/tests/threads/alarm.pm b/src/tests/threads/alarm.pm index 84d6d12..84b3b7f 100644 --- a/src/tests/threads/alarm.pm +++ b/src/tests/threads/alarm.pm @@ -3,7 +3,7 @@ sub check_alarm { our ($test); @output = read_text_file ("$test.output"); - common_checks (@output); + common_checks ("run", @output); my (@products); for (my ($i) = 0; $i < $iterations; $i++) { diff --git a/src/tests/threads/mlfqs-block.ck b/src/tests/threads/mlfqs-block.ck index e3b883a..8833a3a 100644 --- a/src/tests/threads/mlfqs-block.ck +++ b/src/tests/threads/mlfqs-block.ck @@ -14,3 +14,4 @@ check_expected ([<<'EOF']); (mlfqs-block) Block thread should have already acquired lock. (mlfqs-block) end EOF +pass; diff --git a/src/tests/threads/mlfqs-load-1.ck b/src/tests/threads/mlfqs-load-1.ck index db78881..faf0ffa 100644 --- a/src/tests/threads/mlfqs-load-1.ck +++ b/src/tests/threads/mlfqs-load-1.ck @@ -6,9 +6,9 @@ use tests::tests; our ($test); my (@output) = read_text_file ("$test.output"); -common_checks (@output); +common_checks ("run", @output); -@output = get_core_output (@output); +@output = get_core_output ("run", @output); fail "missing PASS in output" unless grep ($_ eq '(mlfqs-load-1) PASS', @output); diff --git a/src/tests/threads/mlfqs-load-60.ck b/src/tests/threads/mlfqs-load-60.ck index d2d6d63..cb69220 100644 --- a/src/tests/threads/mlfqs-load-60.ck +++ b/src/tests/threads/mlfqs-load-60.ck @@ -7,8 +7,8 @@ use tests::threads::mlfqs; our ($test); my (@output) = read_text_file ("$test.output"); -common_checks (@output); -@output = get_core_output (@output); +common_checks ("run", @output); +@output = get_core_output ("run", @output); # Get actual values. local ($_); diff --git a/src/tests/threads/mlfqs-load-avg.ck b/src/tests/threads/mlfqs-load-avg.ck index 3852072..2254d05 100644 --- a/src/tests/threads/mlfqs-load-avg.ck +++ b/src/tests/threads/mlfqs-load-avg.ck @@ -7,8 +7,8 @@ use tests::threads::mlfqs; our ($test); my (@output) = read_text_file ("$test.output"); -common_checks (@output); -@output = get_core_output (@output); +common_checks ("run", @output); +@output = get_core_output ("run", @output); # Get actual values. local ($_); diff --git a/src/tests/threads/mlfqs-recent-1.ck b/src/tests/threads/mlfqs-recent-1.ck index 76b7223..a2ba44d 100644 --- a/src/tests/threads/mlfqs-recent-1.ck +++ b/src/tests/threads/mlfqs-recent-1.ck @@ -6,8 +6,8 @@ use tests::threads::mlfqs; our ($test); my (@output) = read_text_file ("$test.output"); -common_checks (@output); -@output = get_core_output (@output); +common_checks ("run", @output); +@output = get_core_output ("run", @output); # Get actual values. local ($_); diff --git a/src/tests/threads/mlfqs.pm b/src/tests/threads/mlfqs.pm index 2ca7d09..184ac16 100644 --- a/src/tests/threads/mlfqs.pm +++ b/src/tests/threads/mlfqs.pm @@ -73,8 +73,8 @@ sub check_mlfqs_fair { my ($nice, $maxdiff) = @_; our ($test); my (@output) = read_text_file ("$test.output"); - common_checks (@output); - @output = get_core_output (@output); + common_checks ("run", @output); + @output = get_core_output ("run", @output); my (@actual); local ($_); diff --git a/src/tests/threads/priority-change.ck b/src/tests/threads/priority-change.ck index a0c759a..f4d9b2f 100644 --- a/src/tests/threads/priority-change.ck +++ b/src/tests/threads/priority-change.ck @@ -11,3 +11,4 @@ check_expected ([<<'EOF']); (priority-change) Thread 2 should have just exited. (priority-change) end EOF +pass; diff --git a/src/tests/threads/priority-condvar.ck b/src/tests/threads/priority-condvar.ck index 580a019..195c1ab 100644 --- a/src/tests/threads/priority-condvar.ck +++ b/src/tests/threads/priority-condvar.ck @@ -36,3 +36,4 @@ check_expected ([<<'EOF']); (priority-condvar) Thread priority 21 woke up. (priority-condvar) end EOF +pass; diff --git a/src/tests/threads/priority-donate-lower.ck b/src/tests/threads/priority-donate-lower.ck index b009fd8..c9bb61b 100644 --- a/src/tests/threads/priority-donate-lower.ck +++ b/src/tests/threads/priority-donate-lower.ck @@ -13,3 +13,4 @@ check_expected ([<<'EOF']); (priority-donate-lower) Main thread should have priority 21. Actual priority: 21. (priority-donate-lower) end EOF +pass; diff --git a/src/tests/threads/priority-donate-multiple.ck b/src/tests/threads/priority-donate-multiple.ck index d84a0ee..0afd20b 100644 --- a/src/tests/threads/priority-donate-multiple.ck +++ b/src/tests/threads/priority-donate-multiple.ck @@ -16,3 +16,4 @@ check_expected ([<<'EOF']); (priority-donate-multiple) Main thread should have priority 31. Actual priority: 31. (priority-donate-multiple) end EOF +pass; diff --git a/src/tests/threads/priority-donate-multiple2.ck b/src/tests/threads/priority-donate-multiple2.ck index 3855afd..b23533a 100644 --- a/src/tests/threads/priority-donate-multiple2.ck +++ b/src/tests/threads/priority-donate-multiple2.ck @@ -16,3 +16,4 @@ check_expected ([<<'EOF']); (priority-donate-multiple2) Main thread should have priority 31. Actual priority: 31. (priority-donate-multiple2) end EOF +pass; diff --git a/src/tests/threads/priority-donate-nest.ck b/src/tests/threads/priority-donate-nest.ck index 6ec1b4a..923460e 100644 --- a/src/tests/threads/priority-donate-nest.ck +++ b/src/tests/threads/priority-donate-nest.ck @@ -16,3 +16,4 @@ check_expected ([<<'EOF']); (priority-donate-nest) Low thread should have priority 31. Actual priority: 31. (priority-donate-nest) end EOF +pass; diff --git a/src/tests/threads/priority-donate-one.ck b/src/tests/threads/priority-donate-one.ck index c09ecfd..b7c8e6f 100644 --- a/src/tests/threads/priority-donate-one.ck +++ b/src/tests/threads/priority-donate-one.ck @@ -14,3 +14,4 @@ check_expected ([<<'EOF']); (priority-donate-one) This should be the last line before finishing this test. (priority-donate-one) end EOF +pass; diff --git a/src/tests/threads/priority-donate-sema.ck b/src/tests/threads/priority-donate-sema.ck index 904dbc1..92b8d07 100644 --- a/src/tests/threads/priority-donate-sema.ck +++ b/src/tests/threads/priority-donate-sema.ck @@ -13,3 +13,4 @@ check_expected ([<<'EOF']); (priority-donate-sema) Main thread finished. (priority-donate-sema) end EOF +pass; diff --git a/src/tests/threads/priority-fifo.ck b/src/tests/threads/priority-fifo.ck index a5322ec..11f1dd3 100644 --- a/src/tests/threads/priority-fifo.ck +++ b/src/tests/threads/priority-fifo.ck @@ -29,7 +29,7 @@ use tests::tests; our ($test); my (@output) = read_text_file ("$test.output"); -common_checks (@output); +common_checks ("run", @output); my ($thread_cnt) = 16; my ($iter_cnt) = 16; diff --git a/src/tests/threads/priority-preempt.ck b/src/tests/threads/priority-preempt.ck index e41f332..43a26ee 100644 --- a/src/tests/threads/priority-preempt.ck +++ b/src/tests/threads/priority-preempt.ck @@ -13,3 +13,4 @@ check_expected ([<<'EOF']); (priority-preempt) The high-priority thread should have already completed. (priority-preempt) end EOF +pass; diff --git a/src/tests/threads/priority-sema.ck b/src/tests/threads/priority-sema.ck index f2b9cde..559988d 100644 --- a/src/tests/threads/priority-sema.ck +++ b/src/tests/threads/priority-sema.ck @@ -26,3 +26,4 @@ check_expected ([<<'EOF']); (priority-sema) Back in main thread. (priority-sema) end EOF +pass; diff --git a/src/tests/userprog/Make.tests b/src/tests/userprog/Make.tests index f8ad9c9..9a5869f 100644 --- a/src/tests/userprog/Make.tests +++ b/src/tests/userprog/Make.tests @@ -1,8 +1,6 @@ # -*- makefile -*- -PINTOSFLAGS += --fs-disk=2 -KERNELFLAGS += -f - +tests/%.output: FSDISK = 2 tests/%.output: PUTFILES = $(filter-out os.dsk, $^) tests/userprog_TESTS = $(addprefix tests/userprog/,args-none \ diff --git a/src/tests/userprog/args-dbl-space.ck b/src/tests/userprog/args-dbl-space.ck index b0a32e0..dfbcf4b 100644 --- a/src/tests/userprog/args-dbl-space.ck +++ b/src/tests/userprog/args-dbl-space.ck @@ -12,3 +12,4 @@ check_expected ([<<'EOF']); (args) end args-dbl-space: exit(0) EOF +pass; diff --git a/src/tests/userprog/args-many.ck b/src/tests/userprog/args-many.ck index 3ed939f..214574a 100644 --- a/src/tests/userprog/args-many.ck +++ b/src/tests/userprog/args-many.ck @@ -32,3 +32,4 @@ check_expected ([<<'EOF']); (args) end args-many: exit(0) EOF +pass; diff --git a/src/tests/userprog/args-multiple.ck b/src/tests/userprog/args-multiple.ck index 11596ff..227e6cc 100644 --- a/src/tests/userprog/args-multiple.ck +++ b/src/tests/userprog/args-multiple.ck @@ -14,3 +14,4 @@ check_expected ([<<'EOF']); (args) end args-multiple: exit(0) EOF +pass; diff --git a/src/tests/userprog/args-none.ck b/src/tests/userprog/args-none.ck index 9679fa0..146318e 100644 --- a/src/tests/userprog/args-none.ck +++ b/src/tests/userprog/args-none.ck @@ -10,3 +10,4 @@ check_expected ([<<'EOF']); (args) end args-none: exit(0) EOF +pass; diff --git a/src/tests/userprog/args-single.ck b/src/tests/userprog/args-single.ck index aeca358..24582b4 100644 --- a/src/tests/userprog/args-single.ck +++ b/src/tests/userprog/args-single.ck @@ -11,3 +11,4 @@ check_expected ([<<'EOF']); (args) end args-single: exit(0) EOF +pass; diff --git a/src/tests/userprog/close-bad-fd.ck b/src/tests/userprog/close-bad-fd.ck index 4a0be96..497b17c 100644 --- a/src/tests/userprog/close-bad-fd.ck +++ b/src/tests/userprog/close-bad-fd.ck @@ -10,3 +10,4 @@ EOF (close-bad-fd) begin close-bad-fd: exit(-1) EOF +pass; diff --git a/src/tests/userprog/close-normal.ck b/src/tests/userprog/close-normal.ck index 890cea0..fe41342 100644 --- a/src/tests/userprog/close-normal.ck +++ b/src/tests/userprog/close-normal.ck @@ -9,3 +9,4 @@ check_expected ([<<'EOF']); (close-normal) end close-normal: exit(0) EOF +pass; diff --git a/src/tests/userprog/close-stdin.ck b/src/tests/userprog/close-stdin.ck index c62b53f..3d28507 100644 --- a/src/tests/userprog/close-stdin.ck +++ b/src/tests/userprog/close-stdin.ck @@ -10,3 +10,4 @@ EOF (close-stdin) begin close-stdin: exit(-1) EOF +pass; diff --git a/src/tests/userprog/close-stdout.ck b/src/tests/userprog/close-stdout.ck index 83cf984..3cbbcff 100644 --- a/src/tests/userprog/close-stdout.ck +++ b/src/tests/userprog/close-stdout.ck @@ -10,3 +10,4 @@ EOF (close-stdout) begin close-stdout: exit(-1) EOF +pass; diff --git a/src/tests/userprog/close-twice.ck b/src/tests/userprog/close-twice.ck index e21b169..deb55a6 100644 --- a/src/tests/userprog/close-twice.ck +++ b/src/tests/userprog/close-twice.ck @@ -16,3 +16,4 @@ EOF (close-twice) close "sample.txt" again close-twice: exit(-1) EOF +pass; diff --git a/src/tests/userprog/create-bad-ptr.ck b/src/tests/userprog/create-bad-ptr.ck index 46453bb..ac13405 100644 --- a/src/tests/userprog/create-bad-ptr.ck +++ b/src/tests/userprog/create-bad-ptr.ck @@ -6,3 +6,4 @@ check_expected ([<<'EOF']); (create-bad-ptr) begin create-bad-ptr: exit(-1) EOF +pass; diff --git a/src/tests/userprog/create-bound.ck b/src/tests/userprog/create-bound.ck index 87b7bd5..7656b7f 100644 --- a/src/tests/userprog/create-bound.ck +++ b/src/tests/userprog/create-bound.ck @@ -8,3 +8,4 @@ check_expected ([<<'EOF']); (create-bound) end create-bound: exit(0) EOF +pass; diff --git a/src/tests/userprog/create-empty.ck b/src/tests/userprog/create-empty.ck index 32fcb00..93a1058 100644 --- a/src/tests/userprog/create-empty.ck +++ b/src/tests/userprog/create-empty.ck @@ -11,3 +11,4 @@ EOF (create-empty) begin create-empty: exit(-1) EOF +pass; diff --git a/src/tests/userprog/create-exists.ck b/src/tests/userprog/create-exists.ck index d227033..006885e 100644 --- a/src/tests/userprog/create-exists.ck +++ b/src/tests/userprog/create-exists.ck @@ -12,3 +12,4 @@ check_expected ([<<'EOF']); (create-exists) end create-exists: exit(0) EOF +pass; diff --git a/src/tests/userprog/create-long.ck b/src/tests/userprog/create-long.ck index 3124584..628411c 100644 --- a/src/tests/userprog/create-long.ck +++ b/src/tests/userprog/create-long.ck @@ -8,3 +8,4 @@ check_expected ([<<'EOF']); (create-long) end create-long: exit(0) EOF +pass; diff --git a/src/tests/userprog/create-normal.ck b/src/tests/userprog/create-normal.ck index c956a1c..ca74a6e 100644 --- a/src/tests/userprog/create-normal.ck +++ b/src/tests/userprog/create-normal.ck @@ -8,3 +8,4 @@ check_expected ([<<'EOF']); (create-normal) end create-normal: exit(0) EOF +pass; diff --git a/src/tests/userprog/create-null.ck b/src/tests/userprog/create-null.ck index 641ff9b..09b7872 100644 --- a/src/tests/userprog/create-null.ck +++ b/src/tests/userprog/create-null.ck @@ -6,3 +6,4 @@ check_expected ([<<'EOF']); (create-null) begin create-null: exit(-1) EOF +pass; diff --git a/src/tests/userprog/exec-arg.ck b/src/tests/userprog/exec-arg.ck index bdedca6..b7533ed 100644 --- a/src/tests/userprog/exec-arg.ck +++ b/src/tests/userprog/exec-arg.ck @@ -14,3 +14,4 @@ child-args: exit(0) (exec-arg) end exec-arg: exit(0) EOF +pass; diff --git a/src/tests/userprog/exec-bad-ptr.ck b/src/tests/userprog/exec-bad-ptr.ck index f0fdd69..63f5f78 100644 --- a/src/tests/userprog/exec-bad-ptr.ck +++ b/src/tests/userprog/exec-bad-ptr.ck @@ -10,3 +10,4 @@ EOF (exec-bad-ptr) begin exec-bad-ptr: exit(-1) EOF +pass; diff --git a/src/tests/userprog/exec-missing.ck b/src/tests/userprog/exec-missing.ck index 726a4e7..0ef7aaa 100644 --- a/src/tests/userprog/exec-missing.ck +++ b/src/tests/userprog/exec-missing.ck @@ -28,3 +28,4 @@ no-such-file: exit(-1) (exec-missing) end exec-missing: exit(0) EOF +pass; diff --git a/src/tests/userprog/exec-multiple.ck b/src/tests/userprog/exec-multiple.ck index 6076958..99624cd 100644 --- a/src/tests/userprog/exec-multiple.ck +++ b/src/tests/userprog/exec-multiple.ck @@ -15,3 +15,4 @@ child-simple: exit(81) (exec-multiple) end exec-multiple: exit(0) EOF +pass; diff --git a/src/tests/userprog/exec-once.ck b/src/tests/userprog/exec-once.ck index 7aa688a..00b59ed 100644 --- a/src/tests/userprog/exec-once.ck +++ b/src/tests/userprog/exec-once.ck @@ -9,3 +9,4 @@ child-simple: exit(81) (exec-once) end exec-once: exit(0) EOF +pass; diff --git a/src/tests/userprog/exit.ck b/src/tests/userprog/exit.ck index 206c48b..a552702 100644 --- a/src/tests/userprog/exit.ck +++ b/src/tests/userprog/exit.ck @@ -6,3 +6,4 @@ check_expected ([<<'EOF']); (exit) begin exit: exit(57) EOF +pass; diff --git a/src/tests/userprog/halt.ck b/src/tests/userprog/halt.ck index 4b1207d..1b701ed 100644 --- a/src/tests/userprog/halt.ck +++ b/src/tests/userprog/halt.ck @@ -6,7 +6,7 @@ use tests::tests; our ($test); my (@output) = read_text_file ("$test.output"); -common_checks (@output); +common_checks ("run", @output); fail "missing 'begin' message\n" if !grep ($_ eq '(halt) begin', @output); diff --git a/src/tests/userprog/multi-child-fd.ck b/src/tests/userprog/multi-child-fd.ck index bad0378..d0b3a33 100644 --- a/src/tests/userprog/multi-child-fd.ck +++ b/src/tests/userprog/multi-child-fd.ck @@ -22,3 +22,4 @@ child-close: exit(-1) (multi-child-fd) end multi-child-fd: exit(0) EOF +pass; diff --git a/src/tests/userprog/multi-recurse.ck b/src/tests/userprog/multi-recurse.ck index d2a4e1b..41eb4a6 100644 --- a/src/tests/userprog/multi-recurse.ck +++ b/src/tests/userprog/multi-recurse.ck @@ -67,3 +67,4 @@ multi-recurse: exit(14) (multi-recurse) end 15 multi-recurse: exit(15) EOF +pass; diff --git a/src/tests/userprog/no-vm/multi-oom.ck b/src/tests/userprog/no-vm/multi-oom.ck index 52434a2..7ed5cc8 100644 --- a/src/tests/userprog/no-vm/multi-oom.ck +++ b/src/tests/userprog/no-vm/multi-oom.ck @@ -5,9 +5,9 @@ use tests::tests; our ($test); my (@output) = read_text_file ("$test.output"); -common_checks (@output); +common_checks ("run", @output); -@output = get_core_output (@output); +@output = get_core_output ("run", @output); my ($n) = 0; while (my ($m) = $output[0] =~ /^\(multi-oom\) begin (\d+)$/) { fail "Child process $m started out of order.\n" if $m != $n; diff --git a/src/tests/userprog/null.ck b/src/tests/userprog/null.ck index cacc658..980de35 100644 --- a/src/tests/userprog/null.ck +++ b/src/tests/userprog/null.ck @@ -5,3 +5,4 @@ use tests::tests; check_expected ([<<'EOF']); system call! EOF +pass; diff --git a/src/tests/userprog/open-bad-ptr.ck b/src/tests/userprog/open-bad-ptr.ck index c0a1153..45349e2 100644 --- a/src/tests/userprog/open-bad-ptr.ck +++ b/src/tests/userprog/open-bad-ptr.ck @@ -10,3 +10,4 @@ EOF (open-bad-ptr) begin open-bad-ptr: exit(-1) EOF +pass; diff --git a/src/tests/userprog/open-boundary.ck b/src/tests/userprog/open-boundary.ck index 40c9bf6..8060d22 100644 --- a/src/tests/userprog/open-boundary.ck +++ b/src/tests/userprog/open-boundary.ck @@ -8,3 +8,4 @@ check_expected ([<<'EOF']); (open-boundary) end open-boundary: exit(0) EOF +pass; diff --git a/src/tests/userprog/open-empty.ck b/src/tests/userprog/open-empty.ck index 5537d25..885fb41 100644 --- a/src/tests/userprog/open-empty.ck +++ b/src/tests/userprog/open-empty.ck @@ -7,3 +7,4 @@ check_expected ([<<'EOF']); (open-empty) end open-empty: exit(0) EOF +pass; diff --git a/src/tests/userprog/open-missing.ck b/src/tests/userprog/open-missing.ck index a1aaf79..d72d878 100644 --- a/src/tests/userprog/open-missing.ck +++ b/src/tests/userprog/open-missing.ck @@ -7,3 +7,4 @@ check_expected ([<<'EOF']); (open-missing) end open-missing: exit(0) EOF +pass; diff --git a/src/tests/userprog/open-normal.ck b/src/tests/userprog/open-normal.ck index 492433f..4f6c342 100644 --- a/src/tests/userprog/open-normal.ck +++ b/src/tests/userprog/open-normal.ck @@ -7,3 +7,4 @@ check_expected ([<<'EOF']); (open-normal) end open-normal: exit(0) EOF +pass; diff --git a/src/tests/userprog/open-null.ck b/src/tests/userprog/open-null.ck index 92188b3..b4a3bcb 100644 --- a/src/tests/userprog/open-null.ck +++ b/src/tests/userprog/open-null.ck @@ -10,3 +10,4 @@ EOF (open-null) begin open-null: exit(-1) EOF +pass; diff --git a/src/tests/userprog/open-twice.ck b/src/tests/userprog/open-twice.ck index d23ee84..64fa805 100644 --- a/src/tests/userprog/open-twice.ck +++ b/src/tests/userprog/open-twice.ck @@ -9,3 +9,4 @@ check_expected ([<<'EOF']); (open-twice) end open-twice: exit(0) EOF +pass; diff --git a/src/tests/userprog/read-bad-fd.ck b/src/tests/userprog/read-bad-fd.ck index 3dd5a93..5fedcc7 100644 --- a/src/tests/userprog/read-bad-fd.ck +++ b/src/tests/userprog/read-bad-fd.ck @@ -10,3 +10,4 @@ EOF (read-bad-fd) begin read-bad-fd: exit(-1) EOF +pass; diff --git a/src/tests/userprog/read-bad-ptr.ck b/src/tests/userprog/read-bad-ptr.ck index 2c95bc6..d10accf 100644 --- a/src/tests/userprog/read-bad-ptr.ck +++ b/src/tests/userprog/read-bad-ptr.ck @@ -12,3 +12,4 @@ EOF (read-bad-ptr) open "sample.txt" read-bad-ptr: exit(-1) EOF +pass; diff --git a/src/tests/userprog/read-boundary.ck b/src/tests/userprog/read-boundary.ck index 505b24b..08dc161 100644 --- a/src/tests/userprog/read-boundary.ck +++ b/src/tests/userprog/read-boundary.ck @@ -8,3 +8,4 @@ check_expected ([<<'EOF']); (read-boundary) end read-boundary: exit(0) EOF +pass; diff --git a/src/tests/userprog/read-normal.ck b/src/tests/userprog/read-normal.ck index b1139cf..0ed2998 100644 --- a/src/tests/userprog/read-normal.ck +++ b/src/tests/userprog/read-normal.ck @@ -10,3 +10,4 @@ check_expected ([<<'EOF']); (read-normal) end read-normal: exit(0) EOF +pass; diff --git a/src/tests/userprog/read-stdout.ck b/src/tests/userprog/read-stdout.ck index 758a1c2..7d87b52 100644 --- a/src/tests/userprog/read-stdout.ck +++ b/src/tests/userprog/read-stdout.ck @@ -10,3 +10,4 @@ EOF (read-stdout) begin read-stdout: exit(-1) EOF +pass; diff --git a/src/tests/userprog/read-zero.ck b/src/tests/userprog/read-zero.ck index 3d9b091..8346dbc 100644 --- a/src/tests/userprog/read-zero.ck +++ b/src/tests/userprog/read-zero.ck @@ -8,3 +8,4 @@ check_expected ([<<'EOF']); (read-zero) end read-zero: exit(0) EOF +pass; diff --git a/src/tests/userprog/rox-child.ck b/src/tests/userprog/rox-child.ck index 2994575..e6363fb 100644 --- a/src/tests/userprog/rox-child.ck +++ b/src/tests/userprog/rox-child.ck @@ -17,3 +17,4 @@ child-rox: exit(12) (rox-child) end rox-child: exit(0) EOF +pass; diff --git a/src/tests/userprog/rox-multichild.ck b/src/tests/userprog/rox-multichild.ck index 704ccce..14b27db 100644 --- a/src/tests/userprog/rox-multichild.ck +++ b/src/tests/userprog/rox-multichild.ck @@ -41,3 +41,4 @@ child-rox: exit(12) (rox-multichild) end rox-multichild: exit(0) EOF +pass; diff --git a/src/tests/userprog/rox-simple.ck b/src/tests/userprog/rox-simple.ck index 67c3116..c9dcc66 100644 --- a/src/tests/userprog/rox-simple.ck +++ b/src/tests/userprog/rox-simple.ck @@ -10,3 +10,4 @@ check_expected ([<<'EOF']); (rox-simple) end rox-simple: exit(0) EOF +pass; diff --git a/src/tests/userprog/sc-bad-arg.ck b/src/tests/userprog/sc-bad-arg.ck index a255768..8981105 100644 --- a/src/tests/userprog/sc-bad-arg.ck +++ b/src/tests/userprog/sc-bad-arg.ck @@ -6,3 +6,4 @@ check_expected ([<<'EOF']); (sc-bad-arg) begin sc-bad-arg: exit(-1) EOF +pass; diff --git a/src/tests/userprog/sc-bad-sp.ck b/src/tests/userprog/sc-bad-sp.ck index d0622d4..498cec1 100644 --- a/src/tests/userprog/sc-bad-sp.ck +++ b/src/tests/userprog/sc-bad-sp.ck @@ -6,3 +6,4 @@ check_expected ([<<'EOF']); (sc-bad-sp) begin sc-bad-sp: exit(-1) EOF +pass; diff --git a/src/tests/userprog/sc-boundary-2.ck b/src/tests/userprog/sc-boundary-2.ck index 61c9f23..43766bf 100644 --- a/src/tests/userprog/sc-boundary-2.ck +++ b/src/tests/userprog/sc-boundary-2.ck @@ -6,3 +6,4 @@ check_expected ([<<'EOF']); (sc-boundary-2) begin sc-boundary-2: exit(67) EOF +pass; diff --git a/src/tests/userprog/sc-boundary.ck b/src/tests/userprog/sc-boundary.ck index f00c3eb..3f7cbaf 100644 --- a/src/tests/userprog/sc-boundary.ck +++ b/src/tests/userprog/sc-boundary.ck @@ -6,3 +6,4 @@ check_expected ([<<'EOF']); (sc-boundary) begin sc-boundary: exit(42) EOF +pass; diff --git a/src/tests/userprog/wait-bad-pid.ck b/src/tests/userprog/wait-bad-pid.ck index 3c36a53..db63fb9 100644 --- a/src/tests/userprog/wait-bad-pid.ck +++ b/src/tests/userprog/wait-bad-pid.ck @@ -10,3 +10,4 @@ EOF (wait-bad-pid) begin wait-bad-pid: exit(-1) EOF +pass; diff --git a/src/tests/userprog/wait-killed.ck b/src/tests/userprog/wait-killed.ck index 6bc5c20..5df0e9c 100644 --- a/src/tests/userprog/wait-killed.ck +++ b/src/tests/userprog/wait-killed.ck @@ -10,3 +10,4 @@ child-bad: exit(-1) (wait-killed) end wait-killed: exit(0) EOF +pass; diff --git a/src/tests/userprog/wait-simple.ck b/src/tests/userprog/wait-simple.ck index 8e53e8c..93dd577 100644 --- a/src/tests/userprog/wait-simple.ck +++ b/src/tests/userprog/wait-simple.ck @@ -10,3 +10,4 @@ child-simple: exit(81) (wait-simple) end wait-simple: exit(0) EOF +pass; diff --git a/src/tests/userprog/wait-twice.ck b/src/tests/userprog/wait-twice.ck index e013123..6d53843 100644 --- a/src/tests/userprog/wait-twice.ck +++ b/src/tests/userprog/wait-twice.ck @@ -11,3 +11,4 @@ child-simple: exit(81) (wait-twice) end wait-twice: exit(0) EOF +pass; diff --git a/src/tests/userprog/write-bad-fd.ck b/src/tests/userprog/write-bad-fd.ck index 23cee06..8da7a8b 100644 --- a/src/tests/userprog/write-bad-fd.ck +++ b/src/tests/userprog/write-bad-fd.ck @@ -10,3 +10,4 @@ EOF (write-bad-fd) begin write-bad-fd: exit(-1) EOF +pass; diff --git a/src/tests/userprog/write-bad-ptr.ck b/src/tests/userprog/write-bad-ptr.ck index 84d3372..ad9f399 100644 --- a/src/tests/userprog/write-bad-ptr.ck +++ b/src/tests/userprog/write-bad-ptr.ck @@ -12,3 +12,4 @@ EOF (write-bad-ptr) open "sample.txt" write-bad-ptr: exit(-1) EOF +pass; diff --git a/src/tests/userprog/write-boundary.ck b/src/tests/userprog/write-boundary.ck index 720e3cd..7883781 100644 --- a/src/tests/userprog/write-boundary.ck +++ b/src/tests/userprog/write-boundary.ck @@ -8,3 +8,4 @@ check_expected ([<<'EOF']); (write-boundary) end write-boundary: exit(0) EOF +pass; diff --git a/src/tests/userprog/write-normal.ck b/src/tests/userprog/write-normal.ck index c78cfb5..9fa6024 100644 --- a/src/tests/userprog/write-normal.ck +++ b/src/tests/userprog/write-normal.ck @@ -9,3 +9,4 @@ check_expected ([<<'EOF']); (write-normal) end write-normal: exit(0) EOF +pass; diff --git a/src/tests/userprog/write-stdin.ck b/src/tests/userprog/write-stdin.ck index 3aca818..a6caf81 100644 --- a/src/tests/userprog/write-stdin.ck +++ b/src/tests/userprog/write-stdin.ck @@ -10,3 +10,4 @@ EOF (write-stdin) begin write-stdin: exit(-1) EOF +pass; diff --git a/src/tests/userprog/write-zero.ck b/src/tests/userprog/write-zero.ck index 5fe4385..cc4cd60 100644 --- a/src/tests/userprog/write-zero.ck +++ b/src/tests/userprog/write-zero.ck @@ -8,3 +8,4 @@ check_expected ([<<'EOF']); (write-zero) end write-zero: exit(0) EOF +pass; diff --git a/src/tests/vm/Make.tests b/src/tests/vm/Make.tests index 4a5820d..460bfd0 100644 --- a/src/tests/vm/Make.tests +++ b/src/tests/vm/Make.tests @@ -1,7 +1,5 @@ # -*- makefile -*- -PINTOSFLAGS += --swap-disk=4 - tests/vm_TESTS = $(addprefix tests/vm/,pt-grow-stack pt-grow-pusha \ pt-grow-bad pt-big-stk-obj pt-bad-addr pt-bad-read pt-write-code \ pt-write-code2 pt-grow-stk-sc page-linear page-parallel page-merge-seq \ diff --git a/src/tests/vm/mmap-bad-fd.ck b/src/tests/vm/mmap-bad-fd.ck index 2873af1..f3f58d5 100644 --- a/src/tests/vm/mmap-bad-fd.ck +++ b/src/tests/vm/mmap-bad-fd.ck @@ -12,3 +12,4 @@ EOF (mmap-bad-fd) try to mmap invalid fd mmap-bad-fd: exit(-1) EOF +pass; diff --git a/src/tests/vm/mmap-clean.ck b/src/tests/vm/mmap-clean.ck index 29e44aa..1666d6c 100644 --- a/src/tests/vm/mmap-clean.ck +++ b/src/tests/vm/mmap-clean.ck @@ -13,3 +13,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (mmap-clean) file change was retained after munmap (mmap-clean) end EOF +pass; diff --git a/src/tests/vm/mmap-close.ck b/src/tests/vm/mmap-close.ck index 6c7a199..d15e41a 100644 --- a/src/tests/vm/mmap-close.ck +++ b/src/tests/vm/mmap-close.ck @@ -8,3 +8,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (mmap-close) mmap "sample.txt" (mmap-close) end EOF +pass; diff --git a/src/tests/vm/mmap-exit.ck b/src/tests/vm/mmap-exit.ck index 7f11742..457d34a 100644 --- a/src/tests/vm/mmap-exit.ck +++ b/src/tests/vm/mmap-exit.ck @@ -14,3 +14,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (mmap-exit) close "sample.txt" (mmap-exit) end EOF +pass; diff --git a/src/tests/vm/mmap-inherit.ck b/src/tests/vm/mmap-inherit.ck index 59b5389..7e69122 100644 --- a/src/tests/vm/mmap-inherit.ck +++ b/src/tests/vm/mmap-inherit.ck @@ -13,3 +13,4 @@ child-inherit: exit(-1) (mmap-inherit) end mmap-inherit: exit(0) EOF +pass; diff --git a/src/tests/vm/mmap-misalign.ck b/src/tests/vm/mmap-misalign.ck index fc1234d..145a2e8 100644 --- a/src/tests/vm/mmap-misalign.ck +++ b/src/tests/vm/mmap-misalign.ck @@ -8,3 +8,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (mmap-misalign) try to mmap at misaligned address (mmap-misalign) end EOF +pass; diff --git a/src/tests/vm/mmap-null.ck b/src/tests/vm/mmap-null.ck index 7cfc1f1..aacdd65 100644 --- a/src/tests/vm/mmap-null.ck +++ b/src/tests/vm/mmap-null.ck @@ -8,3 +8,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (mmap-null) try to mmap at address 0 (mmap-null) end EOF +pass; diff --git a/src/tests/vm/mmap-over-code.ck b/src/tests/vm/mmap-over-code.ck index bb8cb2d..b5b23c7 100644 --- a/src/tests/vm/mmap-over-code.ck +++ b/src/tests/vm/mmap-over-code.ck @@ -8,3 +8,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (mmap-over-code) try to mmap over code segment (mmap-over-code) end EOF +pass; diff --git a/src/tests/vm/mmap-over-data.ck b/src/tests/vm/mmap-over-data.ck index 15a4f6d..98770cc 100644 --- a/src/tests/vm/mmap-over-data.ck +++ b/src/tests/vm/mmap-over-data.ck @@ -8,3 +8,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (mmap-over-data) try to mmap over data segment (mmap-over-data) end EOF +pass; diff --git a/src/tests/vm/mmap-over-stk.ck b/src/tests/vm/mmap-over-stk.ck index 3b7ac98..e6880cf 100644 --- a/src/tests/vm/mmap-over-stk.ck +++ b/src/tests/vm/mmap-over-stk.ck @@ -8,3 +8,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (mmap-over-stk) try to mmap over stack segment (mmap-over-stk) end EOF +pass; diff --git a/src/tests/vm/mmap-overlap.ck b/src/tests/vm/mmap-overlap.ck index f8b58ab..f13801e 100644 --- a/src/tests/vm/mmap-overlap.ck +++ b/src/tests/vm/mmap-overlap.ck @@ -10,3 +10,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (mmap-overlap) try to mmap "zeros" again (mmap-overlap) end EOF +pass; diff --git a/src/tests/vm/mmap-read.ck b/src/tests/vm/mmap-read.ck index 9978310..95ab790 100644 --- a/src/tests/vm/mmap-read.ck +++ b/src/tests/vm/mmap-read.ck @@ -8,3 +8,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (mmap-read) mmap "sample.txt" (mmap-read) end EOF +pass; diff --git a/src/tests/vm/mmap-remove.ck b/src/tests/vm/mmap-remove.ck index 1b8a311..d3cc938 100644 --- a/src/tests/vm/mmap-remove.ck +++ b/src/tests/vm/mmap-remove.ck @@ -11,3 +11,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (mmap-remove) create "another" (mmap-remove) end EOF +pass; diff --git a/src/tests/vm/mmap-shuffle.ck b/src/tests/vm/mmap-shuffle.ck index fcfa0b2..c158301 100644 --- a/src/tests/vm/mmap-shuffle.ck +++ b/src/tests/vm/mmap-shuffle.ck @@ -44,3 +44,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [< 1, [<<'EOF']); (mmap-twice) compare mmap'd file 1 against data (mmap-twice) end EOF +pass; diff --git a/src/tests/vm/mmap-write.ck b/src/tests/vm/mmap-write.ck index d48ce3a..d2c9cc5 100644 --- a/src/tests/vm/mmap-write.ck +++ b/src/tests/vm/mmap-write.ck @@ -10,3 +10,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (mmap-write) compare read data against written data (mmap-write) end EOF +pass; diff --git a/src/tests/vm/mmap-zero.ck b/src/tests/vm/mmap-zero.ck index 1625798..0130fbd 100644 --- a/src/tests/vm/mmap-zero.ck +++ b/src/tests/vm/mmap-zero.ck @@ -9,3 +9,4 @@ check_expected ([<<'EOF']); (mmap-zero) mmap "empty" mmap-zero: exit(-1) EOF +pass; diff --git a/src/tests/vm/page-linear.ck b/src/tests/vm/page-linear.ck index c4a26c8..dcbc884 100644 --- a/src/tests/vm/page-linear.ck +++ b/src/tests/vm/page-linear.ck @@ -11,3 +11,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (page-linear) read pass (page-linear) end EOF +pass; diff --git a/src/tests/vm/page-merge-par.ck b/src/tests/vm/page-merge-par.ck index 9f6205a..31f8aa7 100644 --- a/src/tests/vm/page-merge-par.ck +++ b/src/tests/vm/page-merge-par.ck @@ -26,3 +26,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (page-merge-par) success, buf_idx=1,048,576 (page-merge-par) end EOF +pass; diff --git a/src/tests/vm/page-merge-seq.ck b/src/tests/vm/page-merge-seq.ck index 7bfe275..d78f69d 100644 --- a/src/tests/vm/page-merge-seq.ck +++ b/src/tests/vm/page-merge-seq.ck @@ -26,3 +26,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (page-merge-seq) success, buf_idx=1,032,192 (page-merge-seq) end EOF +pass; diff --git a/src/tests/vm/page-parallel.ck b/src/tests/vm/page-parallel.ck index 14b37df..c6817b7 100644 --- a/src/tests/vm/page-parallel.ck +++ b/src/tests/vm/page-parallel.ck @@ -12,3 +12,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (page-parallel) wait for child 2 (page-parallel) end EOF +pass; diff --git a/src/tests/vm/page-shuffle.ck b/src/tests/vm/page-shuffle.ck index 88ec934..6447d38 100644 --- a/src/tests/vm/page-shuffle.ck +++ b/src/tests/vm/page-shuffle.ck @@ -41,3 +41,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [< 1, [<<'EOF']); (pt-big-stk-obj) cksum: 3256410166 (pt-big-stk-obj) end EOF +pass; diff --git a/src/tests/vm/pt-grow-bad.ck b/src/tests/vm/pt-grow-bad.ck index cc3d31e..a5775c7 100644 --- a/src/tests/vm/pt-grow-bad.ck +++ b/src/tests/vm/pt-grow-bad.ck @@ -6,3 +6,4 @@ check_expected ([<<'EOF']); (pt-grow-bad) begin pt-grow-bad: exit(-1) EOF +pass; diff --git a/src/tests/vm/pt-grow-pusha.ck b/src/tests/vm/pt-grow-pusha.ck index 8653888..5000966 100644 --- a/src/tests/vm/pt-grow-pusha.ck +++ b/src/tests/vm/pt-grow-pusha.ck @@ -6,3 +6,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (pt-grow-pusha) begin (pt-grow-pusha) end EOF +pass; diff --git a/src/tests/vm/pt-grow-stack.ck b/src/tests/vm/pt-grow-stack.ck index 92d8f93..1e669db 100644 --- a/src/tests/vm/pt-grow-stack.ck +++ b/src/tests/vm/pt-grow-stack.ck @@ -7,3 +7,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (pt-grow-stack) cksum: 3424492700 (pt-grow-stack) end EOF +pass; diff --git a/src/tests/vm/pt-grow-stk-sc.ck b/src/tests/vm/pt-grow-stk-sc.ck index 005f6f4..23d3b02 100644 --- a/src/tests/vm/pt-grow-stk-sc.ck +++ b/src/tests/vm/pt-grow-stk-sc.ck @@ -12,3 +12,4 @@ check_expected (IGNORE_EXIT_CODES => 1, [<<'EOF']); (pt-grow-stk-sc) compare written data against read data (pt-grow-stk-sc) end EOF +pass; diff --git a/src/tests/vm/pt-write-code2.ck b/src/tests/vm/pt-write-code2.ck index ac8ff2a..69ffc77 100644 --- a/src/tests/vm/pt-write-code2.ck +++ b/src/tests/vm/pt-write-code2.ck @@ -7,3 +7,4 @@ check_expected ([<<'EOF']); (pt-write-code2) open "sample.txt" pt-write-code2: exit(-1) EOF +pass; diff --git a/tests/Makefile b/tests/Makefile index 102e1e9..f8cd357 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -19,7 +19,7 @@ cd $@/src && $(MAKE) -s clean endef define run-tests -cd $@/src/$(PROJECT) && $(MAKE) check +cd $@/src/$(PROJECT) && time $(MAKE) check endef define grade-tests