#!/usr/bin/perl # test.pl - Don Yang (uguu.org) # Regression test for yuriko/nozomi # # 02/12/06 use strict; my ($TEST_DIR); $TEST_DIR = "tests"; # Get list of input files for testing sub GetTestCases($$) { my ($gold, $test) = @_; my (@list, $file); local (*DIR); @list = (); opendir DIR, $TEST_DIR or die $!; while( $file = readdir DIR ) { next unless $file =~ /^mono/ || $file =~ /^poly/; push @list, "$TEST_DIR/$file"; } push @list, $gold, $test; return @list; } # Compile source with MSVC toolchain sub CompileWithMSVC($$) { my ($infile, $outfile) = @_; system "cl -nologo -Ox $infile -link -out:$outfile ". "-opt:ref -incremental:no -nodefaultlib -release kernel32.lib libc.lib"; die "cl returned $?\n" if $? != 0; } # Compile source with GCC toolchain sub CompileWithGCC($$) { my ($infile, $outfile) = @_; system "gcc -O3 $infile -o $outfile"; die "gcc returned $?\n" if $? != 0; } # Compare two outputs sub CompareLists($$) { my ($gold, $test) = @_; my ($i); return 1 if $#$gold != $#$test; for($i = 0; $i <= $#$gold; $i++) { return 1 if $$gold[$i] ne $$test[$i]; } return 0; } # Test that output of two programs are identical sub TestPair($$$) { my ($gold, $test, $input) = @_; my (@gold_output, @test_output); @gold_output = `./$gold < $input`; @test_output = `./$test < $input`; if( CompareLists(\@gold_output, \@test_output) ) { die "Output differ for ($test, $input, 0)\n"; } @gold_output = `./$gold $input`; @test_output = `./$test $input`; if( CompareLists(\@gold_output, \@test_output) ) { die "Output differ for ($test, $input, 1)\n"; } @gold_output = `./$gold $input $input`; @test_output = `./$test $input $input`; if( CompareLists(\@gold_output, \@test_output) ) { die "Output differ for ($test, $input, 2)\n"; } } # Copy one file to another sub CopyFile($$) { my ($infile, $outfile) = @_; my ($line); local (*INFILE); local (*OUTFILE); open INFILE, "< $infile" or die $!; open OUTFILE, "> $outfile" or die $!; while( $line = ) { print OUTFILE $line; } close INFILE; close OUTFILE; } # Test source for both versions of the program sub RunTests($$) { my ($gold, $test) = @_; my (@test_list, @output1, @output2); my ($op, $input); @test_list = GetTestCases($gold, $test); # Check that both of modes of operation are still backward compatible foreach $op ("yuriko", "nozomi") { CopyFile($gold, "${op}_gold.c"); CopyFile($test, "${op}_test.c"); CompileWithMSVC("${op}_gold.c", "${op}_gold.exe"); CompileWithMSVC("${op}_test.c", "${op}_test.exe"); foreach $input (@test_list) { TestPair("${op}_gold.exe", "${op}_test.exe", $input); } CompileWithGCC("${op}_gold.c", "${op}_gold.exe"); CompileWithGCC("${op}_test.c", "${op}_test.exe"); foreach $input (@test_list) { TestPair("${op}_gold.exe", "${op}_test.exe", $input); } } # Check that the two modes of operation are indeed separate modes CompileWithMSVC("yuriko_test.c", "yuriko_test.exe"); CompileWithMSVC("nozomi_test.c", "nozomi_test.exe"); foreach $input (@test_list) { @output1 = `./yuriko_test.exe $input`; @output2 = `./nozomi_test.exe $input`; if( CompareLists(\@output1, \@output2) == 0 ) { die "Expected different output from different modes\n"; } } CompileWithGCC("yuriko_test.c", "yuriko_test.exe"); CompileWithGCC("nozomi_test.c", "nozomi_test.exe"); foreach $input (@test_list) { @output1 = `./yuriko_test.exe $input`; @output2 = `./nozomi_test.exe $input`; if( CompareLists(\@output1, \@output2) == 0 ) { die "Expected different output from different modes\n"; } } # Cleanup unlink "yuriko_gold.c", "nozomi_gold.c", "yuriko_gold.exe", "nozomi_gold.exe", "yuriko_gold.obj", "nozomi_gold.obj", "yuriko_test.c", "nozomi_test.c", "yuriko_test.exe", "nozomi_test.exe", "yuriko_test.obj", "nozomi_test.obj"; print "PASS\n"; } die "$0 \n" unless $#ARGV == 1; RunTests($ARGV[0], $ARGV[1]);