From 354ad36447e1ab498e42fdabfd3f2d9179f187e2 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sun, 18 Nov 2007 19:33:08 +0100 Subject: [PATCH] A new unit test module. Explicit input and output files can be defined now, the expected exit code of the process can be set and, last but not least, test cases can be named to simplify orientation in long test suites. The `run' directory is no longer hard-wired, the tester now accepts --verbose and --rundir switches. The makefiles now pass --rundir=run and also $TESTERFLAGS, allowing to turn on the verbose mode at request. --- build/Makebottom | 2 +- build/tester | 104 +++++++++++++++++++++++++++++++++++++---------- 2 files changed, 84 insertions(+), 22 deletions(-) diff --git a/build/Makebottom b/build/Makebottom index bf342b0c..a474614b 100644 --- a/build/Makebottom +++ b/build/Makebottom @@ -126,7 +126,7 @@ $(o)/%-t: $(o)/%-tt.o $(TESTING_DEPS) $(o)/%.test: $(s)/%.t $(s)/build/tester $(M)TEST $@ - $(Q)$(s)/build/tester $< && touch $@ + $(Q)$(s)/build/tester --rundir=run $(TESTERFLAGS) $< && touch $@ # Rules for binaries diff --git a/build/tester b/build/tester index 73794d93..fd6cce3f 100755 --- a/build/tester +++ b/build/tester @@ -1,8 +1,32 @@ #!/usr/bin/perl # A simple unit testing script -# (c) 2004 Martin Mares +# (c) 2004--2007 Martin Mares # (c) 2007 Pavel Charvat +# Tests in the test file have a syntax similar to mail headers, +# individual test case are separated by blank lines and they can contain +# the following fields: +# +# Name: name of the case (default: sequence number since start of file) +# Run: command to run (default: command from the previous test case) +# This can be an arbitrary shell pipeline, sequences $0 to $9 are +# replaced by file names of In or Out files (see below). +# In: lines to pass to the program as standard input +# Out: lines to expect at the program's standard output +# In: lines to pass to the program as input file +# Out: lines to expect from the program in output file +# Both In and Out can be specified simultaneously if we +# are testing a program which modifies some of its input files. +# Exit: expected exit code of the program (default: 0) + +use Getopt::Long; + +my $verbose = 0; +my $rundir = "."; +GetOptions("verbose!" => \$verbose, + "rundir=s" => \$rundir) + or die "Usage: tester [--verbose] [--rundir=] \n"; + my @tests = (); my $tt; my $append_to; @@ -30,50 +54,88 @@ while (<>) { my $i = 0; my $errors = 0; my $prev_run = undef; -foreach $tt (@tests) { +TEST: foreach $tt (@tests) { $i++; - print "Test $i: "; + my $name = $tt->{'Name'} || $i; + print "Test $name: "; $run = ($tt->{'Run'} || $prev_run) or die "Don't know what to run"; $prev_run = $run; - my ($ifi, $ofi); + + my @out_files = (); + my @out_checks = (); + my @temps = (); + my $redirs = ""; + if (defined $tt->{'In'}) { - $ifi = "tmp/test$i.in"; - open X, ">run/$ifi" or die "Unable to create $ifi"; + my $ifi = "tmp/test$i.in"; + open X, ">$rundir/$ifi" or die "Unable to create $ifi"; print X $tt->{'In'}, "\n"; close X; - $run .= " <$ifi"; + $redirs .= " <$ifi"; + push @temps, $ifi; } else { - $run .= " {'Out'}) { - $ofi = "tmp/test$i.out"; - unlink "run/$ofi"; - $run .= " >$ofi"; + my $ofi = "tmp/test$i.out"; + unlink "$rundir/$ofi"; + $redirs .= " >$ofi"; + push @temps, $ofi; + push @out_files, $ofi; + push @out_checks, $tt->{'Out'}; } else { - $run .= " >/dev/null"; + $redirs .= " >/dev/null"; + } + foreach my $arg (0..9) { + my $f = "tmp/test$i.$arg"; + if (defined $tt->{"Out$arg"}) { + unlink "$rundir/$f"; + push @temps, $f; + push @out_files, $f; + push @out_checks, $tt->{"Out$arg"}; + } + if (defined $tt->{"In$arg"}) { + open X, ">$rundir/$f" or die "Unable to create $f"; + print X $tt->{"In$arg"}, "\n"; + close X; + push @temps, $f; + } } - system "cd run && ( $run )"; - if ($?) { - print "FAILED with exit code $?\n"; + $run =~ s/\$(\d)/tmp\/test$i.$1/g; + print "(running $run) " if $verbose; + system "cd $rundir && ( $run ) $redirs"; + if ($? % 256) { + print "FAILED with status code $?\n"; $errors++; next; } - if (defined $tt->{'Out'}) { - open X, "{'Exit'} || 0; + if ($ec != $expect_ec) { + print "FAILED: unexpected exit code $ec\n"; + $errors++; + next; + } + + for (my $i=0; $i<=$#out_files; $i++) { + my $ofi = $out_files[$i]; + open X, "<$rundir/$ofi" or die "Unable to read $ofi"; my $out; { local $/ = undef; $out = ; } close X; - if ($out ne $tt->{'Out'} . "\n") { + if ($out ne $out_checks[$i] . "\n") { print "FAILED (see $ofi)\n"; $errors++; - next; + next TEST; } } - unlink $ifi if $ifi; - unlink $ofi if $ofi; + + foreach my $f (@temps) { + unlink "$rundir/$f"; + } print "OK\n"; } -- 2.39.2