]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/valgrind/src/valgrind-3.6.0-svn/tests/vg_regtest.in
update
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / tests / vg_regtest.in
index 15c53f14a5a6796afa57e58cb45e4fe44a0f1272..6712a0495b53560408101fe53c818941daea429a 100755 (executable)
@@ -37,6 +37,8 @@
 #   --valgrind-lib: valgrind libraries to use.  Default is $tests_dir/.in_place.
 #               (This option should probably only be used in conjunction with
 #               --valgrind.)
+#   --keep-unfiltered: keep a copy of the unfiltered output/error output
+#     of each test by adding an extension .unfiltered.out
 #
 # The easiest way is to run all tests in valgrind/ with (assuming you installed
 # in $PREFIX):
 #                                                    multiple are allowed)
 #   - stdout_filter: <filter to run stdout through> (default: none)
 #   - stderr_filter: <filter to run stderr through> (default: ./filter_stderr)
+#
+#   - progB:  <prog to run in parallel with prog>   (default: none)
+#   - argsB:  <args for progB>                      (default: none)
+#   - stdinB: <input file for progB>                (default: none)
+#   - stdoutB_filter: <filter progB stdout through> (default: none)
+#   - stderrB_filter: <filter progB stderr through> (default: ./filter_stderr)
+#
 #   - prereq: <prerequisite command>                (default: none)
 #   - post: <post-test check command>               (default: none)
 #   - cleanup: <post-test cleanup cmd>              (default: none)
 #
+# If prog or probB is a relative path, it will be prefix with the test directory.
 # Note that filters are necessary for stderr results to filter out things that
 # always change, eg. process id numbers.
+# Note that if a progB is specified, it is started in background (before prog).
 #
 # Expected stdout (filtered) is kept in <test>.stdout.exp* (can be more
 # than one expected output).  It can be missing if it would be empty.  Expected
 # one stderr.exp* file.  Any .exp* file that ends in '~' or '#' is ignored;
 # this is because Emacs creates temporary files of these names.
 #
+# Expected output for progB is handled similarly, except that
+# expected stdout and stderr for progB are in  <test>.stdoutB.exp*
+# and <test>.stderrB.exp*.
+#
 # If results don't match, the output can be found in <test>.std<strm>.out,
 # and the diff between expected and actual in <test>.std<strm>.diff*.
+# (for progB, in <test>.std<strm>2.out and <test>.std<strm>2.diff*).
 #
 # The prerequisite command, if present, works like this:
 # - if it returns 0 the test is run
@@ -99,10 +115,10 @@ use strict;
 # Global vars
 #----------------------------------------------------------------------------
 my $usage="\n"
-          . "Usage:\n"
-          . "   vg_regtest [--all, --valgrind, --valgrind-lib]\n"
-          . "   Use EXTRA_REGTEST_OPTS to supply extra args for all tests\n"
-          . "\n";
+     . "Usage:\n"
+     . "   vg_regtest [--all, --valgrind, --valgrind-lib, --keep-unfiltered]\n"
+     . "   Use EXTRA_REGTEST_OPTS to supply extra args for all tests\n"
+     . "\n";
 
 my $tmp="vg_regtest.tmp.$$";
 
@@ -112,6 +128,11 @@ my $prog;               # test prog
 my $args;               # test prog args
 my $stdout_filter;      # filter program to run stdout results file through
 my $stderr_filter;      # filter program to run stderr results file through
+my $progB;              # Same but for progB
+my $argsB;              # 
+my $stdoutB_filter;     # 
+my $stderrB_filter;     # 
+my $stdinB;             # Input file for progB
 my $prereq;             # prerequisite test to satisfy before running test
 my $post;               # check command after running test
 my $cleanup;            # cleanup command to run
@@ -119,7 +140,9 @@ my $cleanup;            # cleanup command to run
 my @failures;           # List of failed tests
 
 my $num_tests_done      = 0;
-my %num_failures        = (stderr => 0, stdout => 0, post => 0);
+my %num_failures        = (stderr => 0, stdout => 0, 
+                           stderrB => 0, stdoutB => 0,
+                           post => 0);
 
 # Default valgrind to use is this build tree's (uninstalled) one
 my $valgrind = "./coregrind/valgrind";
@@ -127,6 +150,7 @@ my $valgrind = "./coregrind/valgrind";
 chomp(my $tests_dir = `pwd`);
 
 my $valgrind_lib = "$tests_dir/.in_place";
+my $keepunfiltered = 0;
 
 # default filter is the one named "filter_stderr" in the test's directory
 my $default_stderr_filter = "filter_stderr";
@@ -175,6 +199,8 @@ sub process_command_line()
                 $valgrind = $1;
             } elsif ($arg =~ /^--valgrind-lib=(.*)$/) {
                 $valgrind_lib = $1;
+            } elsif ($arg =~ /^--keep-unfiltered$/) {
+                $keepunfiltered = 1;
             } else {
                 die $usage;
             }
@@ -204,12 +230,16 @@ sub read_vgtest_file($)
     my ($f) = @_;
 
     # Defaults.
-    ($vgopts, $prog, $args)          = ("", undef, "");
-    ($stdout_filter, $stderr_filter) = (undef, undef);
-    ($prereq, $post, $cleanup)       = (undef, undef, undef);
+    ($vgopts, $prog, $args)            = ("", undef, "");
+    ($stdout_filter, $stderr_filter)   = (undef, undef);
+    ($progB, $argsB, $stdinB)          = (undef, "", undef);
+    ($stdoutB_filter, $stderrB_filter) = (undef, undef);
+    ($prereq, $post, $cleanup)         = (undef, undef, undef);
 
     # Every test directory must have a "filter_stderr"
     $stderr_filter = validate_program(".", $default_stderr_filter, 1, 1);
+    $stderrB_filter = validate_program(".", $default_stderr_filter, 1, 1);
+    
 
     open(INPUTFILE, "< $f") || die "File $f not openable\n";
 
@@ -217,7 +247,9 @@ sub read_vgtest_file($)
         if      ($line =~ /^\s*#/ || $line =~ /^\s*$/) {
            next;
        } elsif ($line =~ /^\s*vgopts:\s*(.*)$/) {
-            $vgopts = $vgopts . " " . $1;   # Nb: Make sure there's a space!
+            my $addvgopts = $1;
+            $addvgopts =~ s/\${PWD}/$ENV{PWD}/g;
+            $vgopts = $vgopts . " " . $addvgopts;   # Nb: Make sure there's a space!
         } elsif ($line =~ /^\s*prog:\s*(.*)$/) {
             $prog = validate_program(".", $1, 0, 0);
         } elsif ($line =~ /^\s*args:\s*(.*)$/) {
@@ -226,6 +258,16 @@ sub read_vgtest_file($)
             $stdout_filter = validate_program(".", $1, 1, 1);
         } elsif ($line =~ /^\s*stderr_filter:\s*(.*)$/) {
             $stderr_filter = validate_program(".", $1, 1, 1);
+        } elsif ($line =~ /^\s*progB:\s*(.*)$/) {
+            $progB = validate_program(".", $1, 0, 0);
+        } elsif ($line =~ /^\s*argsB:\s*(.*)$/) {
+            $argsB = $1;
+        } elsif ($line =~ /^\s*stdinB:\s*(.*)$/) {
+            $stdinB = $1;
+        } elsif ($line =~ /^\s*stdoutB_filter:\s*(.*)$/) {
+            $stdoutB_filter = validate_program(".", $1, 1, 1);
+        } elsif ($line =~ /^\s*stderrB_filter:\s*(.*)$/) {
+            $stderrB_filter = validate_program(".", $1, 1, 1);
         } elsif ($line =~ /^\s*prereq:\s*(.*)$/) {
             $prereq = $1;
         } elsif ($line =~ /^\s*post:\s*(.*)$/) {
@@ -255,6 +297,17 @@ sub mysystem($)
     return $exit_code;
 }
 
+# if $keepunfiltered, copies $1 to $1.unfiltered.out
+# renames $0 tp $1
+sub filtered_rename($$) 
+{
+    if ($keepunfiltered == 1) {
+        mysystem("cp  $_[1] $_[1].unfiltered.out");
+    }
+    rename ($_[0], $_[1]);
+}
+
+
 # from a directory name like "/foo/cachesim/tests/" determine the tool name
 sub determine_tool()
 {
@@ -331,8 +384,27 @@ sub do_one_test($$)
         }
     }
 
-    printf("%-16s valgrind $extraopts $vgopts $prog $args\n", "$name:");
 
+    if (defined $progB) {
+        # If there is a progB, let's start it in background:
+        printf("%-16s valgrind $extraopts $vgopts $prog $args (progB: $progB $argsB)\n",
+               "$name:");
+        # progB.done used to detect child has finished. See below.
+        # Note: redirection of stdout and stderr is before $progB to allow argsB
+        # to e.g. redirect stdoutB to stderrB
+        if (defined $stdinB) {
+            mysystem("(rm -f progB.done;"
+                     . " < $stdinB > $name.stdoutB.out 2> $name.stderrB.out $progB $argsB;"
+                     . "touch progB.done) &");
+        } else {
+            mysystem("(rm -f progB.done;"
+                     . " > $name.stdoutB.out 2> $name.stderrB.out $progB $argsB;"
+                     . "touch progB.done)  &");
+        }
+    } else {
+        printf("%-16s valgrind $extraopts $vgopts $prog $args\n", "$name:");
+    }
     # Pass the appropriate --tool option for the directory (can be overridden
     # by an "args:" line, though).  Set both VALGRIND_LIB and
     # VALGRIND_LIB_INNER in case this Valgrind was configured with
@@ -346,7 +418,7 @@ sub do_one_test($$)
     # Filter stdout
     if (defined $stdout_filter) {
         mysystem("$stdout_filter < $name.stdout.out > $tmp");
-        rename($tmp, "$name.stdout.out");
+        filtered_rename($tmp, "$name.stdout.out");
     }
     # Find all the .stdout.exp files.  If none, use /dev/null.
     my @stdout_exps = <$name.stdout.exp*>;
@@ -355,12 +427,44 @@ sub do_one_test($$)
 
     # Filter stderr
     mysystem("$stderr_filter < $name.stderr.out > $tmp");
-    rename($tmp, "$name.stderr.out");
+    filtered_rename($tmp, "$name.stderr.out");
     # Find all the .stderr.exp files.  At least one must exist.
     my @stderr_exps = <$name.stderr.exp*>;
     (0 != scalar @stderr_exps) or die "Could not find `$name.stderr.exp*'\n";
     do_diffs($fullname, $name, "stderr", \@stderr_exps); 
 
+    if (defined $progB) {
+        # wait for the child to be finished
+        # tried things such as:
+        #   wait;
+        #   $SIG{CHLD} = sub { wait };
+        # but nothing worked:
+        # e.g. running mssnapshot.vgtest in a loop failed from time to time
+        # due to some missing output (not yet written?).
+        # So, we search progB.done during max 100 times 100 millisecond.
+        my $count;
+        for ($count = 1; $count <= 100; $count++) {
+            (-f "progB.done") or select(undef, undef, undef, 0.100);
+        }
+        # Filter stdout
+        if (defined $stdoutB_filter) {
+            mysystem("$stdoutB_filter < $name.stdoutB.out > $tmp");
+            filtered_rename($tmp, "$name.stdoutB.out");
+        }
+        # Find all the .stdoutB.exp files.  If none, use /dev/null.
+        my @stdoutB_exps = <$name.stdoutB.exp*>;
+        @stdoutB_exps = ( "/dev/null" ) if (0 == scalar @stdoutB_exps);
+        do_diffs($fullname, $name, "stdoutB", \@stdoutB_exps); 
+        
+        # Filter stderr
+        mysystem("$stderrB_filter < $name.stderrB.out > $tmp");
+        filtered_rename($tmp, "$name.stderrB.out");
+        # Find all the .stderrB.exp files.  At least one must exist.
+        my @stderrB_exps = <$name.stderrB.exp*>;
+        (0 != scalar @stderrB_exps) or die "Could not find `$name.stderrB.exp*'\n";
+        do_diffs($fullname, $name, "stderrB", \@stderrB_exps); 
+    }
+
     # Maybe do post-test check
     if (defined $post) {
        if (mysystem("$post > $name.post.out") != 0) {
@@ -447,10 +551,13 @@ sub summarise_results
     my $x = ( $num_tests_done == 1 ? "test" : "tests" );
     
     printf("\n== %d test%s, %d stderr failure%s, %d stdout failure%s, "
+                         . "%d stderrB failure%s, %d stdoutB failure%s, "
                          . "%d post failure%s ==\n", 
            $num_tests_done, plural($num_tests_done),
            $num_failures{"stderr"},   plural($num_failures{"stderr"}),
            $num_failures{"stdout"},   plural($num_failures{"stdout"}),
+           $num_failures{"stderrB"},  plural($num_failures{"stderrB"}),
+           $num_failures{"stdoutB"},  plural($num_failures{"stdoutB"}),
            $num_failures{"post"},     plural($num_failures{"post"}));
 
     foreach my $failure (@failures) {
@@ -506,6 +613,8 @@ if ($ENV{"EXTRA_REGTEST_OPTS"}) {
 
 if (0 == $num_failures{"stdout"} &&
     0 == $num_failures{"stderr"} &&
+    0 == $num_failures{"stdoutB"} &&
+    0 == $num_failures{"stderrB"} &&
     0 == $num_failures{"post"}) {
     exit 0;
 } else {