scan for gmake and make to prefer gmake on systems that have it
[platform/upstream/curl.git] / tests / testcurl.pl
1 #!/usr/bin/env perl
2 #***************************************************************************
3 #                                  _   _ ____  _
4 #  Project                     ___| | | |  _ \| |
5 #                             / __| | | | |_) | |
6 #                            | (__| |_| |  _ <| |___
7 #                             \___|\___/|_| \_\_____|
8 #
9 # Copyright (C) 1998 - 2005, Daniel Stenberg, <daniel@haxx.se>, et al.
10 #
11 # This software is licensed as described in the file COPYING, which
12 # you should have received as part of this distribution. The terms
13 # are also available at http://curl.haxx.se/docs/copyright.html.
14 #
15 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
16 # copies of the Software, and permit persons to whom the Software is
17 # furnished to do so, under the terms of the COPYING file.
18 #
19 # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 # KIND, either express or implied.
21 #
22 # $Id$
23 ###########################################################################
24
25 ###########################
26 #  What is This Script?
27 ###########################
28
29 # testcurl.pl is the master script to use for automatic testing of CVS-curl.
30 # This is written for the purpose of being run from a crontab job or similar
31 # at a regular interval. The output is suitable to be mailed to
32 # curl-autocompile@haxx.se to be dealt with automatically (make sure the
33 # subject includes the word "autobuild" as the mail gets silently discarded
34 # otherwise).  The most current build status (with a resonable backlog) will
35 # be published on the curl site, at http://curl.haxx.se/auto/
36
37 # USAGE:
38 # testcurl.pl [options] [curl-daily-name] > output
39
40 # Options:
41 #
42 # --configure=[options]    Configure options
43 # --crosscompile           This is a crosscompile
44 # --desc=[desc]            Description of your test system
45 # --email=[email]          Set email address to report as
46 # --mktarball=[command]    Command to run after completed test
47 # --name=[name]            Set name to report as
48 # --nocvsup                Don't update from CVS even though it is a CVS tree
49 # --runtestopts=[options]  Options to pass to runtests.pl
50 # --setup=[file name]      File name to read setup from (deprecated)
51 # --target=[your os]       Specify your target environment.
52 #
53 # if [curl-daily-name] is omitted, a 'curl' CVS directory is assumed.
54 #
55
56 use strict;
57
58 use Cwd;
59
60 # Turn on warnings (equivalent to -w, which can't be used with /usr/bin/env)
61 #BEGIN { $^W = 1; }
62
63 use vars qw($version $fixed $infixed $CURLDIR $CVS $pwd $build $buildlog
64             $buildlogname $configurebuild $targetos $confsuffix $binext
65             $libext);
66 use vars qw($name $email $desc $confopts $runtestopts $setupfile $mktarball
67             $nocvsup $crosscompile);
68
69 # version of this script
70 $version='$Revision$';
71 $fixed=0;
72
73 # Determine if we're running from CVS or a canned copy of curl,
74 # or if we got a specific target option or setup file option.
75 $CURLDIR="curl";
76 $CVS=1;
77 $setupfile = 'setup';
78 while ($ARGV[0]) {
79   if ($ARGV[0] =~ /--target=/) {
80     $targetos = (split(/=/, shift @ARGV))[1];
81   }
82   elsif ($ARGV[0] =~ /--setup=/) {
83     $setupfile = (split(/=/, shift @ARGV))[1];
84   }
85   elsif ($ARGV[0] =~ /--mktarball=/) {
86     $mktarball = (split(/=/, shift @ARGV))[1];
87   }
88   elsif ($ARGV[0] =~ /--name=/) {
89     $name = (split(/=/, shift @ARGV))[1];
90   }
91   elsif ($ARGV[0] =~ /--email=/) {
92     $email = (split(/=/, shift @ARGV))[1];
93   }
94   elsif ($ARGV[0] =~ /--desc=/) {
95     $desc = (split(/=/, shift @ARGV))[1];
96   }
97   elsif ($ARGV[0] =~ /--configure=/) {
98     $confopts = (split(/=/, shift @ARGV))[1];
99   }
100   elsif ($ARGV[0] =~ /--nocvsup/) {
101     $nocvsup=1;
102     shift @ARGV;
103   }
104   elsif ($ARGV[0] =~ /--crosscompile/) {
105     $crosscompile=1;
106     shift @ARGV;
107   }
108   elsif ($ARGV[0] =~ /--runtestopts=/) {
109     $runtestopts = (split(/=/, shift @ARGV, 2))[1];
110   }
111   else {
112     $CURLDIR=shift @ARGV;
113     $CVS=0;
114   }
115 }
116
117 # Do the platform-specific stuff here
118 $configurebuild = 1;
119 $confsuffix = '';
120 $binext = '';
121 $libext = '.la'; # .la since both libcurl and libcares are made with libtool
122 if ($^O eq 'MSWin32' || $targetos) {
123   if (!$targetos) {
124     # If no target defined on Win32 lets assume vc
125     $targetos = 'vc';
126   }
127   if ($targetos =~ /vc/ || $targetos =~ /mingw32/ || $targetos =~ /borland/) {
128     $binext = '.exe';
129     $libext = '.lib' if ($targetos =~ /vc/ || $targetos =~ /borland/);
130     $libext = '.a' if ($targetos =~ /mingw32/);
131   }
132   elsif ($targetos =~ /netware/) {
133     $configurebuild = 0;
134     $binext = '.nlm';
135     $libext = '.lib';
136   }
137 }
138
139 if ($^O eq 'MSWin32') {
140
141   # Set these things only when building ON Windows, not when simply building
142   # FOR Windows since we might be cross-compiling on another system. Non-
143   # Windows builds still default to configure-style builds with no confsuffix.
144
145   $configurebuild = 0;
146   $confsuffix = '-win32';
147 }
148
149
150 $ENV{LANG}="C";
151
152 sub rmtree($) {
153     my $target = $_[0];
154     if ($^O eq 'MSWin32') {
155       foreach (glob($target)) {
156         s:/:\\:g;
157         system("rd /s /q $_");
158       }
159     } else {
160       system("rm -rf $target");
161     }
162 }
163
164 sub grepfile($$) {
165     my ($target, $fn) = @_;
166     open(F, $fn) or die;
167     while (<F>) {
168       if (/$target/) {
169         close(F);
170         return 1;
171       }
172     }
173     close(F);
174     return 0;
175 }
176
177 sub logit($) {
178     my $text=$_[0];
179     if ($text) {
180       print "testcurl: $text\n";
181     }
182 }
183
184 sub mydie($){
185     my $text=$_[0];
186     logit "$text";
187     chdir $pwd; # cd back to the original root dir
188
189     if ($pwd && $build) {
190       # we have a build directory name, remove the dir
191       logit "removing the $build dir";
192       rmtree "$pwd/$build";
193     }
194     if (-r $buildlog) {
195       # we have a build log output file left, remove it
196       logit "removing the $buildlogname file";
197       unlink "$buildlog";
198     }
199     logit "ENDING HERE"; # last line logged!
200     exit 1;
201 }
202
203 if (open(F, "$setupfile")) {
204   while (<F>) {
205     if (/(\w+)=(.*)/) {
206       eval "\$$1=$2;";
207     }
208   }
209   close(F);
210   $infixed=$fixed;
211 } else {
212   $infixed=0;    # so that "additional args to configure" works properly first time...
213 }
214
215 if (!$name) {
216   print "please enter your name\n";
217   $name = <>;
218   chomp $name;
219   $fixed=1;
220 }
221
222 if (!$email) {
223   print "please enter your contact email address\n";
224   $email = <>;
225   chomp $email;
226   $fixed=2;
227 }
228
229 if (!$desc) {
230   print "please enter a one line system description\n";
231   $desc = <>;
232   chomp $desc;
233   $fixed=3;
234 }
235
236 if (!$confopts) {
237   if ($infixed < 4) {
238     print "please enter your additional arguments to configure\n";
239     print "examples: --with-ssl --enable-debug --enable-ipv6 --with-krb4\n";
240     $confopts = <>;
241     chomp $confopts;
242   }
243 }
244
245
246 if ($fixed < 4) {
247     $fixed=4;
248     open(F, ">$setupfile") or die;
249     print F "name='$name'\n";
250     print F "email='$email'\n";
251     print F "desc='$desc'\n";
252     print F "confopts='$confopts'\n";
253     print F "fixed='$fixed'\n";
254     close(F);
255 }
256
257 logit "STARTING HERE"; # first line logged, for scripts to trigger on
258 logit "NAME = $name";
259 logit "EMAIL = $email";
260 logit "DESC = $desc";
261 logit "CONFOPTS = $confopts";
262 logit "CFLAGS = ".$ENV{CFLAGS};
263 logit "LDFLAGS = ".$ENV{LDFLAGS};
264 logit "CC = ".$ENV{CC};
265 logit "target = ".$targetos;
266 logit "version = $version"; # script version
267 logit "date = ".(scalar gmtime)." UTC";
268
269 # Make $pwd to become the path without newline. We'll use that in order to cut
270 # off that path from all possible logs and error messages etc.
271 $pwd = cwd();
272
273 if (-d $CURLDIR) {
274   if ($CVS && -d "$CURLDIR/CVS") {
275     logit "$CURLDIR is verified to be a fine source dir";
276     # remove the generated sources to force them to be re-generated each
277     # time we run this test
278     unlink "$CURLDIR/src/hugehelp.c";
279   } elsif (!$CVS && -f "$CURLDIR/tests/testcurl.pl") {
280     logit "$CURLDIR is verified to be a fine daily source dir"
281   } else {
282     mydie "$CURLDIR is not a daily source dir or checked out from CVS!"
283   }
284 }
285 $build="build-$$";
286 $buildlogname="buildlog-$$";
287 $buildlog="$pwd/$buildlogname";
288
289 # remove any previous left-overs
290 rmtree "build-*";
291 rmtree "buildlog-*";
292
293 # this is to remove old build logs that ended up in the wrong dir
294 foreach (glob("$CURLDIR/buildlog-*")) { unlink $_; }
295
296 # create a dir to build in
297 mkdir $build, 0777;
298
299 if (-d $build) {
300   logit "build dir $build was created fine";
301 } else {
302   mydie "failed to create dir $build";
303 }
304
305 # get in the curl source tree root
306 chdir $CURLDIR;
307
308 # Do the CVS thing, or not...
309 if ($CVS) {
310
311   # this is a temporary fix to make things work again, remove later
312   logit "remove ares/aclocal.m4";
313   unlink "ares/aclocal.m4";
314
315   logit "update from CVS";
316   my $cvsstat;
317
318   sub cvsup() {
319     # update quietly to the latest CVS
320     logit "run cvs up";
321     if($nocvsup) {
322         logit "Skipping CVS update (--nocvsup)";
323         return 1;
324     }
325     else {
326         system("cvs -Q up -dP 2>&1");
327     }
328
329     $cvsstat=$?;
330
331     # return !RETURNVALUE so that errors return 0 while goodness
332     # returns 1
333     return !$cvsstat;
334   }
335
336   my $att=0;
337   while (!cvsup()) {
338     $att++;
339     logit "failed CVS update attempt number $att.";
340     if ($att > 10) {
341       $cvsstat=111;
342       last; # get out of the loop
343     }
344     sleep 5;
345   }
346
347   if ($cvsstat != 0) {
348     mydie "failed to update from CVS ($cvsstat), exiting";
349   }
350
351   # remove possible left-overs from the past
352   unlink "configure";
353   unlink "autom4te.cache";
354
355   if ($configurebuild) {
356     # generate the build files
357     logit "invoke buildconf, but filter off the silly aclocal warnings";
358     open(F, "./buildconf 2>&1 |") or die;
359     open(LOG, ">$buildlog") or die;
360     while (<F>) {
361       next if /warning: underquoted definition of/;
362       print;
363       print LOG;
364     }
365     close(F);
366     close(LOG);
367
368     if (grepfile("^buildconf: OK", $buildlog)) {
369       logit "buildconf was successful";
370     }
371     else {
372       mydie "buildconf was NOT successful";
373     }
374
375     if($confopts =~ /--enable-ares/) {
376         logit "run buildconf for ares";
377         chdir "ares";
378         open(F, "./buildconf 2>&1 |") or die;
379         open(LOG, ">$buildlog") or die;
380         while (<F>) {
381             next if /warning: underquoted definition of/;
382             print;
383             print LOG;
384         }
385         close(F);
386         close(LOG);
387         chdir "..";
388     }
389
390   }
391   else {
392     logit "buildconf was successful (dummy message)";
393   }
394 }
395
396 if ($configurebuild) {
397   if (-f "configure") {
398     logit "configure created";
399   } else {
400     mydie "no configure created";
401   }
402 } else {
403   logit "configure created (dummy message)"; # dummy message to feign success
404 }
405
406 sub findinpath {
407     my $c;
408     my $e;
409     my $p=$ENV{'PATH'};
410     my @pa = split(":", $p);
411     for $c (@_) {
412         for $e (@pa) {
413             if( -x "$e/$c") {
414                 return $c;
415             }
416         }
417     }
418 }
419
420
421 my $make = findinpath("gmake", "make", "nmake");
422 if(!$make) {
423     mydie "Couldn't find make in the PATH";
424 }
425 logit "going with $make as make";
426
427 # change to build dir
428 chdir "$pwd/$build";
429
430 if ($configurebuild) {
431   # run configure script
432   print `../$CURLDIR/configure $confopts 2>&1`;
433
434   if (-f "lib/Makefile") {
435     logit "configure seems to have finished fine";
436   } else {
437     mydie "configure didn't work";
438   }
439 } else {
440   if (($^O eq 'MSWin32') && ($targetos !~ /netware/)) {
441     system("xcopy /s /q ..\\$CURLDIR .");
442     system("buildconf.bat");
443   }
444   elsif (($^O eq 'linux') || ($targetos =~ /netware/)) {
445     system("cp -afr ../$CURLDIR/* ."); 
446     system("cp -af ../$CURLDIR/Makefile.dist Makefile"); 
447     system("$make -i -C lib -f Makefile.$targetos prebuild");
448     system("$make -i -C src -f Makefile.$targetos prebuild");
449   }
450 }
451
452 logit "display lib/config$confsuffix.h";
453 open(F, "lib/config$confsuffix.h") or die "lib/config$confsuffix.h: $!";
454 while (<F>) {
455   print if /^ *#/;
456 }
457 close(F);
458
459 if (grepfile("define USE_ARES", "lib/config$confsuffix.h")) {
460   logit "setup to build ares";
461
462   logit "display ares/config$confsuffix.h";
463   if(open(F, "ares/config$confsuffix.h")) {
464       while (<F>) {
465           print if /^ *#/;
466       }
467       close(F);
468   }
469
470   logit "build ares";
471   chdir "ares";
472
473   if ($targetos && !$configurebuild) {
474       logit "$make -f Makefile.$targetos";
475       open(F, "$make -f Makefile.$targetos 2>&1 |") or die;
476   }
477   else {
478       logit "$make";
479       open(F, "$make 2>&1 |") or die;
480   }
481   while (<F>) {
482     s/$pwd//g;
483     print;
484   }
485   close(F);
486
487   if (-f "libcares$libext") {
488     logit "ares is now built successfully (libcares$libext)";
489   } else {
490     logit "ares build failed (libares$libext)";
491   }
492
493   # cd back to the curl build dir
494   chdir "$pwd/$build";
495 }
496
497 if ($configurebuild) {
498   logit "$make -i";
499   open(F, "$make -i 2>&1 |") or die;
500   while (<F>) {
501     s/$pwd//g;
502     print;
503   }
504   close(F);
505 }
506 else {
507   logit "$make -i $targetos";
508   if ($^O eq 'MSWin32') {
509     if ($targetos =~ /vc/) {
510       open(F, "nmake -i $targetos|") or die;
511     }
512     else {
513       open(F, "$make -i $targetos |") or die;
514     }
515   }
516   else {
517     open(F, "$make -i $targetos 2>&1 |") or die;
518   }
519   while (<F>) {
520     s/$pwd//g;
521     print;
522   }
523   close(F);
524 }
525
526 if (-f "lib/libcurl$libext") {
527   logit "lib/libcurl was created fine (libcurl$libext)";
528 }
529 else {
530   logit "lib/libcurl was not created (libcurl$libext)";
531 }
532
533 if (-f "src/curl$binext") {
534   logit "src/curl was created fine (curl$binext)";
535 }
536 else {
537   mydie "src/curl was not created (curl$binext)";
538 }
539
540 if ($targetos =~ /netware/) {
541   if (-f '../../curlver') {
542     system('../../curlver');
543   }
544 }
545 elsif(!$crosscompile) {
546   logit "display curl$binext --version output";
547   open(F, "./src/curl$binext --version|");
548   while(<F>) {
549       print;
550       print LOG;
551   }
552   close(F);
553 }
554
555 if ($configurebuild && !$crosscompile) {
556   my $o;
557   if($runtestopts) {
558       $o = "TEST_F=\"$runtestopts\" ";
559   }
560   logit "$make ${o}test-full";
561   open(F, "$make ${o}test-full 2>&1 |") or die;
562   open(LOG, ">$buildlog") or die;
563   while (<F>) {
564     s/$pwd//g;
565     print;
566     print LOG;
567   }
568   close(F);
569   close(LOG);
570
571   if (grepfile("^TEST", $buildlog)) {
572     logit "tests were run";
573   } else {
574     mydie "test suite failure";
575   }
576
577   if (grepfile("^TESTFAIL:", $buildlog)) {
578     logit "the tests were not successful";
579   } else {
580     logit "the tests were successful!";
581   }
582 } else {
583   # dummy message to feign success
584   if($crosscompile) {
585     logit "cross-compiling, can't run tests";
586   }
587   print "TESTDONE: 1 tests out of 0 (dummy message)\n";
588 }
589
590 # create a tarball if we got that option.
591 if (($mktarball ne '') && (-f $mktarball)) {
592   system($mktarball);
593 }
594
595 # mydie to cleanup
596 mydie "ending nicely";