diff options
author | Paul Smith <psmith@gnu.org> | 2019-09-15 15:30:34 -0400 |
---|---|---|
committer | Paul Smith <psmith@gnu.org> | 2019-09-16 08:25:33 -0400 |
commit | 414af96a5010353643d2e8691d86dc3416ffbd75 (patch) | |
tree | 645ff3248b37bb7e5f5828bd38cd4feb30c90287 /tests/run_make_tests.pl | |
parent | 1b976397e542e310d5932d6d847e7f24ee441f6d (diff) | |
download | make-git-414af96a5010353643d2e8691d86dc3416ffbd75.tar.gz |
Refresh the test suite framework implementation.
Go through both run_make_tests.pl and test_driver.pl and slightly
modernize the Perl and clean up indentation etc. Fix a number of
warnings in the test scripts detected by running with -w.
* tests/test_driver.pl: Move make error string detection out of the
base test driver.
(run_all_tests): Ensure that we always look for tests in the cwd.
* tests/run_make_tests.pl: Use File::Spec for path manipulations.
Correctly use setlocale() when detecting error strings.
Get configuration from the config-flags.pm file not config.status.
* tests/scripts/features/archives: Use new $cwddir variable.
* tests/scripts/features/reinvoke: Add missing semicolon.
* tests/scripts/features/vpath2: Avoid non-existent variable.
* tests/scripts/functions/foreach: Escape variables.
* tests/scripts/misc/bs-nl: Remove non-existing \v escape sequence.
* tests/scripts/misc/general4: Use handy create_file().
* tests/scripts/options/dash-C: Use Cwd/$cwddir.
* tests/scripts/options/dash-I: Use subst_make_string() and #PWD#.
* tests/scripts/options/symlinks: Use File::Spec.
* tests/scripts/targets/DEFAULT: Use create_file and run_make_test.
* tests/scripts/variables/CURDIR: Use run_make_test.
* tests/scripts/variables/automatic: Remove extraneous "\".
* tests/scripts/vms/library: Remove extra "my" and extraneous "\".
Diffstat (limited to 'tests/run_make_tests.pl')
-rw-r--r-- | tests/run_make_tests.pl | 430 |
1 files changed, 274 insertions, 156 deletions
diff --git a/tests/run_make_tests.pl b/tests/run_make_tests.pl index f49f1d7e..57dfd49d 100644 --- a/tests/run_make_tests.pl +++ b/tests/run_make_tests.pl @@ -27,6 +27,21 @@ # You should have received a copy of the GNU General Public License along with # this program. If not, see <http://www.gnu.org/licenses/>. +# Add the working directory to @INC and load the test driver +use FindBin; +use lib "$FindBin::Bin"; + +require "test_driver.pl"; + +use File::Spec::Functions qw(:DEFAULT splitdir splitpath catpath); + +use Cwd; +$cwdpath = cwd(); +($cwdvol, $cwddir, $_) = splitpath($cwdpath, 1); + +# Some target systems might not have the POSIX module... +$has_POSIX = eval { require "POSIX.pm" }; + %FEATURES = (); $valgrind = 0; # invoke make with valgrind @@ -36,7 +51,12 @@ $massif_args = '--num-callers=15 --tool=massif --alloc-fn=xmalloc --alloc-fn=xca $pure_log = undef; # The location of the GNU make source directory -$srcdir = ''; +$srcdir = undef; +$srcvol = undef; + +# The location of the build directory +$blddir = undef; +$bldvol = undef; $command_string = ''; @@ -67,24 +87,71 @@ if ($^O eq 'VMS') $CMD_rmfile = 'delete_file -no_ask'; } -use FindBin; -use lib "$FindBin::Bin"; +%CONFIG_FLAGS = (); -require "test_driver.pl"; +# Find the strings that will be generated for various error codes. +# We want them from the C locale regardless of our current locale. -%CONFIG_FLAGS = (); +$ERR_no_such_file = undef; +$ERR_read_only_file = undef; +$ERR_unreadable_file = undef; +$ERR_noexe_file = undef; +$ERR_exe_dir = undef; -my $statnm = "$FindBin::Bin/../config.status"; -if (open(my $fh, '<', $statnm)) { - while (my $line = <$fh>) { - $line =~ m/^[SD]\["([^\"]+)"\]=" *(.*)"/ and $CONFIG_FLAGS{$1} = $2; - } -} else { - warn "Failed to open $statnm: $!"; -} +{ + use locale; -# Some target systems might not have the POSIX module... -$has_POSIX = eval { require "POSIX.pm" }; + my $loc = undef; + if ($has_POSIX) { + POSIX->import(qw(locale_h)); + # Windows has POSIX locale, but only LC_ALL not LC_MESSAGES + $loc = POSIX::setlocale(&POSIX::LC_ALL); + POSIX::setlocale(&POSIX::LC_ALL, 'C'); + } + + if (open(my $F, '<', 'file.none')) { + print "Opened non-existent file! Skipping related tests.\n"; + } else { + $ERR_no_such_file = "$!"; + } + + unlink('file.out'); + touch('file.out'); + + chmod(0444, 'file.out'); + if (open(my $F, '>', 'file.out')) { + print "Opened read-only file! Skipping related tests.\n"; + close($F); + } else { + $ERR_read_only_file = "$!"; + } + + $_ = `./file.out 2>/dev/null`; + if ($? == 0) { + print "Executed non-executable file! Skipping related tests.\n"; + } else { + $ERR_nonexe_file = "$!"; + } + + $_ = `./. 2>/dev/null`; + if ($? == 0) { + print "Executed directory! Skipping related tests.\n"; + } else { + $ERR_exe_dir = "$!"; + } + + chmod(0000, 'file.out'); + if (open(my $F, '<', 'file.out')) { + print "Opened unreadable file! Skipping related tests.\n"; + close($F); + } else { + $ERR_unreadable_file = "$!"; + } + + unlink('file.out') or die "Failed to delete file.out: $!\n"; + + $loc and POSIX::setlocale(&POSIX::LC_ALL, $loc); +} #$SIG{INT} = sub { print STDERR "Caught a signal!\n"; die @_; }; @@ -103,7 +170,7 @@ sub valid_option if ($option =~ /^-srcdir$/i) { $srcdir = shift @argv; - if (! -f "$srcdir/src/gnumake.h") { + if (! -f catfile($srcdir, 'src', 'gnumake.h')) { print "$option $srcdir: Not a valid GNU make source directory.\n"; exit 0; } @@ -155,7 +222,7 @@ sub subst_make_string s/#MAKEPATH#/$mkpath/g; s/#MAKE#/$make_name/g; s/#PERL#/$perl_name/g; - s/#PWD#/$pwd/g; + s/#PWD#/$cwdpath/g; return $_; } @@ -170,7 +237,7 @@ sub run_make_test if (! defined $makestring) { defined $old_makefile - || die "run_make_test(undef) invoked before run_make_test('...')\n"; + or die "run_make_test(undef) invoked before run_make_test('...')\n"; $makefile = $old_makefile; } else { if (! defined($makefile)) { @@ -182,9 +249,9 @@ sub run_make_test $makestring = subst_make_string($makestring); # Populate the makefile! - open(MAKEFILE, "> $makefile") || die "Failed to open $makefile: $!\n"; + open(MAKEFILE, "> $makefile") or die "Failed to open $makefile: $!\n"; print MAKEFILE $makestring; - close(MAKEFILE) || die "Failed to write $makefile: $!\n"; + close(MAKEFILE) or die "Failed to write $makefile: $!\n"; } # Do the same processing on $answer as we did on $makestring. @@ -317,8 +384,7 @@ sub run_make_with_options { # If we have a purify log, save it $tn = $pure_testname . ($num_of_logfiles ? ".$num_of_logfiles" : ""); print("Renaming purify log file to $tn\n") if $debug; - rename($pure_log, "$tn") - || die "Can't rename $log to $tn: $!\n"; + rename($pure_log, "$tn") or die "Can't rename $log to $tn: $!\n"; ++$purify_errors; } else { unlink($pure_log); @@ -363,168 +429,220 @@ sub print_help "\tRun the test suite under valgrind's memcheck tool.", "\tChange the default valgrind args with the VALGRIND_ARGS env var.", "-massif", - "\tRun the test suite under valgrind's massif toool.", + "\tRun the test suite under valgrind's massif tool.", "\tChange the default valgrind args with the VALGRIND_ARGS env var." ); } -sub get_this_pwd { - if ($has_POSIX) { - $__pwd = POSIX::getcwd(); - } elsif ($vos) { - $__pwd = `++(current_dir)`; - } else { - # No idea... just try using pwd as a last resort. - chop ($__pwd = `pwd`); - } - - return $__pwd; +sub set_defaults +{ + # $profile = 1; + $testee = "GNU make"; + $make_path = "make"; + $tmpfilesuffix = "mk"; } -sub set_defaults +# This is no longer used: we import config-flags.pm instead +# sub parse_status +# { +# if (open(my $fh, '<', "$_[0]/config.status")) { +# while (my $line = <$fh>) { +# $line =~ m/^[SD]\["([^\"]+)"\]=" *(.*)"/ and $CONFIG_FLAGS{$1} = $2; +# } +# return 1; +# } +# return 0; +# } + +sub find_prog { - # $profile = 1; - $testee = "GNU make"; - $make_path = "make"; - $tmpfilesuffix = "mk"; - $pwd = &get_this_pwd; + my $prog = $_[0]; + my ($v, $d, $f) = splitpath($prog); + + # If there's no directory then we need to search the PATH + if (! $d) { + foreach my $e (path()) { + $prog = catfile($e, $f); + -x $prog or continue; + ($v, $d, $f) = splitpath($prog); + last; + } + } + + return ($v, $d, $f); } sub set_more_defaults { - local($string); - local($index); - - # On DOS/Windows system the filesystem apparently can't track - # timestamps with second granularity (!!). Change the sleep time - # needed to force a file to be considered "old". - $wtime = $port_type eq 'UNIX' ? 1 : $port_type eq 'OS/2' ? 2 : 4; - - # Find the full pathname of Make. For DOS systems this is more - # complicated, so we ask make itself. - if ($osname eq 'VMS') { - $port_type = 'VMS-DCL' unless defined $ENV{"SHELL"}; - # On VMS pre-setup make to be found with simply 'make'. - $make_path = 'make'; - } else { - create_file('make.mk', 'all:;$(info $(MAKE))'); - my $mk = `$make_path -sf make.mk`; - unlink('make.mk'); - chop $mk; - $mk or die "FATAL ERROR: Cannot determine the value of \$(MAKE)\n"; - $make_path = $mk; - } + local($string); + local($index); + + # Now that we have located make_path, locate the srcdir and blddir + my ($mpv, $mpd, $mpf) = find_prog($make_path); + + # We have a make program so try to compute the blddir. + if ($mpd) { + my $f = catpath($mpv, catdir($mpd, 'tests'), 'config-flags.pm'); + if (-f $f) { + $bldvol = $mpv; + $blddir = $mpd; + } + } - # Ask make what shell to use - create_file('shell.mk', 'all:;$(info $(SHELL))'); - $sh_name = `$make_path -sf shell.mk`; - unlink('shell.mk'); - chop $sh_name; - if (! $sh_name) { - print "Cannot determine shell\n"; - $is_posix_sh = 0; - } else { - my $o = `$sh_name -c ': do nothing' 2>&1`; - $is_posix_sh = $? == 0 && $o == ''; - } + # If srcdir wasn't provided on the command line, try to find it. + if (! $srcdir && $blddir) { + # See if the blddir is the srcdir + my $f = catpath($bldvol, catdir($blddir, 'src'), 'gnumake.h'); + if (-f $f) { + $srcdir = $blddir; + $srcvol = $bldvol; + } + } - $string = `$make_path -v`; - $string =~ /^(GNU Make [^,\n]*)/ or die "$make_path is not GNU make. Version:\n$string"; - $testee_version = "$1\n"; + if (! $srcdir) { + # Not found, see if our parent is the source dir + my $f = catpath($cwdvol, catdir(updir(), 'src'), 'gnumake.h'); + if (-f $f) { + $srcdir = updir(); + $srcvol = $cwdvol; + } + } - create_file('null.mk', ''); + # If we have srcdir but not blddir, set them equal + if ($srcdir && !$blddir) { + $blddir = $srcdir; + $bldvol = $srcvol; + } - my $redir = '2>&1'; - $redir = '' if os_name eq 'VMS'; - $string = `$make_path -f null.mk $redir`; - if ($string =~ /(.*): \*\*\* No targets\. Stop\./) { - $make_name = $1; - } - else { - $make_path =~ /^(?:.*$pathsep)?(.+)$/; - $make_name = $1; - } + # Load the config flags + if (!$blddir) { + warn "Cannot locate config-flags.pm (no blddir)\n"; + } else { + my $f = catpath($bldvol, catdir($blddir, 'tests'), 'config-flags.pm'); + if (! -f $f) { + warn "Cannot locate $f\n"; + } else { + unshift(@INC, catpath($bldvol, catdir($blddir, 'tests'), '')); + require "config-flags.pm"; + } + } + + # On DOS/Windows system the filesystem apparently can't track + # timestamps with second granularity (!!). Change the sleep time + # needed to force a file to be considered "old". + $wtime = $port_type eq 'UNIX' ? 1 : $port_type eq 'OS/2' ? 2 : 4; + + # Find the full pathname of Make. For DOS systems this is more + # complicated, so we ask make itself. + if ($osname eq 'VMS') { + $port_type = 'VMS-DCL' unless defined $ENV{"SHELL"}; + # On VMS pre-setup make to be found with simply 'make'. + $make_path = 'make'; + } else { + create_file('make.mk', 'all:;$(info $(MAKE))'); + my $mk = `$make_path -sf make.mk`; + unlink('make.mk'); + chop $mk; + $mk or die "FATAL ERROR: Cannot determine the value of \$(MAKE)\n"; + $make_path = $mk; + } + ($mpv, $mpd, $mpf) = splitpath($make_path); + + # Ask make what shell to use + create_file('shell.mk', 'all:;$(info $(SHELL))'); + $sh_name = `$make_path -sf shell.mk`; + unlink('shell.mk'); + chop $sh_name; + if (! $sh_name) { + print "Cannot determine shell\n"; + $is_posix_sh = 0; + } else { + my $o = `$sh_name -c ': do nothing' 2>&1`; + $is_posix_sh = $? == 0 && $o eq ''; + } - # prepend pwd if this is a relative path (ie, does not - # start with a slash, but contains one). Thanks for the - # clue, Roland. + $string = `$make_path -v`; + $string =~ /^(GNU Make [^,\n]*)/ or die "$make_path is not GNU make. Version:\n$string"; + $testee_version = "$1\n"; - if (index ($make_path, ":") != 1 && index ($make_path, "/") > 0) - { - $mkpath = "$pwd$pathsep$make_path"; - } - else - { - $mkpath = $make_path; - } + create_file('null.mk', ''); - # If srcdir wasn't provided on the command line, see if the - # location of the make program gives us a clue. Don't fail if not; - # we'll assume it's been installed into /usr/include or wherever. - if (! $srcdir) { - $make_path =~ /^(.*$pathsep)?/; - my $d = $1 || '../'; - -f "${d}/src/gnumake.h" and $srcdir = $d; - } + my $redir = '2>&1'; + $redir = '' if os_name eq 'VMS'; + $string = `$make_path -f null.mk $redir`; + if ($string =~ /(.*): \*\*\* No targets\. Stop\./) { + $make_name = $1; + } else { + $make_name = $mpf; + } - # Not with the make program, so see if we can get it out of the makefile - if (! $srcdir && open(MF, "< ../Makefile")) { - local $/ = undef; - $_ = <MF>; - close(MF); - /^abs_srcdir\s*=\s*(.*?)\s*$/m; - -f "$1/src/gnumake.h" and $srcdir = $1; - } + # prepend pwd if this is a relative path (ie, does not + # start with a slash, but contains one). Thanks for the + # clue, Roland. - # Get Purify log info--if any. + if ($mpd && !file_name_is_absolute($make_path) && $cwdvol == $mpv) { + $mkpath = catpath($cwdvol, catdir($cwd, $mpd), $mpf); + } else { + $mkpath = $make_path; + } - if (exists $ENV{PURIFYOPTIONS} - && $ENV{PURIFYOPTIONS} =~ /.*-logfile=([^ ]+)/) { - $pure_log = $1 || ''; - $pure_log =~ s/%v/$make_name/; - $purify_errors = 0; - } + # Not with the make program, so see if we can get it out of the makefile + if (! $srcdir && open(MF, '<', catfile(updir(), 'Makefile'))) { + local $/ = undef; + $_ = <MF>; + close(MF); + /^abs_srcdir\s*=\s*(.*?)\s*$/m; + -f catfile($1, 'src', 'gnumake.h') and $srcdir = $1; + } - $string = `$make_path -j 2 -f null.mk $redir`; - if ($string =~ /not supported/) { - $parallel_jobs = 0; - } - else { - $parallel_jobs = 1; - } + # Get Purify log info--if any. - unlink('null.mk'); + if (exists $ENV{PURIFYOPTIONS} + && $ENV{PURIFYOPTIONS} =~ /.*-logfile=([^ ]+)/) { + $pure_log = $1 || ''; + $pure_log =~ s/%v/$make_name/; + $purify_errors = 0; + } - create_file('features.mk', 'all:;$(info $(.FEATURES))'); - %FEATURES = map { $_ => 1 } split /\s+/, `$make_path -sf features.mk`; - unlink('features.mk'); + $string = `$make_path -j 2 -f null.mk $redir`; + if ($string =~ /not supported/) { + $parallel_jobs = 0; + } + else { + $parallel_jobs = 1; + } - # Set up for valgrind, if requested. + unlink('null.mk'); - $make_command = $make_path; + create_file('features.mk', 'all:;$(info $(.FEATURES))'); + %FEATURES = map { $_ => 1 } split /\s+/, `$make_path -sf features.mk`; + unlink('features.mk'); - if ($valgrind) { - my $args = $valgrind_args; - open(VALGRIND, "> valgrind.out") - || die "Cannot open valgrind.out: $!\n"; - # -q --leak-check=yes - exists $ENV{VALGRIND_ARGS} and $args = $ENV{VALGRIND_ARGS}; - $make_path = "valgrind --log-fd=".fileno(VALGRIND)." $args $make_path"; - # F_SETFD is 2 - fcntl(VALGRIND, 2, 0) or die "fcntl(setfd) failed: $!\n"; - system("echo Starting on `date` 1>&".fileno(VALGRIND)); - print "Enabled valgrind support.\n"; - } + # Set up for valgrind, if requested. - if ($debug) { - print "Port type: $port_type\n"; - print "Make path: $make_path\n"; - print "Shell path: $sh_name".($is_posix_sh ? ' (POSIX)' : '')."\n"; - print "#PWD#: $pwd\n"; - print "#PERL#: $perl_name\n"; - print "#MAKEPATH#: $mkpath\n"; - print "#MAKE#: $make_name\n"; - } + $make_command = $make_path; + + if ($valgrind) { + my $args = $valgrind_args; + open(VALGRIND, "> valgrind.out") or die "Cannot open valgrind.out: $!\n"; + # -q --leak-check=yes + exists $ENV{VALGRIND_ARGS} and $args = $ENV{VALGRIND_ARGS}; + $make_path = "valgrind --log-fd=".fileno(VALGRIND)." $args $make_path"; + # F_SETFD is 2 + fcntl(VALGRIND, 2, 0) or die "fcntl(setfd) failed: $!\n"; + system("echo Starting on `date` 1>&".fileno(VALGRIND)); + print "Enabled valgrind support.\n"; + } + + if ($debug) { + print "Port type: $port_type\n"; + print "Make path: $make_path\n"; + print "Shell path: $sh_name".($is_posix_sh ? ' (POSIX)' : '')."\n"; + print "#PWD#: $cwdpath\n"; + print "#PERL#: $perl_name\n"; + print "#MAKEPATH#: $mkpath\n"; + print "#MAKE#: $make_name\n"; + } } sub setup_for_test |