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