diff options
Diffstat (limited to 'ACE/bin/auto_compile')
-rwxr-xr-x | ACE/bin/auto_compile | 607 |
1 files changed, 607 insertions, 0 deletions
diff --git a/ACE/bin/auto_compile b/ACE/bin/auto_compile new file mode 100755 index 00000000000..914bcabaa18 --- /dev/null +++ b/ACE/bin/auto_compile @@ -0,0 +1,607 @@ +eval '(exit $?0)' && eval 'exec perl -S $0 ${1+"$@"}' + & eval 'exec perl -S $0 $argv:q' + if 0; + +# -*- perl -*- +# $Id$ +# +# This script checkouts ACE from CVS, updates the "clone" directory, +# compiles $ACE_ROOT/ace and $ACE_ROOT/tests and finally runs +# $ACE_ROOT/tests/run_tests.sh. +# +# If it detects any problem it send email. +# +# DO NOT invoke this script from your crontab, use +# auto_compile_wrapper for that. +# +# This script requires Perl5. +# +# TODO: Modify the script or split it in such a way that the main copy +# can be obtained either using cvs or downloading the lastest beta +# from the WWW. +# + +# The first three lines above let this script run without specifying the +# full path to perl, as long as it is in the user's PATH. +# Taken from perlrun man page. + +use File::Basename; +use File::Copy; +use FileHandle; +require POSIX; + +# This are the sub-directories (in the module) we really compile. + +# Find out the command name. +$CMD = basename($0); + +$dont_update = 0; +# $copy_logs = 1; +# $LOG_DESTINATION = $ENV{'HOME'}.'/.www-docs/auto_compile'; + +$copy_logs = 0; +$LOG_DESTINATION='bugzilla'.'@cs.wustl.edu'; + +$dont_build_tao = 0; +$dont_run = 0; +$makefile_suffix = ""; +$pre_realclean = 0; +$post_realclean = 0; +$report_success = 0; +$debug = 0; +$sandbox = ''; +$sandbox_timeout = 600; +$sendreport = 0; +@BUILD_LIST= (); +@CONFIGURATION_OPTIONS = (); + +@ARGS = (); +while ($#ARGV >= 0) { + if (!($ARGV[0] =~ m/^-/)) { + push @ARGS, $ARGV[0]; + } elsif ($ARGV[0] eq "-single_threaded") { + print STDERR "$CMD: obsolete option $ARGV[0], " + ."please use -config instead\n"; + push @CONFIGURATION_OPTIONS, 'ST'; + } elsif ($ARGV[0] eq "-minimum_corba") { + print STDERR "$CMD: obsolete option $ARGV[0], " + ."please use -config instead\n"; + push @CONFIGURATION_OPTIONS, 'MINIMUM'; + } elsif ($ARGV[0] eq "-ami") { + print STDERR "$CMD: obsolete option $ARGV[0], " + ."please use -config instead\n"; + push @CONFIGURATION_OPTIONS, 'AMI'; + } elsif ($ARGV[0] eq "-smart_proxies") { + print STDERR "$CMD: obsolete option $ARGV[0], " + ."please use -config instead\n"; + push @CONFIGURATION_OPTIONS, 'SMART_PROXIES'; + } elsif ($ARGV[0] eq "-static") { + print STDERR "$CMD: obsolete option $ARGV[0], " + ."please use -config instead\n"; + push @CONFIGURATION_OPTIONS, 'STATIC'; + } elsif ($ARGV[0] eq "-config") { + shift; + push @CONFIGURATION_OPTIONS, $ARGV[0]; + } elsif ($ARGV[0] eq "-build_list") { + shift; + @BUILD_LIST = split (/,/, $ARGV[0]); + } elsif ($ARGV[0] eq "-dont_update") { + $dont_update = 1; + } elsif ($ARGV[0] eq "-copy_logs") { + shift; + $copy_logs = 1; + $LOG_DESTINATION = $ARGV[0]; + } elsif ($ARGV[0] eq "-sandbox") { + shift; + $sandbox = $ARGV[0]; + } elsif ($ARGV[0] eq "-sandbox_timeout") { + shift; + $sandbox_timeout = $ARGV[0]; + } elsif ($ARGV[0] eq "-dont_run") { + $dont_run = 1; + } elsif ($ARGV[0] eq "-pre_realclean") { + $pre_realclean = 1; + } elsif ($ARGV[0] eq "-post_realclean") { + $post_realclean = 1; + } elsif ($ARGV[0] eq "-report_success") { + $report_success = 1; + } elsif ($ARGV[0] eq "-debug") { + $debug = 1; + } elsif ($ARGV[0] eq "-sendreport") { + $sendreport = 1; + } elsif ($ARGV[0] eq "-notao") { + $dont_build_tao = 1; + } elsif ($ARGV[0] eq "-make_type") { + shift; + $makefile_suffix = $ARGV[0]; + } else { + print "Ignoring option $ARGV[0]\n"; + } + shift; +} + +# Extract configuration information from command line. + # TODO: Some validation and checking should be done here. +$CHECKOUT = $ARGS[0]; +$BUILD = $ARGS[1]; +$LOGDIR = $ARGS[2]; +$ADMIN = $ARGS[3]; +$MAIL = "mail"; +if ($#ARGS >= 4) { + $MAIL = $ARGS[4]; +} +$LOG_URL = "http://ace.cs.wustl.edu/~bugzilla/auto_compile_logs/"; +if ($#ARGS >= 5) { + $LOG_URL = $ARGS[5]; +} +# This is the module we will checkout unless a different one is on the +# command line. +$MODULE='ACE_wrappers'; +if ($#ARGS >= 6) { + $MODULE = $ARGS[6]; +} + +$ENV{'ACE_ROOT'} = $CHECKOUT . '/' . $MODULE . '/build/' . $BUILD; +$ENV{'TAO_ROOT'} = $CHECKOUT . '/' . $MODULE . '/build/' . $BUILD . '/TAO'; + +# We obtain our revision to report errors. +$REVISION='$Revision$ '; + +# When an error is found we try to die gracefully and send some email +# to ADMIN. + +$disable_file = $LOGDIR . '/.disable'; +$histfile = $LOGDIR . '/history'; +$LOGBASE = POSIX::strftime("%Y_%m_%d_%H_%M", localtime); +$LOGFILE = $LOGDIR . '/' . $LOGBASE . '.txt'; +$HOST = `hostname`; +chop $HOST; +$LOG_NAME = $HOST . '_' . $BUILD . '/' . $LOGBASE . '.txt'; +$STATUS = "OK"; + +if ($debug) { + print "CHECKOUT = $CHECKOUT\n"; + print "BUILD = $BUILD\n"; + print "LOGDIR = $LOGDIR\n"; + print "ADMIN = $ADMIN\n"; + print "MAIL = $MAIL\n"; + print "ACE_ROOT = $ENV{ACE_ROOT}\n"; + print "TAO_ROOT = $ENV{TAO_ROOT}\n"; + print "CONFIGURATION_OPTIONS = ", @CONFIGURATION_OPTIONS, "\n"; +} + +push @INC, $CHECKOUT . '/' . $MODULE . '/bin'; + +require PerlACE::ConfigList; + +$config_list = new PerlACE::ConfigList; + +$config_list->my_config_list (@CONFIGURATION_OPTIONS); + +if ($#BUILD_LIST == -1) { + if ($dont_build_tao) { + @BUILD_LIST=('ace', 'netsvcs', 'tests'); + } + else { + @BUILD_LIST=('.', 'TAO'); + } +} + +sub mydie { + my $DEST_DIR = $LOG_DESTINATION.'/'.$HOST.'_'.$BUILD; + mkdir $DEST_DIR,0755 if (!-d $DEST_DIR); + if (open(STATUS, '>'.$DEST_DIR.'/status.txt')) { + print STATUS "SCOREBOARD_STATUS: Inactive\n"; + close STATUS; + } + unlink $disable_file; + die $_ . "\n"; +} + +@RUN_LIST = (); + +if ($debug) { + + @BUILD_LIST = ('ace'); + @RUN_LIST = ('TAO/tests/OctetSeq/run_test.pl'); + $ADMIN = $ENV{'LOGNAME'}; + +} else { + $config_list->load ($CHECKOUT . '/' . $MODULE . '/' . 'build/' . $BUILD . '/bin/auto_run_tests.lst'); + + @RUN_LIST = $config_list->valid_entries (); +} + +sub mail_logs { + open (MAIL, "|".$MAIL.' -s AUTO_COMPILE_LOG='.$LOG_NAME.' '.$LOG_DESTINATION) + || mydie "Cannot open mail pipe for: $LOG_NAME\n"; + + print MAIL 'This is the log for: ', "\n"; + print MAIL $CMD, ' [', $REVISION, "] for $HOST/$BUILD\n"; + + print MAIL "\n================================================================\n"; + + if (open (THELOG, "$LOGFILE")) + { + while (<THELOG>) { + print MAIL $_; + } + close (THELOG); + } + close (MAIL); # Ignore errors.... +} + +sub copy_logs { + local $DEST_DIR = $LOG_DESTINATION.'/'.$HOST.'_'.$BUILD; + mkdir $DEST_DIR,0755 if (!-d $DEST_DIR); + + copy($LOGFILE, $DEST_DIR.'/'.$LOGBASE.'.txt'); + + local $MAKE_PRETTY="$CHECKOUT/$MODULE/bin/make_pretty.pl"; + system ("perl $MAKE_PRETTY -b -i $LOGFILE >$DEST_DIR/$LOGBASE"."_brief.html"); + system ("perl $MAKE_PRETTY -i $LOGFILE >$DEST_DIR/$LOGBASE".".html"); + + chmod 0644, $DEST_DIR.'/'.$LOGBASE.'.txt' + , $DEST_DIR.'/'.$LOGBASE.'_brief.html' + , $DEST_DIR.'/'.$LOGBASE.'.html' ; +} + +sub report_errors { + + # First clear the lock, so the next execution works... + unlink $disable_file; # Ignore errors! + + if ($sendreport) { + # Now send a summary of the errors to the ADMIN account, if there are any. + + if ($#_ >= 0) { + local $to = $ADMIN; + + open (MAIL, "|".$MAIL.' -s "[AUTO_COMPILE] '.$HOST.' '.$BUILD.'" '.$to) + || mydie "Cannot open mail pipe for: $_\n"; + + print MAIL 'The following message is brought to you by: ', "\n"; + print MAIL $CMD, ' [', $REVISION, "] for $BUILD on $HOST\n\n"; + + print MAIL "\nPlease check the following log for more info:\n\n"; + print MAIL $LOG_URL, '?', $HOST, '_', $BUILD, "\n\n"; + + local $m; + foreach $m (@_) { + print MAIL $m, "\n"; + } + close (MAIL); # Ignore errors.... + } + } + + # Now send the complete log to bugzilla... + if ($copy_logs) { + copy_logs (); + } else { + mail_logs (); + } +} + +### MAIN FUNCTION + +if (-f $disable_file) { + print 'The following message is brought to you by: ', "\n"; + print $CMD, ' [', $REVISION, "] for $BUILD on $CHECKOUT\n"; + + print "DISABLED\n"; + + exit 0; +} + +open (DISABLE, '>' . $disable_file) + || die "cannot open disable file <$disable_file>\n"; +print DISABLE "auto_compile <$date> is running\n"; +close (DISABLE) + || die "cannot close disable file"; + +open(HIST, '>>' . $histfile) + # Do not use 'mydie' to report the problem, it tries to remove the + # disable file + || mydie "cannot open history file \"$histfile\"\n"; + +$date = localtime; + +print HIST $CMD, ': running at ', $date, ' '; + +open(LOG, '>' . $LOGFILE) + || mydie "cannot open log file"; + +LOG->autoflush (); + +# The following lines are useful when debugging the script or wrapper. +# print LOG $CHECKOUT, " ", $BUILD, " ", $LOGDIR, " ", $ADMIN, "\n"; +#while (($key,$value) = each %ENV) { +# print LOG $key, " = ", $value, "\n"; +#} + +print LOG "#################### CVS\n"; +my $DEST_DIR = $LOG_DESTINATION.'/'.$HOST.'_'.$BUILD; +mkdir $DEST_DIR,0755 if !-d $DEST_DIR; +if (open(STATUS, '>'.$DEST_DIR.'/status.txt')) { + print STATUS "SCOREBOARD_STATUS: CVS\n"; + close STATUS; +} + +chdir($CHECKOUT) + || mydie "Cannot chdir to $CHECKOUT"; + +if ($dont_update == 0) { + $date = localtime; + print LOG "$CMD: starting checkout at ", $date, "\n"; + open(CVS, "cvs -q checkout -P $MODULE 2>&1 |") + || mydie "cannot start checkout of $MODULE"; + + $conflicts = 0; + while (<CVS>) { + if (m/^C /) { + ($unused, $entry) = split('/'); + if (($entry ne "ChangeLog\n") && ($entry ne "THANKS\n")) { + $conflicts = 1; + } + } + print LOG $_; + } + close(CVS); +# || mydie "error while checking out $MODULE"; + $date = localtime; + print LOG "$CMD: checkout finished at ", $date, "\n"; + + if ($conflicts != 0) { + mydie "conflicts on checkout"; + } +} + +chdir($MODULE) + || mydie "cannot chdir to $MODULE"; + +$date = localtime; +print LOG "$CMD: starting clone at ", $date, "\n"; +open(CLONE, "perl bin/create_ace_build -a -v $BUILD 2>&1 |") + || mydie "cannot clone directory"; +while(<CLONE>) { + print LOG $_; +} +close(CLONE) + || mydie "error while cloning ACE_ROOT"; +$date = localtime; +print LOG "$CMD: clone finished at ", $date, "\n"; + +chdir('build/' . $BUILD) + || mydie "cannot chdir to $BUILD"; + +@failures = (); + +if ($makefile_suffix ne "") { + $MAKEFLAGS = "-f Makefile.$makefile_suffix"; +} + +print LOG "#################### Compiler\n"; +if (open(STATUS, '>'.$DEST_DIR.'/status.txt')) { + print STATUS "SCOREBOARD_STATUS: Compile\n"; + close STATUS; +} + +if ($pre_realclean) { + foreach $i (reverse(@BUILD_LIST)) { + $date = localtime; + print LOG "$CMD: =============================================\n"; + print LOG "$CMD: make realclean in $i started at ", $date, "\n"; + open(MAKE, "make -k $MAKEFLAGS -C $i realclean 2>&1 |") + || mydie "cannot start make in $i"; + + while (<MAKE>) { + # Ignore errors.... + } + if (close(MAKE) == 0) { + push @failures, "errors while cleaning $i"; + } + $date = localtime; + print LOG "$CMD: make realclean in $i finished at ", $date, "\n"; + print LOG "$CMD: =============================================\n\n"; + } +} + +$MAKEFLAGS .= ""; +foreach $i (@BUILD_LIST) { + $date = localtime; + print LOG "$CMD: =============================================\n"; + print LOG "$CMD: make for $i started at ", $date, "\n"; + open(MAKE, "make -k $MAKEFLAGS -C $i 2>&1 |") + || mydie "cannot start make for $i"; + + local $current_dir = $i; + local $last_error = ""; + local $this_error = 0; + local $this_warning = 0; + while (<MAKE>) { + chop; + $this_error = $this_warning = 0; + if ($^O eq 'hpux' + && m/^Warning:[ \t]+[0-9]+ future errors were detected/) { + next; + } + print LOG $_, "\n"; + + if (m/^make(\[[0-9]+\])?: Entering directory /) { + s/^make(\[[0-9]+\])?: Entering directory //; + s%^$ENV{'ACE_ROOT'}/%%; + $current_dir = $_; + } + if (m/error:/i || m/error /i + || m/^make(\[[0-9]+\])?: \*\*\*/) { + $this_error = 1; + } + if ($^O eq 'aix' + && m/\d+-\d+ \([SI]\)/) { + $this_error = 1; + } + if ($this_error) { + if ($last_error ne $current_dir + || STATUS eq "COMPILATION WARNING") { + $STATUS = "COMPILATION ERROR"; + push @failures, "Error while compiling in $current_dir \n"; + $last_error = $current_dir; + } + } + if (m/warning:/i + || m/warning /i + || m/Info: /i) { + $this_warning = 1; + if ($^O eq 'aix' + && m/^ld: \d+-\d+ WARNING: Duplicate symbol: .*ACE.*/) { + $this_warning = 0; + } + } + if ($^O eq 'aix' + && m/\d+-\d+ \(W\)/) { + $this_warning = 1; + } + if ($this_warning) { + if ($last_error ne $current_dir) { + if ($STATUS eq "OK") { + $STATUS = "COMPILATION WARNING"; + } + push @failures, "Warning while compiling in $current_dir\n"; + $last_error = $current_dir; + } + } + } + if (close(MAKE) == 0) { + push @failures, "errors while running make in $i"; + } + $date = localtime; + print LOG "$CMD: make for $i finished at ", $date, "\n"; + print LOG "$CMD: =============================================\n\n"; +} + +print LOG "#################### Tests\n"; +if (open(STATUS, '>'.$DEST_DIR.'/status.txt')) { + print STATUS "SCOREBOARD_STATUS: Tests\n"; + close STATUS; +} + +if ($dont_run == 0) { + my $config_params; + if ($#CONFIGURATION_OPTIONS != -1) { + $config_params = ' -Config '; + } + $config_params .= join ' -Config ', @CONFIGURATION_OPTIONS; + + foreach my $i (@RUN_LIST) { + + local $directory = '.'; + local $program = $i; + + if ($i =~ /(.*)\/([^\/]*)$/) { + $directory = $1; + $program = $2; + } + + $date = localtime; + print LOG "\n\n$CMD: ================ $date ================\n"; + print LOG "auto_run_tests: $i\n"; + local $subdir = + $CHECKOUT .'/'. $MODULE .'/build/'. $BUILD .'/'. $directory; + chdir ($subdir) + || mydie "cannot chdir to $subdir"; + + $run_error = 0; + my $prefix = ''; + if ($sandbox ne "") { + $prefix = $sandbox.' '.$sandbox_timeout.' '; + } + if (open(RUN, $prefix."perl $program $config_params 2>&1 |") == 0) { + push @failures, "cannot run $program in $directory"; + next; + } + while (<RUN>) { + print LOG $_; + if (m/Error/ + || m/ERROR/ + || m/FAILED/ + || m/EXCEPTION/ + || m/pure virtual /i) { + if ($STATUS eq "OK") { + $STATUS = "RUNTIME ERROR"; + } + $run_error = 1; + } + } + if (close(RUN) == 0) { + if ($STATUS eq "OK") { + $STATUS = "RUNTIME ERROR"; + } + print LOG "ERROR, non-zero status returned by test script\n"; + push @failures, "Error when closing pipe for $program in $directory"; + next; + } + $date = localtime; + print LOG "$CMD: $program finished ", $date, "\n"; + + if ($run_error != 0) { + push @failures, + "errors detected while running $program in $directory"; + } + } +} + +if ($post_realclean) { + foreach $i (reverse(@BUILD_LIST)) { + $date = localtime; + print LOG "$CMD: =============================================\n"; + print LOG "$CMD: make realclean in $i started at ", $date, "\n"; + open(MAKE, "make -k $MAKEFLAGS -C $i realclean 2>&1 |"); + + while (<MAKE>) { + # Ignore errors.... + } + if (close(MAKE) == 0) { + push @failures, "errors while cleaning $i"; + } + $date = localtime; + print LOG "$CMD: make realclean in $i finished at ", $date, "\n"; + print LOG "$CMD: =============================================\n\n"; + } +} + +print LOG "#################### Config\n"; + +chdir($CHECKOUT . "/" . $MODULE . "/build/" . $BUILD) + || mydie "Cannot chdir to $CHECKOUT/$MODULE/build/$BUILD"; + +open (CONFIG, "perl bin/nightlybuilds/print_config.pl $CHECKOUT/$MODULE/build/$BUILD 2>&1 |") + || mydie "Cannot run print_config.pl script"; +while (<CONFIG>) { + print LOG $_; +} +close (CONFIG) + || mydie "Error while running print_config.pl script"; + +report_errors @failures; + +print LOG "#################### End\n"; +if (open(STATUS, '>'.$DEST_DIR.'/status.txt')) { + print STATUS "SCOREBOARD_STATUS: Inactive\n"; + close STATUS; +} + +close(LOG) + || mydie "cannot close LOGFILE"; + +print HIST "$STATUS\n"; +close(HIST) + || mydie "cannot close history file"; + +unlink $disable_file + || die "cannot unlink disable file"; + +if ($report_success && $STATUS eq "OK") { + report_errors "Congratulations: No errors or warnings detected\n"; +} + +exit 0; |