Imported Upstream version 3.82
[platform/upstream/make.git] / tests / run_make_tests.pl
1 #!/usr/bin/env perl
2 # -*-perl-*-
3
4 # Test driver for the Make test suite
5
6 # Usage:  run_make_tests  [testname]
7 #                         [-debug]
8 #                         [-help]
9 #                         [-verbose]
10 #                         [-keep]
11 #                         [-make <make prog>]
12 #                        (and others)
13
14 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
15 # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software
16 # Foundation, Inc.
17 # This file is part of GNU Make.
18 #
19 # GNU Make is free software; you can redistribute it and/or modify it under
20 # the terms of the GNU General Public License as published by the Free Software
21 # Foundation; either version 3 of the License, or (at your option) any later
22 # version.
23 #
24 # GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
25 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
26 # FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
27 # details.
28 #
29 # You should have received a copy of the GNU General Public License along with
30 # this program.  If not, see <http://www.gnu.org/licenses/>.
31
32
33 $valgrind = 0;              # invoke make with valgrind
34 $valgrind_args = '';
35 $memcheck_args = '--num-callers=15 --tool=memcheck --leak-check=full';
36 $massif_args = '--num-callers=15 --tool=massif --alloc-fn=xmalloc --alloc-fn=xcalloc --alloc-fn=xrealloc --alloc-fn=xstrdup --alloc-fn=xstrndup';
37 $pure_log = undef;
38
39 $command_string = '';
40
41 $all_tests = 0;
42
43 require "test_driver.pl";
44
45 # Some target systems might not have the POSIX module...
46 $has_POSIX = eval { require "POSIX.pm" };
47
48 #$SIG{INT} = sub { print STDERR "Caught a signal!\n"; die @_; };
49
50 sub valid_option
51 {
52    local($option) = @_;
53
54    if ($option =~ /^-make([-_]?path)?$/i) {
55        $make_path = shift @argv;
56        if (!-f $make_path) {
57            print "$option $make_path: Not found.\n";
58            exit 0;
59        }
60        return 1;
61    }
62
63    if ($option =~ /^-all([-_]?tests)?$/i) {
64        $all_tests = 1;
65        return 1;
66    }
67
68    if ($option =~ /^-(valgrind|memcheck)$/i) {
69        $valgrind = 1;
70        $valgrind_args = $memcheck_args;
71        return 1;
72    }
73
74    if ($option =~ /^-massif$/i) {
75        $valgrind = 1;
76        $valgrind_args = $massif_args;
77        return 1;
78    }
79
80 # This doesn't work--it _should_!  Someone badly needs to fix this.
81 #
82 #   elsif ($option =~ /^-work([-_]?dir)?$/)
83 #   {
84 #      $workdir = shift @argv;
85 #      return 1;
86 #   }
87
88    return 0;
89 }
90
91
92 # This is an "all-in-one" function.  Arguments are as follows:
93 #
94 #  [0] (string):  The makefile to be tested.  undef means use the last one.
95 #  [1] (string):  Arguments to pass to make.
96 #  [2] (string):  Answer we should get back.
97 #  [3] (integer): Exit code we expect.  A missing code means 0 (success)
98
99 $old_makefile = undef;
100
101 sub run_make_test
102 {
103   local ($makestring, $options, $answer, $err_code, $timeout) = @_;
104
105   # If the user specified a makefile string, create a new makefile to contain
106   # it.  If the first value is not defined, use the last one (if there is
107   # one).
108
109   if (! defined $makestring) {
110     defined $old_makefile
111       || die "run_make_test(undef) invoked before run_make_test('...')\n";
112     $makefile = $old_makefile;
113   } else {
114     if (! defined($makefile)) {
115       $makefile = &get_tmpfile();
116     }
117
118     # Make sure it ends in a newline.
119     $makestring && $makestring !~ /\n$/s and $makestring .= "\n";
120
121     # Replace @MAKEFILE@ with the makefile name and @MAKE@ with the path to
122     # make
123     $makestring =~ s/#MAKEFILE#/$makefile/g;
124     $makestring =~ s/#MAKEPATH#/$mkpath/g;
125     $makestring =~ s/#MAKE#/$make_name/g;
126     $makestring =~ s/#PERL#/$perl_name/g;
127     $makestring =~ s/#PWD#/$pwd/g;
128
129     # Populate the makefile!
130     open(MAKEFILE, "> $makefile") || die "Failed to open $makefile: $!\n";
131     print MAKEFILE $makestring;
132     close(MAKEFILE) || die "Failed to write $makefile: $!\n";
133   }
134
135   # Do the same processing on $answer as we did on $makestring.
136
137   $answer && $answer !~ /\n$/s and $answer .= "\n";
138   $answer =~ s/#MAKEFILE#/$makefile/g;
139   $answer =~ s/#MAKEPATH#/$mkpath/g;
140   $answer =~ s/#MAKE#/$make_name/g;
141   $answer =~ s/#PERL#/$perl_name/g;
142   $answer =~ s/#PWD#/$pwd/g;
143
144   run_make_with_options($makefile, $options, &get_logfile(0),
145                         $err_code, $timeout);
146   &compare_output($answer, &get_logfile(1));
147
148   $old_makefile = $makefile;
149   $makefile = undef;
150 }
151
152 # The old-fashioned way...
153 sub run_make_with_options {
154   local ($filename,$options,$logname,$expected_code,$timeout) = @_;
155   local($code);
156   local($command) = $make_path;
157
158   $expected_code = 0 unless defined($expected_code);
159
160   # Reset to reflect this one test.
161   $test_passed = 1;
162
163   if ($filename) {
164     $command .= " -f $filename";
165   }
166
167   if ($options) {
168     $command .= " $options";
169   }
170
171   $command_string = "$command\n";
172
173   if ($valgrind) {
174     print VALGRIND "\n\nExecuting: $command\n";
175   }
176
177
178   {
179       my $old_timeout = $test_timeout;
180       $timeout and $test_timeout = $timeout;
181
182       # If valgrind is enabled, turn off the timeout check
183       $valgrind and $test_timeout = 0;
184
185       $code = &run_command_with_output($logname,$command);
186
187       $test_timeout = $old_timeout;
188   }
189
190   # Check to see if we have Purify errors.  If so, keep the logfile.
191   # For this to work you need to build with the Purify flag -exit-status=yes
192
193   if ($pure_log && -f $pure_log) {
194     if ($code & 0x7000) {
195       $code &= ~0x7000;
196
197       # If we have a purify log, save it
198       $tn = $pure_testname . ($num_of_logfiles ? ".$num_of_logfiles" : "");
199       print("Renaming purify log file to $tn\n") if $debug;
200       rename($pure_log, "$tn")
201         || die "Can't rename $log to $tn: $!\n";
202       ++$purify_errors;
203     } else {
204       unlink($pure_log);
205     }
206   }
207
208   if ($code != $expected_code) {
209     print "Error running $make_path (expected $expected_code; got $code): $command\n";
210     $test_passed = 0;
211     $runf = &get_runfile;
212     &create_file (&get_runfile, $command_string);
213     # If it's a SIGINT, stop here
214     if ($code & 127) {
215       print STDERR "\nCaught signal ".($code & 127)."!\n";
216       ($code & 127) == 2 and exit($code);
217     }
218     return 0;
219   }
220
221   if ($profile & $vos) {
222     system "add_profile $make_path";
223   }
224
225   return 1;
226 }
227
228 sub print_usage
229 {
230    &print_standard_usage ("run_make_tests",
231                           "[-make_path make_pathname] [-memcheck] [-massif]",);
232 }
233
234 sub print_help
235 {
236    &print_standard_help (
237         "-make_path",
238         "\tYou may specify the pathname of the copy of make to run.",
239         "-valgrind",
240         "-memcheck",
241         "\tRun the test suite under valgrind's memcheck tool.",
242         "\tChange the default valgrind args with the VALGRIND_ARGS env var.",
243         "-massif",
244         "\tRun the test suite under valgrind's massif toool.",
245         "\tChange the default valgrind args with the VALGRIND_ARGS env var."
246        );
247 }
248
249 sub get_this_pwd {
250   $delete_command = 'rm -f';
251   if ($has_POSIX) {
252     $__pwd = POSIX::getcwd();
253   } elsif ($vos) {
254     $delete_command = "delete_file -no_ask";
255     $__pwd = `++(current_dir)`;
256   } else {
257     # No idea... just try using pwd as a last resort.
258     chop ($__pwd = `pwd`);
259   }
260
261   return $__pwd;
262 }
263
264 sub set_defaults
265 {
266    # $profile = 1;
267    $testee = "GNU make";
268    $make_path = "make";
269    $tmpfilesuffix = "mk";
270    $pwd = &get_this_pwd;
271 }
272
273 sub set_more_defaults
274 {
275    local($string);
276    local($index);
277
278    # find the type of the port.  We do this up front to have a single
279    # point of change if it needs to be tweaked.
280    #
281    # This is probably not specific enough.
282    #
283    if ($osname =~ /Windows/i || $osname =~ /MINGW32/i || $osname =~ /CYGWIN_NT/i) {
284      $port_type = 'W32';
285    }
286    # Bleah, the osname is so variable on DOS.  This kind of bites.
287    # Well, as far as I can tell if we check for some text at the
288    # beginning of the line with either no spaces or a single space, then
289    # a D, then either "OS", "os", or "ev" and a space.  That should
290    # match and be pretty specific.
291    elsif ($osname =~ /^([^ ]*|[^ ]* [^ ]*)D(OS|os|ev) /) {
292      $port_type = 'DOS';
293    }
294    # Check for OS/2
295    elsif ($osname =~ m%OS/2%) {
296      $port_type = 'OS/2';
297    }
298    # Everything else, right now, is UNIX.  Note that we should integrate
299    # the VOS support into this as well and get rid of $vos; we'll do
300    # that next time.
301    else {
302      $port_type = 'UNIX';
303    }
304
305    # On DOS/Windows system the filesystem apparently can't track
306    # timestamps with second granularity (!!).  Change the sleep time
307    # needed to force a file to be considered "old".
308    $wtime = $port_type eq 'UNIX' ? 1 : $port_type eq 'OS/2' ? 2 : 4;
309
310    print "Port type: $port_type\n" if $debug;
311    print "Make path: $make_path\n" if $debug;
312
313    # Find the full pathname of Make.  For DOS systems this is more
314    # complicated, so we ask make itself.
315    my $mk = `sh -c 'echo "all:;\@echo \\\$(MAKE)" | $make_path -f-'`;
316    chop $mk;
317    $mk or die "FATAL ERROR: Cannot determine the value of \$(MAKE):\n
318 'echo \"all:;\@echo \\\$(MAKE)\" | $make_path -f-' failed!\n";
319    $make_path = $mk;
320    print "Make\t= `$make_path'\n" if $debug;
321
322    $string = `$make_path -v -f /dev/null 2> /dev/null`;
323
324    $string =~ /^(GNU Make [^,\n]*)/;
325    $testee_version = "$1\n";
326
327    $string = `sh -c "$make_path -f /dev/null 2>&1"`;
328    if ($string =~ /(.*): \*\*\* No targets\.  Stop\./) {
329      $make_name = $1;
330    }
331    else {
332      if ($make_path =~ /$pathsep([^\n$pathsep]*)$/) {
333        $make_name = $1;
334      }
335      else {
336        $make_name = $make_path;
337      }
338    }
339
340    # prepend pwd if this is a relative path (ie, does not
341    # start with a slash, but contains one).  Thanks for the
342    # clue, Roland.
343
344    if (index ($make_path, ":") != 1 && index ($make_path, "/") > 0)
345    {
346       $mkpath = "$pwd$pathsep$make_path";
347    }
348    else
349    {
350       $mkpath = $make_path;
351    }
352
353    # Get Purify log info--if any.
354
355    if (exists $ENV{PURIFYOPTIONS}
356        && $ENV{PURIFYOPTIONS} =~ /.*-logfile=([^ ]+)/) {
357      $pure_log = $1 || '';
358      $pure_log =~ s/%v/$make_name/;
359      $purify_errors = 0;
360    }
361
362    $string = `sh -c "$make_path -j 2 -f /dev/null 2>&1"`;
363    if ($string =~ /not supported/) {
364      $parallel_jobs = 0;
365    }
366    else {
367      $parallel_jobs = 1;
368    }
369
370    # Set up for valgrind, if requested.
371
372    if ($valgrind) {
373      my $args = $valgrind_args;
374      open(VALGRIND, "> valgrind.out")
375        || die "Cannot open valgrind.out: $!\n";
376      #  -q --leak-check=yes
377      exists $ENV{VALGRIND_ARGS} and $args = $ENV{VALGRIND_ARGS};
378      $make_path = "valgrind --log-fd=".fileno(VALGRIND)." $args $make_path";
379      # F_SETFD is 2
380      fcntl(VALGRIND, 2, 0) or die "fcntl(setfd) failed: $!\n";
381      system("echo Starting on `date` 1>&".fileno(VALGRIND));
382      print "Enabled valgrind support.\n";
383    }
384 }
385
386 sub setup_for_test
387 {
388   $makefile = &get_tmpfile;
389   if (-f $makefile) {
390     unlink $makefile;
391   }
392
393   # Get rid of any Purify logs.
394   if ($pure_log) {
395     ($pure_testname = $testname) =~ tr,/,_,;
396     $pure_testname = "$pure_log.$pure_testname";
397     system("rm -f $pure_testname*");
398     print("Purify testfiles are: $pure_testname*\n") if $debug;
399   }
400 }
401
402 exit !&toplevel;