1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#! @PERL@
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--------------------------------------------------------------------##
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--- Valgrind regression testing script                vg_regtest ---##
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--------------------------------------------------------------------##
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  This file is part of Valgrind, a dynamic binary instrumentation
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  framework.
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  Copyright (C) 2003 Nicholas Nethercote
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#     njn@valgrind.org
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  This program is free software; you can redistribute it and/or
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  modify it under the terms of the GNU General Public License as
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  published by the Free Software Foundation; either version 2 of the
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  License, or (at your option) any later version.
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  This program is distributed in the hope that it will be useful, but
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  WITHOUT ANY WARRANTY; without even the implied warranty of
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  General Public License for more details.
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  You should have received a copy of the GNU General Public License
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  along with this program; if not, write to the Free Software
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  02111-1307, USA.
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#  The GNU General Public License is contained in the file COPYING.
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# usage: vg_regtest [options] <dirs | files>
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Options:
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#   --all:      run tests in all subdirs
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#   --valgrind: valgrind launcher to use.  Default is ./coregrind/valgrind.
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#               (This option should probably only be used in conjunction with
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#               --valgrind-lib.)
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#   --valgrind-lib: valgrind libraries to use.  Default is $tests_dir/.in_place.
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#               (This option should probably only be used in conjunction with
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#               --valgrind.)
40b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#   --keep-unfiltered: keep a copy of the unfiltered output/error output
41b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#     of each test by adding an extension .unfiltered.out
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# The easiest way is to run all tests in valgrind/ with (assuming you installed
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# in $PREFIX):
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#   $PREFIX/bin/vg_regtest --all
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# You can specify individual files to test, or whole directories, or both.
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Directories are traversed recursively, except for ones named, for example, 
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# CVS/ or docs/.
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Each test is defined in a file <test>.vgtest, containing one or more of the
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# following lines, in any order:
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#   - prog:   <prog to run>                         (compulsory)
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#   - args:   <args for prog>                       (default: none)
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#   - vgopts: <Valgrind options>                    (default: none;
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#                                                    multiple are allowed)
58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#   - stdout_filter: <filter to run stdout through> (default: none)
59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#   - stderr_filter: <filter to run stderr through> (default: ./filter_stderr)
60b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#   - stdout_filter_args: <args for stdout_filter>  (default: basename of .vgtest file)
61b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#   - stderr_filter_args: <args for stderr_filter>  (default: basename of .vgtest file)
62b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#
63b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#   - progB:  <prog to run in parallel with prog>   (default: none)
64b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#   - argsB:  <args for progB>                      (default: none)
65b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#   - stdinB: <input file for progB>                (default: none)
66b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#   - stdoutB_filter: <filter progB stdout through> (default: none)
67b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#   - stderrB_filter: <filter progB stderr through> (default: ./filter_stderr)
68b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#   - stdoutB_filter_args: <args for stdout_filterB> (default: basename of .vgtest file)
69b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#   - stderrB_filter_args: <args for stderr_filterB>  (default: basename of .vgtest file)
70b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#
71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#   - prereq: <prerequisite command>                (default: none)
72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#   - post: <post-test check command>               (default: none)
73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#   - cleanup: <post-test cleanup cmd>              (default: none)
74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
75b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# If prog or probB is a relative path, it will be prefix with the test directory.
76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Note that filters are necessary for stderr results to filter out things that
77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# always change, eg. process id numbers.
78b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Note that if a progB is specified, it is started in background (before prog).
79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Expected stdout (filtered) is kept in <test>.stdout.exp* (can be more
81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# than one expected output).  It can be missing if it would be empty.  Expected
82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# stderr (filtered) is kept in <test>.stderr.exp*.   There must be at least
83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# one stderr.exp* file.  Any .exp* file that ends in '~' or '#' is ignored;
84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# this is because Emacs creates temporary files of these names.
85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
86b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# Expected output for progB is handled similarly, except that
87b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# expected stdout and stderr for progB are in  <test>.stdoutB.exp*
88b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# and <test>.stderrB.exp*.
89b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov#
90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# If results don't match, the output can be found in <test>.std<strm>.out,
91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# and the diff between expected and actual in <test>.std<strm>.diff*.
92b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# (for progB, in <test>.std<strm>2.out and <test>.std<strm>2.diff*).
93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# The prerequisite command, if present, works like this:
95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# - if it returns 0 the test is run
96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# - if it returns 1 the test is skipped
97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# - if it returns anything else the script aborts.
98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# The idea here is results other than 0 or 1 are likely to be due to
99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# problems with the commands, and you don't want to conflate them with the 1
100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# case, which would happen if you just tested for zero or non-zero.
101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# The post-test command, if present, must return 0 and its stdout must match
103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# the expected stdout which is kept in <test>.post.exp*.
104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Sometimes it is useful to run all the tests at a high sanity check
106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# level or with arbitrary other flags.  To make this simple, extra 
107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# options, applied to all tests run, are read from $EXTRA_REGTEST_OPTS,
108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# and handed to valgrind prior to any other flags specified by the 
109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# .vgtest file.
110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Some more notes on adding regression tests for a new tool are in
112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# docs/xml/manual-writing-tools.xml.
113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------
114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownuse warnings;
116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownuse strict;
117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------
119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Global vars
120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------
121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $usage="\n"
122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     . "Usage:\n"
123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     . "   vg_regtest [--all, --valgrind, --valgrind-lib, --keep-unfiltered]\n"
124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     . "   Use EXTRA_REGTEST_OPTS to supply extra args for all tests\n"
125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov     . "\n";
126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $tmp="vg_regtest.tmp.$$";
128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Test variables
130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $vgopts;             # valgrind options
131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $prog;               # test prog
132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $args;               # test prog args
133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $stdout_filter;      # filter program to run stdout results file through
134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $stderr_filter;      # filter program to run stderr results file through
135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $stdout_filter_args; # arguments passed to stdout_filter
136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $stderr_filter_args; # arguments passed to stderr_filter
137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $progB;              # Same but for progB
138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $argsB;              # 
139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $stdoutB_filter;     # 
140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $stderrB_filter;     # 
141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $stdoutB_filter_args;# arguments passed to stdout_filterB
142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $stderrB_filter_args;# arguments passed to stderr_filterB
143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $stdinB;             # Input file for progB
144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $prereq;             # prerequisite test to satisfy before running test
145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $post;               # check command after running test
146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $cleanup;            # cleanup command to run
147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy @failures;           # List of failed tests
149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $num_tests_done      = 0;
151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy %num_failures        = (stderr => 0, stdout => 0, 
152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                           stderrB => 0, stdoutB => 0,
153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                           post => 0);
154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Default valgrind to use is this build tree's (uninstalled) one
156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $valgrind = "./coregrind/valgrind";
157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownchomp(my $tests_dir = `pwd`);
159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $valgrind_lib = "$tests_dir/.in_place";
161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovmy $keepunfiltered = 0;
162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# default filter is the one named "filter_stderr" in the test's directory
164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy $default_stderr_filter = "filter_stderr";
165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------
168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Process command line, setup
169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------
170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# If $prog is a relative path, it prepends $dir to it.  Useful for two reasons:
172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 1. Can prepend "." onto programs to avoid trouble with users who don't have
174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#    "." in their path (by making $dir = ".")
175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# 2. Can prepend the current dir to make the command absolute to avoid
176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#    subsequent trouble when we change directories.
177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#
178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Also checks the program exists and is executable.
179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub validate_program ($$$$) 
180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my ($dir, $prog, $must_exist, $must_be_executable) = @_;
182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # If absolute path, leave it alone.  If relative, make it
184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # absolute -- by prepending current dir -- so we can change
185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # dirs and still use it.
186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    $prog = "$dir/$prog" if ($prog !~ /^\//);
187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if ($must_exist) {
188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (-f $prog) or die "vg_regtest: `$prog' not found or not a file ($dir)\n";
189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if ($must_be_executable) { 
191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (-x $prog) or die "vg_regtest: `$prog' not executable ($dir)\n";
192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return $prog;
195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub process_command_line() 
198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $alldirs = 0;
200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my @fs;
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    for my $arg (@ARGV) {
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if ($arg =~ /^-/) {
204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if      ($arg =~ /^--all$/) {
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $alldirs = 1;
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            } elsif ($arg =~ /^--valgrind=(.*)$/) {
207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $valgrind = $1;
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            } elsif ($arg =~ /^--valgrind-lib=(.*)$/) {
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $valgrind_lib = $1;
210b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            } elsif ($arg =~ /^--keep-unfiltered$/) {
211b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                $keepunfiltered = 1;
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            } else {
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                die $usage;
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        } else {
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            push(@fs, $arg);
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    $valgrind = validate_program($tests_dir, $valgrind, 1, 0);
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if ($alldirs) {
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        @fs = ();
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        foreach my $f (glob "*") {
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            push(@fs, $f) if (-d $f);
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
228ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    (0 != @fs) or die "No test files or directories specified\n";
229ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
230ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return @fs;
231ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
232ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
233ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------
234ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Read a .vgtest file
235ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub read_vgtest_file($)
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my ($f) = @_;
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
240ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # Defaults.
241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    ($vgopts, $prog, $args)            = ("", undef, "");
242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    ($stdout_filter, $stderr_filter)   = (undef, undef);
243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    ($progB, $argsB, $stdinB)          = (undef, "", undef);
244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    ($stdoutB_filter, $stderrB_filter) = (undef, undef);
245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    ($prereq, $post, $cleanup)         = (undef, undef, undef);
246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    ($stdout_filter_args, $stderr_filter_args)   = (undef, undef);
247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    ($stdoutB_filter_args, $stderrB_filter_args) = (undef, undef);
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
249ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # Every test directory must have a "filter_stderr"
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    $stderr_filter = validate_program(".", $default_stderr_filter, 1, 1);
251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    $stderrB_filter = validate_program(".", $default_stderr_filter, 1, 1);
252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    
253ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
254ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    open(INPUTFILE, "< $f") || die "File $f not openable\n";
255ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
256ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    while (my $line = <INPUTFILE>) {
257ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if      ($line =~ /^\s*#/ || $line =~ /^\s*$/) {
258ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    next;
259ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	} elsif ($line =~ /^\s*vgopts:\s*(.*)$/) {
260ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $addvgopts = $1;
261ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $addvgopts =~ s/\${PWD}/$ENV{PWD}/g;
262ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $vgopts = $vgopts . " " . $addvgopts;   # Nb: Make sure there's a space!
263ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        } elsif ($line =~ /^\s*prog:\s*(.*)$/) {
264ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $prog = validate_program(".", $1, 0, 0);
265ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        } elsif ($line =~ /^\s*args:\s*(.*)$/) {
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $args = $1;
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        } elsif ($line =~ /^\s*stdout_filter:\s*(.*)$/) {
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $stdout_filter = validate_program(".", $1, 1, 1);
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        } elsif ($line =~ /^\s*stderr_filter:\s*(.*)$/) {
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $stderr_filter = validate_program(".", $1, 1, 1);
271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        } elsif ($line =~ /^\s*stdout_filter_args:\s*(.*)$/) {
272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            $stdout_filter_args = $1;
273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        } elsif ($line =~ /^\s*stderr_filter_args:\s*(.*)$/) {
274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            $stderr_filter_args = $1;
275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        } elsif ($line =~ /^\s*progB:\s*(.*)$/) {
276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            $progB = validate_program(".", $1, 0, 0);
277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        } elsif ($line =~ /^\s*argsB:\s*(.*)$/) {
278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            $argsB = $1;
279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        } elsif ($line =~ /^\s*stdinB:\s*(.*)$/) {
280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            $stdinB = $1;
281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        } elsif ($line =~ /^\s*stdoutB_filter:\s*(.*)$/) {
282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            $stdoutB_filter = validate_program(".", $1, 1, 1);
283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        } elsif ($line =~ /^\s*stderrB_filter:\s*(.*)$/) {
284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            $stderrB_filter = validate_program(".", $1, 1, 1);
285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        } elsif ($line =~ /^\s*stdoutB_filter_args:\s*(.*)$/) {
286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            $stdoutB_filter_args = $1;
287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        } elsif ($line =~ /^\s*stderrB_filter_args:\s*(.*)$/) {
288b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            $stderrB_filter_args = $1;
289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        } elsif ($line =~ /^\s*prereq:\s*(.*)$/) {
290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $prereq = $1;
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        } elsif ($line =~ /^\s*post:\s*(.*)$/) {
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $post = $1;
293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        } elsif ($line =~ /^\s*cleanup:\s*(.*)$/) {
294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $cleanup = $1;
295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        } else {
296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            die "Bad line in $f: $line\n";
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    close(INPUTFILE);
300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (!defined $prog) {
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        $prog = "";     # allow no prog for testing error and --help cases
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Do one test
308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Since most of the program time is spent in system() calls, need this to
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# propagate a Ctrl-C enabling us to quit.
311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub mysystem($) 
312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $exit_code = system($_[0]);
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    ($exit_code == 2) and exit 1;      # 2 is SIGINT
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return $exit_code;
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# if $keepunfiltered, copies $1 to $1.unfiltered.out
319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov# renames $0 tp $1
320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovsub filtered_rename($$) 
321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if ($keepunfiltered == 1) {
323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        mysystem("cp  $_[1] $_[1].unfiltered.out");
324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    rename ($_[0], $_[1]);
326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
329ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# from a directory name like "/foo/cachesim/tests/" determine the tool name
330ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub determine_tool()
331ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
332ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $dir = `pwd`;
333ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    $dir =~ /.*\/([^\/]+)\/tests.*/;   # foo/tool_name/tests/foo
334ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    return $1;
335ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
336ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
337ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Compare output against expected output;  it should match at least one of
338ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# them.
339ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub do_diffs($$$$)
340ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
341ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my ($fullname, $name, $mid, $f_exps) = @_;
342ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    
343ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    for my $f_exp (@$f_exps) {
344ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (-r $f_exp) or die "Could not read `$f_exp'\n";
345ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
346ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        # Emacs produces temporary files that end in '~' and '#'.  We ignore
347ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        # these.
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if ($f_exp !~ /[~#]$/) {
349ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            # $n is the (optional) suffix after the ".exp";  we tack it onto
350ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            # the ".diff" file.
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            my $n = "";
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if ($f_exp =~ /.*\.exp(.*)$/) {
353ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $n = $1;
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            } else {
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                $n = "";
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                ($f_exp eq "/dev/null") or die "Unexpected .exp file: $f_exp\n";
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            mysystem("@DIFF@ $f_exp $name.$mid.out > $name.$mid.diff$n");
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (not -s "$name.$mid.diff$n") {
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                # A match;  remove .out and any previously created .diff files.
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                unlink("$name.$mid.out");
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                unlink(<$name.$mid.diff*>);
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                return;
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # If we reach here, none of the .exp files matched.
370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print "*** $name failed ($mid) ***\n";
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    push(@failures, sprintf("%-40s ($mid)", "$fullname"));
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    $num_failures{$mid}++;
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub do_one_test($$) 
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my ($dir, $vgtest) = @_;
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    $vgtest =~ /^(.*)\.vgtest/;
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $name = $1;
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $fullname = "$dir/$name"; 
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # Pull any extra options (for example, --sanity-level=4)
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # from $EXTRA_REGTEST_OPTS.
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $maybe_extraopts = $ENV{"EXTRA_REGTEST_OPTS"};
385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $extraopts = $maybe_extraopts ?  $maybe_extraopts  : "";
386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    read_vgtest_file($vgtest);
388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (defined $prereq) {
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        my $prereq_res = system("$prereq");
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if (0 == $prereq_res) {
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            # Do nothing (ie. continue with the test)
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        } elsif (256 == $prereq_res) {
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            # Nb: weird Perl-ism -- exit code of '1' is seen by Perl as 256...
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            # Prereq failed, skip.
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            printf("%-16s (skipping, prereq failed: $prereq)\n", "$name:");
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            return;
398ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        } else {
399ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            # Bad prereq; abort.
400ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $prereq_res /= 256;
401ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            die "prereq returned $prereq_res: $prereq\n";
402ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
403ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
404ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
405ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
406b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if (defined $progB) {
407b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        # If there is a progB, let's start it in background:
408b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        printf("%-16s valgrind $extraopts $vgopts $prog $args (progB: $progB $argsB)\n",
409b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               "$name:");
410b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        # progB.done used to detect child has finished. See below.
411b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        # Note: redirection of stdout and stderr is before $progB to allow argsB
412b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        # to e.g. redirect stdoutB to stderrB
413b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        if (defined $stdinB) {
414b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            mysystem("(rm -f progB.done;"
415b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     . " < $stdinB > $name.stdoutB.out 2> $name.stderrB.out $progB $argsB;"
416b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     . "touch progB.done) &");
417b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        } else {
418b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            mysystem("(rm -f progB.done;"
419b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     . " > $name.stdoutB.out 2> $name.stderrB.out $progB $argsB;"
420b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                     . "touch progB.done)  &");
421b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        }
422b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    } else {
423b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        printf("%-16s valgrind $extraopts $vgopts $prog $args\n", "$name:");
424b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
425b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov 
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # Pass the appropriate --tool option for the directory (can be overridden
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # by an "args:" line, though).  Set both VALGRIND_LIB and
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # VALGRIND_LIB_INNER in case this Valgrind was configured with
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # --enable-inner.
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $tool=determine_tool();
431ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    mysystem("VALGRIND_LIB=$valgrind_lib VALGRIND_LIB_INNER=$valgrind_lib "
432ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           . "$valgrind --command-line-only=yes --memcheck:leak-check=no "
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           . "--tool=$tool $extraopts $vgopts "
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           . "$prog $args > $name.stdout.out 2> $name.stderr.out");
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
436ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # Filter stdout
437ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (defined $stdout_filter) {
438b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        $stdout_filter_args = $name if (! defined $stdout_filter_args);
439b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        mysystem("$stdout_filter $stdout_filter_args < $name.stdout.out > $tmp");
440b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        filtered_rename($tmp, "$name.stdout.out");
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # Find all the .stdout.exp files.  If none, use /dev/null.
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my @stdout_exps = <$name.stdout.exp*>;
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    @stdout_exps = ( "/dev/null" ) if (0 == scalar @stdout_exps);
445ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    do_diffs($fullname, $name, "stdout", \@stdout_exps); 
446ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
447ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # Filter stderr
448b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    $stderr_filter_args = $name if (! defined $stderr_filter_args);
449b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    mysystem("$stderr_filter $stderr_filter_args < $name.stderr.out > $tmp");
450b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    filtered_rename($tmp, "$name.stderr.out");
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # Find all the .stderr.exp files.  At least one must exist.
452ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my @stderr_exps = <$name.stderr.exp*>;
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    (0 != scalar @stderr_exps) or die "Could not find `$name.stderr.exp*'\n";
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    do_diffs($fullname, $name, "stderr", \@stderr_exps); 
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
456b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    if (defined $progB) {
457b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        # wait for the child to be finished
458b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        # tried things such as:
459b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        #   wait;
460b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        #   $SIG{CHLD} = sub { wait };
461b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        # but nothing worked:
462b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        # e.g. running mssnapshot.vgtest in a loop failed from time to time
463b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        # due to some missing output (not yet written?).
464b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        # So, we search progB.done during max 100 times 100 millisecond.
465b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        my $count;
466b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        for ($count = 1; $count <= 100; $count++) {
467b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            (-f "progB.done") or select(undef, undef, undef, 0.100);
468b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        }
469b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        # Filter stdout
470b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        if (defined $stdoutB_filter) {
471b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            $stdoutB_filter_args = $name if (! defined $stdoutB_filter_args);
472b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            mysystem("$stdoutB_filter $stdoutB_filter_args < $name.stdoutB.out > $tmp");
473b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            filtered_rename($tmp, "$name.stdoutB.out");
474b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        }
475b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        # Find all the .stdoutB.exp files.  If none, use /dev/null.
476b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        my @stdoutB_exps = <$name.stdoutB.exp*>;
477b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        @stdoutB_exps = ( "/dev/null" ) if (0 == scalar @stdoutB_exps);
478b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        do_diffs($fullname, $name, "stdoutB", \@stdoutB_exps); 
479b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        
480b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        # Filter stderr
481b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        $stderrB_filter_args = $name if (! defined $stderrB_filter_args);
482b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        mysystem("$stderrB_filter $stderrB_filter_args < $name.stderrB.out > $tmp");
483b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        filtered_rename($tmp, "$name.stderrB.out");
484b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        # Find all the .stderrB.exp files.  At least one must exist.
485b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        my @stderrB_exps = <$name.stderrB.exp*>;
486b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        (0 != scalar @stderrB_exps) or die "Could not find `$name.stderrB.exp*'\n";
487b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        do_diffs($fullname, $name, "stderrB", \@stderrB_exps); 
488b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    }
489b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # Maybe do post-test check
491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (defined $post) {
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	if (mysystem("$post > $name.post.out") != 0) {
493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    print("post check failed: $post\n");
494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    $num_failures{"post"}++;
495ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	} else {
496ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    # Find all the .post.exp files.  If none, use /dev/null.
497ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    my @post_exps = <$name.post.exp*>;
498ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    @post_exps = ( "/dev/null" ) if (0 == scalar @post_exps);
499ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	    do_diffs($fullname, $name, "post", \@post_exps);
500ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown	}
501ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
502ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 
503ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (defined $cleanup) {
504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        (system("$cleanup") == 0) or 
505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            print("(cleanup operation failed: $cleanup)\n");
506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    $num_tests_done++;
509ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
510ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
511ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------
512ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Test one directory (and any subdirs)
513ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------
514ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub test_one_dir($$);    # forward declaration
515ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
516ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub test_one_dir($$) 
517ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my ($dir, $prev_dirs) = @_;
519ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    $dir =~ s/\/$//;    # trim a trailing '/'
520ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # Ignore dirs into which we should not recurse.
522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if ($dir =~ /^(BitKeeper|CVS|SCCS|docs|doc)$/) { return; }
523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    (-x "$tests_dir/tests/arch_test") or die 
525ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        "vg_regtest: 'arch_test' is missing.  Did you forget to 'make check'?\n";
526ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    
527ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # Ignore any dir whose name matches that of an architecture which is not
528ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # the architecture we are running on.  Eg. when running on x86, ignore
529ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # ppc/ directories ('arch_test' returns 1 for this case).  Likewise for
530ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # the OS and platform.
531ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # Nb: weird Perl-ism -- exit code of '1' is seen by Perl as 256...
532ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (256 == system("$tests_dir/tests/arch_test $dir"))  { return; }
533ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (256 == system("$tests_dir/tests/os_test   $dir"))  { return; }
534ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if ($dir =~ /(\w+)-(\w+)/ &&
535ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        256 == system("sh $tests_dir/tests/platform_test $1 $2")) { return; }
536ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    
537ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    chdir($dir) or die "Could not change into $dir\n";
538ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
539ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    # Nb: Don't prepend a '/' to the base directory
540ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $full_dir = $prev_dirs . ($prev_dirs eq "" ? "" : "/") . $dir;
541ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $dashes = "-" x (50 - length $full_dir);
542ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
543ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my @fs = glob "*";
544ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $found_tests = (0 != (grep { $_ =~ /\.vgtest$/ } @fs));
545ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
546ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if ($found_tests) {
547ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print "-- Running  tests in $full_dir $dashes\n";
548ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
549ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    foreach my $f (@fs) {
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if (-d $f) {
551ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            test_one_dir($f, $full_dir);
552ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        } elsif ($f =~ /\.vgtest$/) {
553ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            do_one_test($full_dir, $f);
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
555ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
556ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if ($found_tests) {
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print "-- Finished tests in $full_dir $dashes\n";
558ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
559ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
560ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    chdir("..");
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
562ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
563ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------
564ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# Summarise results
565ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------
566ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub plural($)
567ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
568ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return ( $_[0] == 1 ? "" : "s" );
569ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
570ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
571ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub summarise_results 
572ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
573ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    my $x = ( $num_tests_done == 1 ? "test" : "tests" );
574ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    
575ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    printf("\n== %d test%s, %d stderr failure%s, %d stdout failure%s, "
576b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                         . "%d stderrB failure%s, %d stdoutB failure%s, "
577ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                         . "%d post failure%s ==\n", 
578ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           $num_tests_done, plural($num_tests_done),
579ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           $num_failures{"stderr"},   plural($num_failures{"stderr"}),
580ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           $num_failures{"stdout"},   plural($num_failures{"stdout"}),
581b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           $num_failures{"stderrB"},  plural($num_failures{"stderrB"}),
582b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           $num_failures{"stdoutB"},  plural($num_failures{"stdoutB"}),
583ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           $num_failures{"post"},     plural($num_failures{"post"}));
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    foreach my $failure (@failures) {
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        print "$failure\n";
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
588ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print "\n";
589ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
590ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
591ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------
592ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# main(), sort of
593ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#----------------------------------------------------------------------------
594ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsub warn_about_EXTRA_REGTEST_OPTS()
595ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
596ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print "WARNING: \$EXTRA_REGTEST_OPTS is set.  You probably don't want\n";
597ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print "to run the regression tests with it set, unless you are doing some\n";
598ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print "strange experiment, and/or you really know what you are doing.\n";
599ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print "\n";
600ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
601ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
602ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown# nuke VALGRIND_OPTS
603ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown$ENV{"VALGRIND_OPTS"} = "";
604ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
605ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownif ($ENV{"EXTRA_REGTEST_OPTS"}) {
606ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    print "\n";
607ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    warn_about_EXTRA_REGTEST_OPTS();
608ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
609ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
610ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownmy @fs = process_command_line();
611ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownforeach my $f (@fs) {
612ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    if (-d $f) {
613ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        test_one_dir($f, "");
614ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    } else { 
615ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        # Allow the .vgtest suffix to be given or omitted
616ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        if ($f =~ /.vgtest$/ && -r $f) {
617ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            # do nothing
618ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        } elsif (-r "$f.vgtest") {
619ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            $f = "$f.vgtest";
620ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        } else {
621ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            die "`$f' neither a directory nor a readable test file/name\n"
622ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        }
623ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        my $dir  = `dirname  $f`;   chomp $dir;
624ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        my $file = `basename $f`;   chomp $file;
625ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        chdir($dir) or die "Could not change into $dir\n";
626ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        do_one_test($dir, $file);
627ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        chdir($tests_dir);
628ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    }
629ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
630ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownsummarise_results();
631ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
632ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownif ($ENV{"EXTRA_REGTEST_OPTS"}) {
633ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    warn_about_EXTRA_REGTEST_OPTS();
634ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
635ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
636ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownif (0 == $num_failures{"stdout"} &&
637ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    0 == $num_failures{"stderr"} &&
638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    0 == $num_failures{"stdoutB"} &&
639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov    0 == $num_failures{"stderrB"} &&
640ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    0 == $num_failures{"post"}) {
641ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    exit 0;
642ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} else {
643ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    exit 1;
644ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
645ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
646ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--------------------------------------------------------------------##
647ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--- end                                               vg_regtest ---##
648ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown##--------------------------------------------------------------------##
649