#!/bin/bash # # Test building the BOINC libraries, server software, and test apps # # This script will automatically retrieve and build the BOINC # software, either from the master branch (the default) or from # a given git branch or tag. (Use the command `git remote show origin` # to get a list of available branches.) # # Syntax: boinc_test_build [ -r git_branch ] # [ --clean | -C ] # [ --veryclean ] # [ --version | -V ] # [ --help ] # # Uses $TMPDIR (if set, otherwise /tmp) and creates under that the # working directory boinc_test, and then under that 'boinc' for the build, # 'install' for installation, and 'apps' for additional apps (hello & # yello, etc) # # Requires bash's function definition facility, so this won't work on # some older versions of the Bourne shell. # # Modified to use git in place of SVN or CVS for the BOINC source code. # The apps from Spy Hill are retrieved via CVS. # # Eric Myers - 2 November 2006 # @(#) $Id: boinc_test_build,v 1.79 2014/11/05 17:09:24 myers Exp $ # ###################################################################### #BOINC_SVN="http://boinc.berkeley.edu/svn" #BOINC_SVN_TRUNK="${BOINC_SVN}/trunk/boinc" SPYHILL_CVS=":pserver:anonymous@www.spy-hill.net:/usr/local/cvsroot/boinc" #BOINC_GIT="git://boinc.berkeley.edu/boinc-v2.git boinc" BOINC_GIT="https://github.com/BOINC/boinc boinc" # Do all the work under TMPDIR, or /tmp if that is not set export TMPDIR=${TMPDIR-"/tmp"} # If run from cron the PATH won't be set, so add directories here for # wx-config, curl, etc.. # And for loading dynamic graphics thread we need . in the library path # export PATH="/usr/local/bin:/sw/bin:/usr/bin:/bin" export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ## # Setup: # WORKDIR=$TMPDIR/boinc_test INSTALL=$WORKDIR/install APPS_TOP=$WORKDIR/apps SYS_RELEASE="" APPLE="" NTEST=0 NFAIL=0 INDENT="pr -o 4 -t " TEST_STARTED=`date` HOSTNAME=`hostname -s ` ## # Parse command line: # REVTAG="" SVN_REV="" CLEAN="" while [ $# != 0 ] do case "$1" in -r) shift; REVTAG="$1" SVN_REV=" -r $REVTAG " ;; --clean|-C) CLEAN="clean" ;; --veryclean) CLEAN="very" ;; --version|-V) VER=`echo "$Revision: 1.79 $ " | awk '{ print $2}' ` DATE=`echo "$Date: 2014/11/05 17:09:24 $ " | awk ' {$1=""; $NF=""; print'} ` echo "This is `basename $0` version $VER of $DATE" exit 0 ;; --help|-h) echo "Usage: $0 [ --clean ] [ --veryclean ] [ -r SVN_revision ]" echo " --clean does \`make clean\` first " echo " --veryclean removes any existing working directory first " exit 0 ;; -*) FLAGS="$FLAGS $1" ;; # other flags (unused) *) FILES="$FILES $1" ;; # files (unused) esac shift done if [ "${REVTAG}" != "" ]; then FAIL_LOG=${REVTAG}_fail.log else FAIL_LOG="boinc_fail.log" fi ############## # Functions: test_rc() { # test $? from last command and print test name and result RC=$? TEST_NAME=$1 NTEST=$(($NTEST+1)) echo -n "* Test ${NTEST}: ${TEST_NAME}: " if [ $RC -ne 0 ]; then echo "THIS TEST FAILED. (rc=$RC) " NFAIL=$(($NFAIL+1)) else echo " succeeded. " fi return $RC } fail_test(){ NTEST=$(($NTEST+1)) NFAIL=$(($NFAIL+1)) } pass_test(){ NTEST=$(($NTEST+1)) } try_git(){ D=`basename $PWD` echo "$D% git $*" git $* test_rc "GIT [$D]" return $? } try_cvs() { D=`basename $PWD` echo "$D% cvs $*" cvs -Q $* test_rc "CVS [$D]" return $? } try_svn() { D=`basename $PWD` echo "$D% svn $*" svn $* test_rc "SVN [$D]" return $? } show_test_conditions(){ echo "System (uname): `uname -a` " echo "Release: $SYS_RELEASE" if [ "$REVTAG" != "" ]; then echo "SVN Tag: $REVTAG " fi echo "wxWidgets version: $WX_VERS" echo "Test start: $TEST_STARTED " } # Clean up at the end: # clean_up(){ cd $WORKDIR/boinc make -s clean > /dev/null if [ "$CLEAN" = "clean" ]; then cd ${WORKDIR}/boinc make distclean > /dev/null cd ${WORKDIR} /bin/rm -rf install fi if [ "$CLEAN" = "very" ]; then cd ${TMPDIR} /bin/rm -rf $WORKDIR fi } # Overall summary # summary(){ echo " " echo "== Summary == " echo " " show_test_conditions echo "Test end: `date` " echo " " echo "Total tests: $NTEST" echo "Tests failed: $NFAIL" echo " " if [ $NFAIL -eq 0 ]; then echo "It would appear that this version PASSES all tests." fi exit $NFAIL } ################################################### # BEGIN: echo " " echo "== BOINC Regression testing ==" echo " " # What flavor of Unix? if [ -f /etc/fedora-release ]; then SYS_RELEASE=`cat /etc/fedora-release` elif [ -f /etc/redhat-release ]; then SYS_RELEASE=`cat /etc/redhat-release` elif [ -f /etc/lsb-release ]; then SYS_RELEASE=`grep DISTRIB_DESCRIPTION lsb-release |\ sed -e 's/DISTRIB_DESCRIPTION="\(.*\)"/\1/' ` elif [ -f /etc/yellowdog-release ]; then SYS_RELEASE=`cat /etc/yellowdog-release` elif [ -f /etc/gentoo-release ]; then SYS_RELEASE=`cat /etc/gentoo-release` elif [ -f /etc/debian_version ]; then SYS_RELEASE=`echo "Debian" ; cat /etc/debian_version` elif [ -f /etc/release ]; then SYS_RELEASE=`grep Solaris /etc/release` #TODO: other Linux distros here...? elif [ `uname -s` = "Darwin" ]; then APPLE="Y" SYS_RELEASE="MacOS X (Darwin `uname -r`)" fi # wxWidgets is used to build the just the BOINC Manager WXCONFIG=`which wx-config ` if [ -f "$WXCONFIG" -a -x "$WXCONFIG" ]; then WX_VERS=`$WXCONFIG --version` WX_UNICODE=`$WXCONFIG --unicode 2>/dev/null ` else WX_VERS=" (none) " WX_UNICODE="" fi show_test_conditions ### # BEGIN: echo " " echo "=== Obtain and Build BOINC ===" echo " " if [ "$CLEAN" = "very" ]; then echo "* Selected --veryclean, removing $WORKDIR first..." /bin/rm -rf $WORKDIR fi if [ -d $WORKDIR ]; then if [ "$CLEAN" = "clean" ]; then cd $WORKDIR/boinc make distclean fi else mkdir $WORKDIR fi if [ ! -d $INSTALL ]; then mkdir $INSTALL fi if [ ! -d $APPS_TOP ]; then mkdir $APPS_TOP fi cd $WORKDIR echo "Working directory: $PWD" echo " " echo "==== Obtain BOINC via git ====" echo " " # First, clone or update repo if [ ! -d boinc -o ! -d boinc/.git ]; then /bin/rm -rf boinc try_git clone $BOINC_GIT else cd boinc try_git pull cd .. fi # If a branch or tag is requested via -r then check that out # (No fancy parsing of branch names, so you must specify full name.) if [ "$REVTAG" != "" ]; then echo "* Selected git branch: $REVTAG" cd boinc try_git checkout $REVTAG cd .. fi echo " " echo "==== Set-up configuration ====" echo " " cd $WORKDIR/boinc export BOINC_BUILD=$PWD /bin/rm -f version.h Makefile set pipefail ./_autosetup >> boinc_configure.log test_rc "_autosetup" SETUP_RC=$? # Regression for AC_PROG_OBJCXX: first just try again if [ $SETUP_RC -ne 0 ];then grep -q "possibly undefined macro: AC_PROG_OBJCXX" boinc_configure.log if [ $? -ne 0 ]; then set pipefail ./_autosetup >> boinc_configure.log test_rc "_autosetup again after AC_PROG_OBJCXX" SETUP_RC=$? fi fi # If we can't setup then we can't go on [ $SETUP_RC -ne 0 ] && summary ## # Function to configure and build BOINC distro configure_and_build(){ CMD=$* echo "$CMD" set pipefail $CMD 2>&1 | tee -a boinc_configure.log test_rc "./configure for `uname -s` " echo "* The real test of configure is whether it created the Makefile." [ -s Makefile -a -s version.h ] test_rc "./configure for `uname -s` created Makefile and version.h" #TODO: this is now redundant if [ $? -ne 0 ]; then echo " " echo "* The problems might go away if we disable client ..." CMD="$CMD --disable-client --disable-server --disable-manager " echo "* Try again with --disable-client " >> boinc_configure.log ./_autosetup > /dev/null echo "$CMD" $CMD 2>&1 | tee -a boinc_configure.log test_rc "./configure with --disable-client etc..." [ -s Makefile -a -s version.h ] test_rc "Makefile and version.h created with client/server disabled" fi echo " " echo "* Build: " echo " " /bin/rm -f ${FAIL_LOG} CMD="make" echo "$CMD" $CMD test_rc "$CMD" MAKE_RC=$? if [ $MAKE_RC -ne 0 ]; then echo "* Now run 'make -k' to build everything that builds... " make -k >/dev/null echo "* Then run 'make -k' again to log the errors... " make -k >> ${FAIL_LOG} fi } ## # Build just the libraries: echo " " echo "==== Configure for base build ==== " echo " " CMD="./configure --prefix=$INSTALL --disable-server --disable-client --disable-manager " # Apple: OpenGL Framework and Fink # if [ "$APPLE" != "" ]; then CMD=" $CMD --with-apple-opengl-framework" if [ -d /sw ]; then $CMD=" $CMD CPPFLAGS=-I/sw/include LDFLAGS=-L/sw/lib " fi fi configure_and_build $CMD ## # Build the project server (on Linux, not Mac), no client if [ "$APPLE" == "" ]; then echo " " echo "=== Configure to build project server === " echo " " CMD="./configure --prefix=$INSTALL --disable-client --disable-manager" CMD="$CMD --disable-fcgi --enable-server " configure_and_build $CMD echo " " echo "Install: " echo " " CMD="make install" echo "$CMD" $CMD test_rc "$CMD" INSTALL_RC=$? fi ## # Build the client on Linux, but not Mac if [ "$APPLE" == "" ]; then echo " " echo "=== Configure to build client: === " echo " " CMD="./configure --prefix=$INSTALL --enable-client --disable-server " CMD="$CMD --enable-client-release --enable-manager " configure_and_build $CMD fi ## # Build self-extracting archive (sea), if present if [ -d sea ]; then echo " " echo "=== Linux Self-Extracting Archive ===" echo " " cd $WORKDIR/boinc/sea make -s -k > /dev/null test_rc "Build Self-Extracting Archive (sea) for Linux " # Save a copy of anything we built # /bin/cp -fp boinc_*.sh /tmp # Only publish the result if everything so far has worked: # if [ $NFAIL -eq 0 -a -d /usr02/pirates/download/alpha ]; then /bin/cp -fp boinc_*.sh /usr02/pirates/download/alpha test_rc "Copy client packages to download/alpha " fi fi ################################################### # Application tests: echo " " echo "=== Apps I: Test Example Applications ===" echo " " cd $WORKDIR if [ ! -d boinc/apps ]; then echo "No boinc/apps directory" fail_test else cd boinc/apps make test_rc "build sample apps" # Concat will concatenate a list of files into the last one # [ -x concat ] test_rc "concat executable" if [ $? -eq 0 ]; then echo -n "Hello, " > fileA echo -n "World! " > fileB ./concat fileA fileB out test_rc "concat execution" grep -q "Hello, World!" out test_rc "concat output" fi # upper_case will convert a file to upper case # [ -x upper_case ] test_rc "upper_case executable" if [ $? -eq 0 ]; then echo "All your base are belong to us" > in ./upper_case test_rc "upper_case execution" grep -q "ALL YOUR BASE ARE BELONG TO US" out test_rc "upper_case output" fi fi echo " " echo "=== Apps II: Obtain and Build Further Applications ===" echo " " cd $WORKDIR if [ ! -d $APPS_TOP ]; then mkdir $APPS_TOP fi # Get common compute thread code for later examples... # cd $APPS_TOP if [ ! -d buffon -o ! -f buffon/CVS/Root ]; then /bin/rm -rf buffon try_cvs -d $SPYHILL_CVS checkout src/apps/buffon if [ -d src/apps/buffon ]; then mv src/apps/buffon $APPS_TOP else echo "FAIL: could not check buffon code out from CVS" fi else cd buffon try_cvs update -C -d cd .. fi # example apps directory if [ ! -f $APPS_TOP/graphics_app.C ]; then try_cvs -d $SPYHILL_CVS checkout src/apps/graphics/graphics_app.C mv src/apps/graphics_app.C $APPS_TOP fi ## # Function to test any of the spy-hill apps test_example_app(){ APP_NAME=$1 APP_DIR=${APP_NAME}.d echo " " echo "==== '${APP_NAME}' application ====" echo " " # Get app code from CVS cd ${APPS_TOP} if [ ! -d ${APP_DIR} -o ! -f ${APP_DIR}/CVS/Root ]; then /bin/rm -rf ${APP_DIR} try_cvs -d $SPYHILL_CVS checkout src/apps/${APP_DIR} if [ -d src/apps/${APP_DIR} ]; then mv src/apps/${APP_DIR} ${APPS_TOP} else echo "FAIL: could not check '${APP_NAME}' out from CVS" fi else cd ${APP_DIR} try_cvs update -C -d make distclean cd .. fi # Build and test the app # if [ -d ${APP_DIR} ]; then cd ${APP_DIR} MAKE_ARGS="BOINC_PREFIX=$INSTALL BOINC_BUILD=$WORKDIR/boinc" # On a Mac, use Makefile.Mac if there is one if [ "$APPLE" != "" -a -f Makefile.Mac ]; then /bin/cp -f Makefile.Mac Makefile fi ### ##cp Makefile Makefile.ORIG ##sed -e "s@^BOINC_BUILD=.*@BOINC_BUILD=$BOINC_BUILD@" \ ## Makefile.ORIG > Makefile ##echo -n "* Modified Makefile to build with " ##grep BOINC_BUILD= Makefile if [ "$APPLE" != "" ]; then ##cp Makefile Makefile.BAK ##sed -e "s@^BUILD_ARCH=.*@BUILD_ARCH=powerpc-apple-darwin@" \ ## -e "s@^LDFLAGS=.*@LDFLAGS=@" \ ## Makefile.BAK > Makefile BUILD_ARGS="$BUILD_ARGS BUILD_ARCH=powerpc-apple-darwin LDFLAGS= " fi echo make ${MAKE_ARGS} ${APP_NAME} make ${MAKE_ARGS} ${APP_NAME} test_rc "make ${APP_NAME}" # Run app standalone # [ -x ${APP_NAME} ] test_rc "${APP_NAME} executable" if [ $? -eq 0 ]; then APP_ARGS=" -N 2e6 " cat /dev/null > out.txt rm -f stderr.txt echo "* Running application ${APP_NAME} in standalone mode. " CMD="./${APP_NAME} ${APP_ARGS}" APP_GFX=${APP_NAME}_graphics if [ -x ${APP_GFX} ]; then CMD="./${APP_GFX} & $CMD ; kill \$\! " echo " (Also running graphics in the background. A window should pop up.) " fi echo "$CMD" $CMD test_rc "${APP_NAME} execution" APP_RC=$? # SIGSEGV might be fixed by touch init_data.xml. Try it. if [ $APP_RC -ne 0 ]; then grep SEGV stderr.txt | tee -a ${FAIL_LOG} if [ $? -eq 0 ]; then echo "* Looks like SIGSEGV. Try the workaround..." cat /dev/null > init_data.xml cat /dev/null > out.txt rm stderr.txt echo "$CMD" $CMD test_rc "workaround: create empty init_data.xml file" APP_RC=$? else echo "* no SIGSEGV, so no workaround attempt. " fi fi # If the app failed, show stderr if [ $APP_RC -ne 0 ]; then echo "* App failed. Contents of stderr: " $INDENT stderr.txt fi # Check stdout and stderr for valid output if [ $APP_NAME = "hello" ]; then OUT_STR="Computation completed" ERR_STR="goodbye!" elif [ $APP_NAME = "yello" ]; then OUT_STR="Blow me down!" ERR_STR="Blow me down!" else OUT_STR="Blow me down!" ERR_STR="worker: all done" fi grep -q "$OUT_STR" out.txt test_rc "$APP_NAME stdout text" grep -q "$ERR_STR" stderr.txt test_rc "$APP_NAME stderr text" fi fi } # Now test all these: # test_example_app hello test_example_app yello test_example_app cube # test_example_app lalanne clean_up summary ##