#!/usr/bin/env perl my $interpreter = shift; my $test = shift; my $disabled_tests = shift; my $dump_output = shift; my $output = $test; my $stdout = $test.'.stdout'; my $stderr = $test.'.stderr'; $output =~ s/\.exe$/.output/; my $timeout_in_minutes = 2; my $test_binary = $test; if ($test =~ /.*\|.*/) { my @values = split(/\|/, $test); my $binary = @values[0]; my $test_name = @values[1]; $test_binary = $binary; $test = $test_name . "_" . $binary; $stdout = $test.'.stdout'; $stderr = $test.'.stderr'; $output = $test; #This is a silly workaround, but all tests that use extra parameters need a larger timeout. $timeout_in_minutes = 15; } $ENV{'TEST_DRIVER_TIMEOUT_SEC'} = $timeout_in_minutes * 60; $| = 0; print "Testing $test... "; foreach $disabled (split (/ /, $disabled_tests)) { $disabled =~ s/^\s+|\s+$//g; if ($disabled eq $test) { print "disabled.\n"; exit (0); } } my $res; my $cpid = fork (); if (!defined ($cpid)) { $res = system("$interpreter @ARGV $test_binary 2>$stderr 1>$stdout"); } elsif ($cpid == 0) { exec ("$interpreter @ARGV $test_binary 2>$stderr 1>$stdout") || die "Cannot exec: $!"; } else { # in the parent, setup the alarm # test must complete in 2 minutes or it is considered buggy my $timeout = $timeout_in_minutes * 60; alarm ($timeout); $SIG{ALRM} = sub { print "failed after $timeout seconds timeout.\n"; dump_files (); # process group kill kill (-9, $cpid); exit (3); }; $res = wait (); $SIG{ALRM} = sub {}; $res = $? >> 8; } if ($res) { printf ("failed $? (%d) signal (%d).\n", $? >> 8, $? & 127); dump_files (); if (($? & 127) == 2) { exit (2); } else { exit (1); } } if (-f $output && (read_file ($output) ne read_file ($stdout))) { print "failed output.\n"; dump_files (); exit (1); } print "pass.\n"; unlink ($stderr); exit (0); sub dump_files { if ($dump_output ne "dump-output") { return; } printf ("----STDOUT-----\n"); print read_file($stdout); printf ("----STDERR-----\n"); print read_file($stderr); printf ("---------------\n"); } sub read_file { local ($/); my $out = shift; open (F, "<$out") || die $!; $out = ; close(F); return $out; }