7 use Getopt
::Long
qw(GetOptions);
8 use Pod
::Usage
qw(pod2usage);
10 use File
::Basename
qw(fileparse);
11 use File
::Compare
qw(compare compare_text);
12 use File
::Copy
qw(move);
13 use File
::Path
qw(mkpath rmtree);
15 #sub debugprint { print (pop() . "\n"); }
20 my ($clean, $diff, $golden, $nasm, $quiet, $testpath) = @_;
21 my ($stdoutfile, $stderrfile) = (".stdout", ".stderr");
23 my ($testname, $ignoredpath, $ignoredsuffix) = fileparse
($testpath, ".asm");
26 my $outputdir = $golden ?
"golden" : "testresults";
28 mkdir "$outputdir" unless -d
"$outputdir";
31 rmtree
"$outputdir/$testname";
35 if(-d
"$outputdir/$testname") {
36 rmtree
"$outputdir/$testname";
39 open(TESTFILE
, '<', $testpath) or (warn "Can't open $testpath\n", return);
42 #See if there is a test case
43 last unless /Testname=(.*);\s*Arguments=(.*);\s*Files=(.*)/;
44 my ($subname, $arguments, $files) = ($1, $2, $3);
45 debugprint
("$subname | $arguments | $files");
47 #Call nasm with this test case
48 system("$nasm $arguments $testpath > $stdoutfile 2> $stderrfile");
49 debugprint
("$nasm $arguments $testpath > $stdoutfile 2> $stderrfile ----> $?");
51 #Move the output to the test dir
52 mkpath
("$outputdir/$testname/$subname");
53 foreach(split / /,$files) {
55 move
($_, "$outputdir/$testname/$subname/$_") or die $!
58 unlink ("$stdoutfile", "$stderrfile"); #Just to be sure
61 print "Test $testname/$subname created.\n" unless $quiet;
63 #Compare them with the golden files
66 foreach(split / /, $files) {
67 if(-f
"$outputdir/$testname/$subname/$_") {
69 if($_ eq $stdoutfile or $_ eq $stderrfile) {
70 #Compare stdout and stderr in text mode so line ending changes won't matter
71 $temp = compare_text
("$outputdir/$testname/$subname/$_", "golden/$testname/$subname/$_",
72 sub { my ($a, $b) = @_;
77 $temp = compare
("$outputdir/$testname/$subname/$_", "golden/$testname/$subname/$_");
83 push @failedfiles, $_;
84 } elsif($temp == -1) {
86 print "Can't compare at $testname/$subname file $_\n";
89 } elsif (-f
"golden/$testname/$subname/$_") {
90 #File exists in golden but not in output
92 push @failedfiles, $_;
97 print "Test $testname/$subname succeeded.\n" unless $quiet;
98 } elsif ($result == 1) {
99 print "Test $testname/$subname failed on @failedfiles.\n";
102 if($_ eq $stdoutfile or $_ eq $stderrfile) {
103 system "diff golden/$testname/$subname/$_ $outputdir/$testname/$subname/$_";
109 die "Impossible result";
123 GetOptions
('clean' => \
$clean,
125 'golden' => \
$golden,
127 'verbose' => \
$verbose,
131 pod2usage
() if $help;
132 die "Please specify either --nasm or --clean. Use --help for help.\n"
133 unless $nasm or $clean;
134 die "Please specify the test files, e.g. *.asm\n" unless @ARGV;
136 unless (!defined $nasm or -x
$nasm) {
137 warn "Warning: $nasm may not be executable. Expect problems.\n\n";
141 perform
($clean, $diff, $golden, $nasm, ! $verbose, $_) foreach @ARGV;
148 performtest.pl - NASM regression tester based on golden files
152 performtest.pl [options] [testfile.asm ...]
154 Runs NASM on the specified test files and compare the results
155 with "golden" output files.
158 --clean Clean up test results (or golden files with --golden)
159 --diff Execute diff when .stdout or .stderr don't match
160 --golden Create golden files
162 --nasm=file Specify the file name for the NASM executable, e.g. ../nasm
163 --verbose Get more output
165 If --clean is not specified, --nasm is required.
168 One or more files that NASM should be tested with,
169 often *.asm in the test directory.
170 It should contain one or more option lines at the start,
171 in the following format:
173 ;Testname=<testname>; Arguments=<arguments to nasm>; Files=<output files>
175 If no such lines are found at the start, the file is skipped.
176 testname should ideally describe the arguments, eg. unoptimized for -O0.
177 arguments can be an optimization level (-O), an output format (-f),
178 an output file specifier (-o) etc.
179 The output files should be a space seperated list of files that will
180 be checked for regressions. This should often be the output file
181 and the special files .stdout and .stderr.
183 Any mismatch could be a regression,
184 but it doesn't have to be. COFF files have a timestamp which
185 makes this method useless. ELF files have a comment section
186 with the current version of NASM, so they will change each version number.