diff options
author | JinWang An <jinwang.an@samsung.com> | 2021-12-28 15:15:18 +0900 |
---|---|---|
committer | JinWang An <jinwang.an@samsung.com> | 2021-12-28 15:15:18 +0900 |
commit | b11e2699c7ec42e6d2fc0f4c940f14e7c89b3974 (patch) | |
tree | 14002517ee70130303762f511b4d1b50251267ca /tests/run_make_tests.pl | |
parent | 0a1cba99f5ce73ae0cacdbf9ab1186137efd77f7 (diff) | |
download | make-b11e2699c7ec42e6d2fc0f4c940f14e7c89b3974.tar.gz make-b11e2699c7ec42e6d2fc0f4c940f14e7c89b3974.tar.bz2 make-b11e2699c7ec42e6d2fc0f4c940f14e7c89b3974.zip |
Imported Upstream version 4.3upstream/4.3
Diffstat (limited to 'tests/run_make_tests.pl')
-rw-r--r-- | tests/run_make_tests.pl | 533 |
1 files changed, 362 insertions, 171 deletions
diff --git a/tests/run_make_tests.pl b/tests/run_make_tests.pl index 916f346..d76e4f3 100644 --- a/tests/run_make_tests.pl +++ b/tests/run_make_tests.pl @@ -11,7 +11,7 @@ # [-make <make prog>] # (and others) -# Copyright (C) 1992-2016 Free Software Foundation, Inc. +# Copyright (C) 1992-2020 Free Software Foundation, Inc. # This file is part of GNU Make. # # GNU Make is free software; you can redistribute it and/or modify it under @@ -27,6 +27,23 @@ # 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"; + +our $testsroot = $FindBin::Bin; + +require "test_driver.pl"; + +use File::Spec; + +use Cwd; +$cwdpath = cwd(); +($cwdvol, $cwddir, $_) = File::Spec->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,12 +53,29 @@ $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; +$fqsrcdir = undef; +$srcvol = undef; + +# The location of the build directory +$blddir = undef; +$fqblddir = undef; +$bldvol = undef; + +$make_path = undef; +@make_command = (); $command_string = ''; $all_tests = 0; +# Shell commands + +$sh_name = '/bin/sh'; +$is_posix_sh = 1; + +$CMD_rmfile = 'rm -f'; + # rmdir broken in some Perls on VMS. if ($^O eq 'VMS') { @@ -56,13 +90,75 @@ if ($^O eq 'VMS') }; *CORE::GLOBAL::rmdir = \&vms_rmdir; + + $CMD_rmfile = 'delete_file -no_ask'; } -require "test_driver.pl"; -require "config-flags.pm"; +%CONFIG_FLAGS = (); -# Some target systems might not have the POSIX module... -$has_POSIX = eval { require "POSIX.pm" }; +# Find the strings that will be generated for various error codes. +# We want them from the C locale regardless of our current locale. + +$ERR_no_such_file = undef; +$ERR_read_only_file = undef; +$ERR_unreadable_file = undef; +$ERR_nonexe_file = undef; +$ERR_exe_dir = undef; + +{ + use locale; + + 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 @_; }; @@ -81,7 +177,7 @@ sub valid_option if ($option =~ /^-srcdir$/i) { $srcdir = shift @argv; - if (! -f "$srcdir/gnumake.h") { + if (! -f File::Spec->catfile($srcdir, 'src', 'gnumake.h')) { print "$option $srcdir: Not a valid GNU make source directory.\n"; exit 0; } @@ -124,7 +220,11 @@ sub valid_option # [2] (string): Answer we should get back. # [3] (integer): Exit code we expect. A missing code means 0 (success) +$makefile = undef; $old_makefile = undef; +$mkpath = undef; +$make_name = undef; +$helptool = undef; sub subst_make_string { @@ -133,7 +233,9 @@ 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; + # If we're using a shell + s/#HELPER#/$perl_name $helptool/g; return $_; } @@ -148,7 +250,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)) { @@ -160,9 +262,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. @@ -179,12 +281,35 @@ sub run_make_test $makefile = undef; } +sub add_options { + my $cmd = shift; + + foreach (@_) { + if (ref($cmd)) { + push(@$cmd, ref($_) ? @$_ : $_); + } else { + $cmd .= ' '.(ref($_) ? "@$_" : $_); + } + } + + return $cmd; +} + +sub create_command { + return !$_[0] || ref($_[0]) ? [@make_command] : join(' ', @make_command); +} + # The old-fashioned way... +# $options can be a scalar (string) or a ref to an array of options +# If it's a scalar the entire argument is passed to system/exec etc. as +# a single string. If it's a ref then the array is passed to system/exec. +# Using a ref should be preferred as it's more portable but all the older +# invocations use strings. sub run_make_with_options { my ($filename,$options,$logname,$expected_code,$timeout,@call) = @_; @call = caller unless @call; - local($code); - local($command) = $make_path; + my $code; + my $command = create_command($options); $expected_code = 0 unless defined($expected_code); @@ -192,13 +317,14 @@ sub run_make_with_options { $test_passed = 1; if ($filename) { - $command .= " -f $filename"; + $command = add_options($command, '-f', $filename); } if ($options) { - if ($^O eq 'VMS') { + if (!ref($options) && $^O eq 'VMS') { # Try to make sure arguments are properly quoted. # This does not handle all cases. + # We should convert the tests to use array refs not strings # VMS uses double quotes instead of single quotes. $options =~ s/\'/\"/g; @@ -230,20 +356,22 @@ sub run_make_with_options { print ("Options fixup = -$options-\n") if $debug; } - $command .= " $options"; + + $command = add_options($command, $options); } - $command_string = ""; + my $cmdstr = ref($command) ? "'".join("' '", @$command)."'" : $command; + if (@call) { - $command_string = "#$call[1]:$call[2]\n"; + $command_string = "#$call[1]:$call[2]\n$cmdstr\n"; + } else { + $command_string = $cmdstr; } - $command_string .= "$command\n"; if ($valgrind) { - print VALGRIND "\n\nExecuting: $command\n"; + print VALGRIND "\n\nExecuting: $cmdstr\n"; } - { my $old_timeout = $test_timeout; $timeout and $test_timeout = $timeout; @@ -251,7 +379,11 @@ sub run_make_with_options { # If valgrind is enabled, turn off the timeout check $valgrind and $test_timeout = 0; - $code = &run_command_with_output($logname,$command); + if (ref($command)) { + $code = run_command_with_output($logname, @$command); + } else { + $code = run_command_with_output($logname, $command); + } $test_timeout = $old_timeout; } @@ -265,8 +397,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 $pure_log to $tn: $!\n"; ++$purify_errors; } else { unlink($pure_log); @@ -274,9 +405,8 @@ sub run_make_with_options { } if ($code != $expected_code) { - print "Error running $make_path (expected $expected_code; got $code): $command\n"; + print "Error running @make_command (expected $expected_code; got $code): $cmdstr\n"; $test_passed = 0; - $runf = &get_runfile; &create_file (&get_runfile, $command_string); # If it's a SIGINT, stop here if ($code & 127) { @@ -287,7 +417,7 @@ sub run_make_with_options { } if ($profile & $vos) { - system "add_profile $make_path"; + system "add_profile @make_command"; } return 1; @@ -311,180 +441,241 @@ 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 { - $delete_command = 'rm -f'; - if ($has_POSIX) { - $__pwd = POSIX::getcwd(); - } elsif ($vos) { - $delete_command = "delete_file -no_ask"; - $__pwd = `++(current_dir)`; +sub set_defaults +{ + # $profile = 1; + $testee = "GNU make"; + $make_path = "make"; + $tmpfilesuffix = "mk"; + if ($port_type eq 'UNIX') { + $scriptsuffix = '.sh'; + } elsif ($port_type eq 'VMS') { + $scriptsuffix = '.com'; } else { - # No idea... just try using pwd as a last resort. - chop ($__pwd = `pwd`); + $scriptsuffix = '.bat'; + } +} + +# 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 +{ + my $prog = $_[0]; + my ($v, $d, $f) = File::Spec->splitpath($prog); + + # If there's no directory then we need to search the PATH + if (! $d) { + foreach my $e (File::Spec->path()) { + $prog = File::Spec->catfile($e, $f); + if (-x $prog) { + ($v, $d, $f) = File::Spec->splitpath($prog); + last; + } + } } - return $__pwd; + return ($v, $d, $f); } -sub set_defaults +sub get_config { - # $profile = 1; - $testee = "GNU make"; - $make_path = "make"; - $tmpfilesuffix = "mk"; - $pwd = &get_this_pwd; + return exists($CONFIG_FLAGS{$_[0]}) ? $CONFIG_FLAGS{$_[0]} : ''; } sub set_more_defaults { - local($string); - local($index); - - # find the type of the port. We do this up front to have a single - # point of change if it needs to be tweaked. - # - # This is probably not specific enough. - # - if ($osname =~ /Windows/i || $osname =~ /MINGW32/i || $osname =~ /CYGWIN_NT/i) { - $port_type = 'W32'; - } - # Bleah, the osname is so variable on DOS. This kind of bites. - # Well, as far as I can tell if we check for some text at the - # beginning of the line with either no spaces or a single space, then - # a D, then either "OS", "os", or "ev" and a space. That should - # match and be pretty specific. - elsif ($osname =~ /^([^ ]*|[^ ]* [^ ]*)D(OS|os|ev) /) { - $port_type = 'DOS'; - } - # Check for OS/2 - elsif ($osname =~ m%OS/2%) { - $port_type = 'OS/2'; - } + my $string; - # VMS has a GNV Unix mode or a DCL mode. - # The SHELL environment variable should not be defined in VMS-DCL mode. - elsif ($osname eq 'VMS' && !defined $ENV{"SHELL"}) { - $port_type = 'VMS-DCL'; - } - # Everything else, right now, is UNIX. Note that we should integrate - # the VOS support into this as well and get rid of $vos; we'll do - # that next time. - else { - $port_type = 'UNIX'; - } + # Now that we have located make_path, locate the srcdir and blddir + my ($mpv, $mpd, $mpf) = find_prog($make_path); - # 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; - - print "Port type: $port_type\n" if $debug; - print "Make path: $make_path\n" if $debug; - - # 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 { - my $mk = `sh -c 'echo "all:;\@echo \\\$(MAKE)" | $make_path -f-'`; - chop $mk; - $mk or die "FATAL ERROR: Cannot determine the value of \$(MAKE):\n -'echo \"all:;\@echo \\\$(MAKE)\" | $make_path -f-' failed!\n"; - $make_path = $mk; - } - print "Make\t= '$make_path'\n" if $debug; + # We have a make program so try to compute the blddir. + if ($mpd) { + my $f = File::Spec->catpath($mpv, File::Spec->catdir($mpd, 'tests'), 'config-flags.pm'); + if (-f $f) { + $bldvol = $mpv; + $blddir = $mpd; + } + } - my $redir2 = '2> /dev/null'; - $redir2 = '' if os_name eq 'VMS'; - $string = `$make_path -v -f /dev/null $redir2`; + # 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 = File::Spec->catpath($bldvol, File::Spec->catdir($blddir, 'src'), 'gnumake.h'); + if (-f $f) { + $srcdir = $blddir; + $srcvol = $bldvol; + } + } - $string =~ /^(GNU Make [^,\n]*)/; - $testee_version = "$1\n"; + if (! $srcdir) { + # Not found, see if our parent is the source dir + my $f = File::Spec->catpath($cwdvol, File::Spec->catdir(File::Spec->updir(), 'src'), 'gnumake.h'); + if (-f $f) { + $srcdir = File::Spec->updir(); + $srcvol = $cwdvol; + } + } - my $redir = '2>&1'; - $redir = '' if os_name eq 'VMS'; - $string = `sh -c "$make_path -f /dev/null $redir"`; - if ($string =~ /(.*): \*\*\* No targets\. Stop\./) { - $make_name = $1; - } - else { - $make_path =~ /^(?:.*$pathsep)?(.+)$/; - $make_name = $1; - } + # If we have srcdir but not blddir, set them equal + if ($srcdir && !$blddir) { + $blddir = $srcdir; + $bldvol = $srcvol; + } - # prepend pwd if this is a relative path (ie, does not - # start with a slash, but contains one). Thanks for the - # clue, Roland. + # Load the config flags + if (!$blddir) { + warn "Cannot locate config-flags.pm (no blddir)\n"; + } else { + my $f = File::Spec->catpath($bldvol, File::Spec->catdir($blddir, 'tests'), 'config-flags.pm'); + if (! -f $f) { + warn "Cannot locate $f\n"; + } else { + unshift(@INC, File::Spec->catpath($bldvol, File::Spec->catdir($blddir, 'tests'), '')); + require "config-flags.pm"; + } + } - if (index ($make_path, ":") != 1 && index ($make_path, "/") > 0) - { - $mkpath = "$pwd$pathsep$make_path"; - } - else - { - $mkpath = $make_path; - } + # 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) = File::Spec->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 ''; + } - # 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}gnumake.h" and $srcdir = $d; - } + $string = `$make_path -v`; + $string =~ /^(GNU Make [^,\n]*)/ or die "$make_path is not GNU make. Version:\n$string"; + $testee_version = "$1\n"; - # 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/gnumake.h" and $srcdir = $1; - } + create_file('null.mk', ''); - # Get Purify log info--if any. + 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; + } - if (exists $ENV{PURIFYOPTIONS} - && $ENV{PURIFYOPTIONS} =~ /.*-logfile=([^ ]+)/) { - $pure_log = $1 || ''; - $pure_log =~ s/%v/$make_name/; - $purify_errors = 0; - } + # prepend pwd if this is a relative path (ie, does not + # start with a slash, but contains one). Thanks for the + # clue, Roland. - $string = `sh -c "$make_path -j 2 -f /dev/null $redir"`; - if ($string =~ /not supported/) { - $parallel_jobs = 0; - } - else { - $parallel_jobs = 1; - } + if ($mpd && !File::Spec->file_name_is_absolute($make_path) && $cwdvol == $mpv) { + $mkpath = File::Spec->catpath($cwdvol, File::Spec->catdir($cwd, $mpd), $mpf); + } else { + $mkpath = $make_path; + } - %FEATURES = map { $_ => 1 } split /\s+/, `sh -c "echo '\\\$(info \\\$(.FEATURES))' | $make_path -f- 2>/dev/null"`; + # Not with the make program, so see if we can get it out of the makefile + if (! $srcdir && open(MF, '<', File::Spec->catfile(File::Spec->updir(), 'Makefile'))) { + local $/ = undef; + $_ = <MF>; + close(MF); + /^abs_srcdir\s*=\s*(.*?)\s*$/m; + -f File::Spec->catfile($1, 'src', 'gnumake.h') and $srcdir = $1; + } - # Set up for valgrind, if requested. + # At this point we should have srcdir and blddir: get fq versions + $fqsrcdir = File::Spec->rel2abs($srcdir); + $fqblddir = File::Spec->rel2abs($blddir); - $make_command = $make_path; + # Find the helper tool + $helptool = File::Spec->catfile($fqsrcdir, 'tests', 'thelp.pl'); - 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"; - } + # It's difficult to quote this properly in all the places it's used so + # ensure it doesn't need to be quoted. + $helptool =~ s,\\,/,g if $port_type eq 'W32'; + $helptool =~ s, ,\\ ,g; + + # Get Purify log info--if any. + + if (exists $ENV{PURIFYOPTIONS} + && $ENV{PURIFYOPTIONS} =~ /.*-logfile=([^ ]+)/) { + $pure_log = $1 || ''; + $pure_log =~ s/%v/$make_name/; + $purify_errors = 0; + } + + $string = `$make_path -j 2 -f null.mk $redir`; + if ($string =~ /not supported/) { + $parallel_jobs = 0; + } + else { + $parallel_jobs = 1; + } + + unlink('null.mk'); + + create_file('features.mk', 'all:;$(info $(.FEATURES))'); + %FEATURES = map { $_ => 1 } split /\s+/, `$make_path -sf features.mk`; + unlink('features.mk'); + + # Set up for valgrind, if requested. + + @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_command = ('valgrind', '--log-fd='.fileno(VALGRIND)); + push(@make_command, split(' ', $args)); + push(@make_command, $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 command: @make_command\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 |