#!/bin/sh # # The regression-test driver script. This used to be explicit in the # makefile before we regrouped the regression tests by stable and unstable # drivers. # Without GNU date extensions, %N won't expand and we only get 1sec precision starttime=`date +"%s * 1000000000 + %N" | sed '/+ N/s///' 2>/dev/null` # We need to have the build directory in $GPSD_HOME to find the new gpsd if [ "`dirname $0`" = "." ]; then GPSD_HOME=`pwd` else GPSD_HOME=`dirname $0` fi # sed may choke on binary data with some LANG settings unset LANG # Arrange to call a gpsfake in the source directory without fuss. if [ -z ${PYTHON} ]; then PYTHON="python2" fi # Define the directories we ask setup.py to install the # modules/extensions and scripts to. The way chosen here reproduces # the internal behaviour of distutils. Unfortunately distutils does # not export the pre-defined/configured directories, so we have to # define them on our own. For default installations of distutils the # chosen values here will match what distutils uses. py_libdir=`pwd`/build/`${PYTHON} -c 'import distutils.util; import sys; print("lib.%s-%s" %(distutils.util.get_platform(), sys.version[0:3]))'` py_scriptdir=`pwd`/build/`${PYTHON} -c 'import sys; print("scripts-%s" %(sys.version[0:3], ))'` if [ -d ${py_libdir} ] && [ -d ${py_scriptdir} ]; then PYTHONPATH=${py_libdir} export PYTHONPATH PATH=${py_scriptdir}:${PATH} fi export GPSD_HOME PATH # Use a non-default value of the SHM key to avoid colliding with # production instances. Value must be legal for strtol(3); # this is the default key plus one. export GPSD_SHM_KEY=0x47505345 mode=regress testing=daemon opts="" logfile="" help="0" baton=false quiet=false quieter=false while getopts cl:sStbuvo:qQh opt do case $opt in c) testing=clientlib ;; # 'client' rather than the daemon l) logfile=$OPTARG ;; # Logfile to save diffs to s) mode=regress ;; # Run regression tests S) mode=slowregress ;; # Run regression tests with big delays t) baton=true mode=regress ;; # Run regression tests w/baton b) mode=build ;; # Rebuild regression check files u) opts="$opts -u" ;; # Force UDP v) mode=view ;; # View result of generating a check file o) opts="$opts $OPTARG" ;; # Pass options to gpsfake q) quiet=true ;; # Suppress header/trailer messages Q) quiet=true; quieter=true ;; # Suppress all success chatter h) help="1" ;; esac done shift $(($OPTIND - 1)) if [ $help -eq "1" ] then echo echo echo "Regression test driver script" echo "-h - this help" echo "-c - test with 'client' rather than the daemon" echo "-l - where to log diffs to" echo "-s - run regression tests" echo "-S - run regression tests with realistic timing delays" echo "-t - Run regression tests w/baton" echo "-b - Rebuild regression check files" echo "-u - Force UDP" echo "-v - view result of generating a check file" echo "-o - Pass options to gpsfake" echo "-q - Suppress header/trailer messages" echo "-Q - Suppress all success chatter" echo exit 0 fi # Enables us to turn debugging up high without screwing up the diff checks # First and Second filter out gpsd log messages. # Third filters out gps.py verbose loggging # Fourth filters out WATCH responses # Fifth filters out DEVICE responses # Sixth filters out VERSION responses # Seventh filters out device fields GPSFILTER="sed -e /^gpsd:/d -e /^gpsfake/d -e /GPS-DATA/d -e /WATCH/d -e /DEVICE/d -e /VERSION/d -e s/,\"device\":[^,}]*//" # Use ALTFILTER to set up custom filtering when a regression test fails # This example filters out altitude and some fields computed by gpsd's error # modeling - these are fragile in the presence of changes to the fix-buffering # logic. Note that as the last attribute mode needs to be handled differently. #ALTFILTER="-e s/\"alt\":[^,]*,// -e s/\"ep[vhs]\":[-+0-9.]*// -e s/,\"mode\":[^}]*//" TMP=`mktemp -d -t gpsd-test-XXXXXXXXXXXXXX` # Only twirl the baton on a tty, avoids junk in transcripts. if [ -t 0 ] then baton=false fi if [ $baton = true ] then opts="$opts -b" fi if [ $mode = slowregress ] then opts="$opts -S" fi if [ $quieter = true ] then opts="$opts -q" fi case $mode in regress|slowregress) [ $quiet = true ] || echo "Testing the $testing..." >&2 errors=0; total=0; notfound=0;error_list=""; for f in $*; do if [ -r $f.chk ] then trap 'rm -f ${TMP}/test-$$.chk; exit $errors' EXIT HUP INT TERM case $testing in daemon) TMPDIR=${TMP} ${PYTHON} ${PYTHON_COVERAGE} ${GPSD_HOME}/gpsfake -s 38400 -1 -p $opts ${f} | ${GPSFILTER} ${ALTFILTER} >${TMP}/test-$$.chk ;; clientlib) ${GPSD_HOME}/tests/test_libgps -b <${f} >${TMP}/test-$$.chk ;; esac if [ "${ALTFILTER}" ] then trap 'rm -f ${TMP}/test-$$.chk ${TMP}/testout-$$.chk ${TMP}/testin-$$.chk ${TMP}/diff-$$; exit $errors' EXIT HUP INT TERM sed -n <${f}.chk >${TMP}/testin-$$.chk ${ALTFILTER} -e 'p'; sed -n <${TMP}/test-$$.chk >${TMP}/testout-$$.chk ${ALTFILTER} -e 'p'; diff -ub ${TMP}/testin-$$.chk ${TMP}/testout-$$.chk >${TMP}/diff-$$; else diff -ub ${f}.chk ${TMP}/test-$$.chk >${TMP}/diff-$$; fi if test -s ${TMP}/diff-$$ ; then errors=`expr $errors + 1`; error_list="$error_list \"${f}\"" if ! test -s ${TMP}/test-$$.chk ; then echo " Output missing for ${f}" >${TMP}/diff-$$ fi if [ -z "$logfile" ] then cat ${TMP}/diff-$$ else cat ${TMP}/diff-$$ >>$logfile fi fi; rm -f ${TMP}/test-$$.chk ${TMP}/testout-$$.chk ${TMP}/testin-$$.chk ${TMP}/diff-$$ else echo "*** No check log $f.chk exists" notfound=`expr $notfound + 1`; fi total=`expr $total + 1`; done; if test $errors -gt 0; then echo "Regression test FAILED: $errors errors in $total tests total ($notfound not found)."; echo "The following test Failed:" echo "================================================================" for err in $error_list do echo $err done echo "================================================================" status=1; else if [ $quiet = true ] && [ $total -eq 1 ] && [ $notfound -eq 0 ] then [ $quieter = true ] || echo "Regression test $1 successful" else echo "Regression test successful: no errors in $total tests ($notfound not found)."; fi status=0; fi ;; build) [ $quiet = true ] || echo "Rebuilding $testing regressions..." >&2 for f in $*; do case $testing in daemon) ${PYTHON} ${PYTHON_COVERAGE} ${GPSD_HOME}/gpsfake -s 38400 -1 -p $opts ${f} | ${GPSFILTER} >${f}.chk;; clientlib) ${GPSD_HOME}/test_libgps -b <${f} >${f}.chk ;; esac done status=0 ;; view) [ $quiet = true ] || echo "Viewing..." >&2 for f in $*; do case $testing in daemon) ${PYTHON} ${PYTHON_COVERAGE} ${GPSD_HOME}/gpsfake -s 38400 -1 -p $opts ${f} | ${GPSFILTER} ;; clientlib) ${GPSD_HOME}/test_libgps -b <${f} ;; esac done status=0 ;; esac # See starttime above endtime=`date +"%s * 1000000000 + %N" | sed '/+ N/s///' 2>/dev/null` if [ $quiet = false ] && [ "$starttime" -a "$endtime" ] then # Avoid using -n here since some shells don't support it. echo "Elapsed time:" \ $(echo "scale=2; (${endtime} - ${starttime}) / 1000000000" | bc) >&2 fi rm -fr ${TMP} exit $status