X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=build%2Ftester;h=f66713e18c45bd4c0f3d12faaa4bc806d6f71696;hb=bfca2c42bc0e749f8611339568be502f22ac5e9c;hp=a9bdfd60f7de2f2c350942917361814b7e605dd0;hpb=45272d09316ecfba01f10e1968bd6f9a921909d2;p=libucw.git diff --git a/build/tester b/build/tester index a9bdfd60..f66713e1 100755 --- a/build/tester +++ b/build/tester @@ -1,6 +1,31 @@ #!/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; @@ -26,53 +51,88 @@ while (<>) { } } +if (! -d "$rundir/tmp") { + mkdir "$rundir/tmp" or die "Unable to create $rundir/tmp: $!"; +} + 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 $redirs = ""; + if (defined $tt->{'In'}) { - $ifi = "run/tmp/test$i.in"; - open X, ">$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"; } else { - $run .= " {'Out'}) { - $ofi = "run/tmp/test$i.out"; - unlink $ofi; - $run .= " >$ofi"; + my $ofi = "tmp/test$i.out"; + unlink "$rundir/$ofi"; + $redirs .= " >$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 @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; + } } - `$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, "<$ofi" or die "Unable to read $ofi"; + my $ec = $? / 256; + my $expect_ec = $tt->{'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; + + system "rm -f $rundir/tmp/test$i.*"; print "OK\n"; }