2003-01-19 21:07:38 +03:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
|
|
|
# Program: RunSafely.sh
|
|
|
|
#
|
|
|
|
# Synopsis: This script simply runs another program. If the program works
|
|
|
|
# correctly, this script has no effect, otherwise it will do things
|
|
|
|
# like print a stack trace of a core dump. It always returns
|
|
|
|
# "successful" so that tests will continue to be run.
|
|
|
|
#
|
2003-05-11 21:34:14 +04:00
|
|
|
# This script funnels stdout and stderr from the program into the
|
2006-11-25 11:56:10 +03:00
|
|
|
# fourth argument specified, and outputs a <outfile>.time file which
|
|
|
|
# contains a timing of the program and the program's exit code.
|
2012-02-23 09:03:03 +04:00
|
|
|
#
|
2007-05-04 01:32:39 +04:00
|
|
|
# If optional parameters -r <remote host> -l <remote user> are
|
|
|
|
# specified, it execute the program remotely using rsh.
|
|
|
|
#
|
2012-02-23 09:03:03 +04:00
|
|
|
# Syntax:
|
2006-11-25 11:56:10 +03:00
|
|
|
#
|
2008-09-10 21:11:20 +04:00
|
|
|
# RunSafely.sh [-r <rhost>] [-l <ruser>] [-rc <client>] [-rp <port>]
|
2012-10-27 04:28:04 +04:00
|
|
|
# [-u <under>] [--show-errors] -t <timeit>
|
2012-10-29 04:17:18 +04:00
|
|
|
# <timeout> <infile> <outfile> <program> <args...>
|
2006-11-25 11:56:10 +03:00
|
|
|
#
|
|
|
|
# where:
|
2007-05-04 01:32:39 +04:00
|
|
|
# <rhost> is the remote host to execute the program
|
|
|
|
# <ruser> is the username on the remote host
|
2008-09-09 10:12:33 +04:00
|
|
|
# <client> is the remote client used to execute the program
|
2008-09-10 21:11:20 +04:00
|
|
|
# <port> is the port used by the remote client
|
2010-01-14 05:10:24 +03:00
|
|
|
# <under> is a wrapper that the program is run under
|
2012-04-17 00:29:52 +04:00
|
|
|
# <timeit> is a wrapper that is used to collect timing data
|
2006-11-25 11:56:10 +03:00
|
|
|
# <timeout> is the maximum number of seconds to let the <program> run
|
|
|
|
# <infile> is a file from which standard input is directed
|
|
|
|
# <outfile> is a file to which standard output and error are directed
|
|
|
|
# <program> is the path to the program to run
|
|
|
|
# <args...> are the arguments to pass to the program.
|
2003-05-11 21:34:14 +04:00
|
|
|
#
|
2012-10-27 04:28:04 +04:00
|
|
|
# If --show-errors is given, then the output file will be printed if the command
|
2012-10-29 22:25:07 +04:00
|
|
|
# fails (returns a non-zero exit code).
|
2012-10-27 04:28:04 +04:00
|
|
|
|
2006-06-07 22:57:36 +04:00
|
|
|
if [ $# -lt 4 ]; then
|
2012-10-29 04:17:18 +04:00
|
|
|
echo "./RunSafely.sh [-t <PATH>] <timeout> <infile> <outfile>" \
|
2012-03-18 23:37:58 +04:00
|
|
|
"<program> <args...>"
|
2006-11-25 11:56:10 +03:00
|
|
|
exit 1
|
2006-06-07 22:57:36 +04:00
|
|
|
fi
|
|
|
|
|
2008-10-26 01:45:37 +04:00
|
|
|
# Save a copy of the original arguments in a string before we
|
|
|
|
# clobber them with the shift command.
|
|
|
|
ORIG_ARGS="$*"
|
|
|
|
|
2006-06-07 22:57:36 +04:00
|
|
|
DIR=${0%%`basename $0`}
|
2007-05-04 01:32:39 +04:00
|
|
|
|
|
|
|
RHOST=
|
|
|
|
RUSER=`id -un`
|
2008-09-09 10:12:33 +04:00
|
|
|
RCLIENT=rsh
|
2008-09-10 21:11:20 +04:00
|
|
|
RPORT=
|
2010-01-14 05:10:24 +03:00
|
|
|
RUN_UNDER=
|
2012-03-18 23:37:58 +04:00
|
|
|
TIMEIT=
|
2012-10-27 04:28:04 +04:00
|
|
|
SHOW_ERRORS=0
|
2007-05-04 01:32:39 +04:00
|
|
|
if [ $1 = "-r" ]; then
|
|
|
|
RHOST=$2
|
|
|
|
shift 2
|
|
|
|
fi
|
|
|
|
if [ $1 = "-l" ]; then
|
|
|
|
RUSER=$2
|
|
|
|
shift 2
|
|
|
|
fi
|
2008-09-09 10:12:33 +04:00
|
|
|
if [ $1 = "-rc" ]; then
|
|
|
|
RCLIENT=$2
|
|
|
|
shift 2
|
|
|
|
fi
|
2008-09-10 21:11:20 +04:00
|
|
|
if [ $1 = "-rp" ]; then
|
|
|
|
RPORT="-p $2"
|
2008-09-09 10:12:33 +04:00
|
|
|
shift 2
|
|
|
|
fi
|
2010-01-14 05:10:24 +03:00
|
|
|
if [ $1 = "-u" ]; then
|
|
|
|
RUN_UNDER=$2
|
|
|
|
shift 2
|
|
|
|
fi
|
2012-10-27 04:28:04 +04:00
|
|
|
if [ $1 = "--show-errors" ]; then
|
|
|
|
SHOW_ERRORS=1
|
|
|
|
shift 1
|
|
|
|
fi
|
2011-02-09 03:37:50 +03:00
|
|
|
if [ $1 = "-t" ]; then
|
|
|
|
TIMEIT=$2
|
|
|
|
shift 2
|
|
|
|
fi
|
2007-05-04 01:32:39 +04:00
|
|
|
|
2012-03-18 23:37:58 +04:00
|
|
|
if [ "$TIMEIT" = "" ]; then
|
|
|
|
echo "error: missing required argument -t for path to 'timeit'"
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
|
2012-03-17 21:59:50 +04:00
|
|
|
TIMELIMIT=$1
|
2012-10-29 04:17:18 +04:00
|
|
|
INFILE=$2
|
|
|
|
OUTFILE=$3
|
|
|
|
PROGRAM=$4
|
|
|
|
shift 4
|
2003-01-19 21:07:38 +03:00
|
|
|
|
2008-11-13 06:24:49 +03:00
|
|
|
PROG=${PROGRAM}
|
2008-11-22 20:03:09 +03:00
|
|
|
if [ `basename ${PROGRAM}` = "lli" ]; then
|
2008-11-13 06:24:49 +03:00
|
|
|
PROG=`basename ${PROGRAM}`
|
|
|
|
fi
|
|
|
|
|
2012-10-29 04:17:21 +04:00
|
|
|
# Disable core file emission.
|
2012-03-18 23:12:04 +04:00
|
|
|
LIMITARGS=""
|
2012-10-29 04:17:21 +04:00
|
|
|
LIMITARGS="$LIMITARGS --limit-core 0"
|
2012-03-18 23:12:04 +04:00
|
|
|
|
2012-10-29 04:17:21 +04:00
|
|
|
# Set the CPU limit. We watchdog the process, so this is mostly just for
|
|
|
|
# paranoia.
|
|
|
|
LIMITARGS="$LIMITARGS --limit-cpu $TIMELIMIT"
|
2012-03-18 23:12:04 +04:00
|
|
|
|
2012-10-29 04:17:21 +04:00
|
|
|
# To prevent infinite loops which fill up the disk, specify a limit on size
|
|
|
|
# of files being output by the tests.
|
|
|
|
#
|
|
|
|
# We set the limit at 100MB.
|
|
|
|
LIMITARGS="$LIMITARGS --limit-file-size 104857600"
|
2008-02-15 02:46:20 +03:00
|
|
|
|
2012-10-29 04:17:21 +04:00
|
|
|
# Set the virtual memory limit at 800MB.
|
|
|
|
LIMITARGS="$LIMITARGS --limit-rss-size 838860800"
|
2003-07-03 00:42:05 +04:00
|
|
|
|
2012-03-18 23:12:04 +04:00
|
|
|
# Run the command, timing its execution and logging the status summary to
|
|
|
|
# $OUTFILE.time.
|
2007-05-04 01:32:39 +04:00
|
|
|
PWD=`pwd`
|
2010-01-14 05:10:24 +03:00
|
|
|
COMMAND="$RUN_UNDER $PROGRAM $*"
|
2006-11-25 11:56:10 +03:00
|
|
|
|
2012-03-18 23:12:04 +04:00
|
|
|
TIMEITCMD="$TIMEIT $LIMITARGS --timeout $TIMELIMIT --chdir $PWD"
|
2007-05-04 01:32:39 +04:00
|
|
|
if [ "x$RHOST" = x ] ; then
|
2012-03-18 03:28:28 +04:00
|
|
|
rm -f "$OUTFILE.time"
|
2012-03-18 23:12:04 +04:00
|
|
|
$TIMEITCMD \
|
|
|
|
--summary $OUTFILE.time \
|
|
|
|
--redirect-input $INFILE \
|
|
|
|
--redirect-output $OUTFILE \
|
|
|
|
$COMMAND
|
2007-05-04 01:32:39 +04:00
|
|
|
else
|
2012-03-20 02:00:15 +04:00
|
|
|
# Get the absolute path to INFILE.
|
2012-03-21 02:17:52 +04:00
|
|
|
ABSINFILE=$(cd $(dirname $INFILE); pwd)/$(basename $INFILE)
|
2008-11-13 06:24:49 +03:00
|
|
|
rm -f "$PWD/${PROG}.command"
|
|
|
|
rm -f "$PWD/${PROG}.remote"
|
2012-03-18 03:28:28 +04:00
|
|
|
rm -f "$PWD/${OUTFILE}.remote.time"
|
2012-03-20 02:00:15 +04:00
|
|
|
echo "$TIMEITCMD --summary $PWD/$OUTFILE.remote.time --redirect-input $ABSINFILE --redirect-output $PWD/${OUTFILE}.remote $COMMAND" > "$PWD/${PROG}.command"
|
2008-11-13 06:24:49 +03:00
|
|
|
chmod +x "$PWD/${PROG}.command"
|
2008-03-04 17:38:01 +03:00
|
|
|
|
2008-11-13 06:24:49 +03:00
|
|
|
( $RCLIENT -l $RUSER $RHOST $RPORT "ls $PWD/${PROG}.command" ) > /dev/null 2>&1
|
|
|
|
( $RCLIENT -l $RUSER $RHOST $RPORT "$PWD/${PROG}.command" )
|
2012-03-18 03:28:28 +04:00
|
|
|
cp $PWD/${OUTFILE}.remote.time $OUTFILE.time
|
2012-03-18 23:12:04 +04:00
|
|
|
sleep 1
|
|
|
|
cp -f $PWD/${OUTFILE}.remote ${OUTFILE}
|
|
|
|
rm -f $PWD/${OUTFILE}.remote
|
|
|
|
rm -f $PWD/${OUTFILE}.remote.time
|
2007-05-04 01:32:39 +04:00
|
|
|
fi
|
2003-07-03 00:42:05 +04:00
|
|
|
|
2006-11-28 10:16:45 +03:00
|
|
|
exitval=`grep '^exit ' $OUTFILE.time | sed -e 's/^exit //'`
|
2008-10-26 01:45:37 +04:00
|
|
|
fail=yes
|
2006-11-28 10:16:45 +03:00
|
|
|
if [ -z "$exitval" ] ; then
|
|
|
|
exitval=99
|
2008-10-26 01:45:37 +04:00
|
|
|
echo "TEST $PROGRAM FAILED: CAN'T GET EXIT CODE!"
|
|
|
|
elif test "$exitval" -eq 126 ; then
|
|
|
|
echo "TEST $PROGRAM FAILED: command not executable (exit status 126)!"
|
|
|
|
elif test "$exitval" -eq 127 ; then
|
|
|
|
echo "TEST $PROGRAM FAILED: command not found (exit status 127)!"
|
|
|
|
elif test "$exitval" -eq 128 ; then
|
|
|
|
# Exit status 128 doesn't have a standard meaning, but it's unlikely
|
|
|
|
# to be expected program behavior.
|
|
|
|
echo "TEST $PROGRAM FAILED: exit status 128!"
|
|
|
|
elif test "$exitval" -gt 128 ; then
|
|
|
|
echo "TEST $PROGRAM FAILED: process terminated by signal (exit status $exitval)!"
|
2012-10-29 22:25:07 +04:00
|
|
|
elif [ "$SHOW_ERRORS" -eq 1 -a "$exitval" -ne 0 ] ; then
|
|
|
|
echo "TEST $PROGRAM FAILED: EXIT != 0"
|
2008-10-26 01:45:37 +04:00
|
|
|
else
|
|
|
|
fail=no
|
2006-11-28 10:16:45 +03:00
|
|
|
fi
|
|
|
|
echo "exit $exitval" >> $OUTFILE
|
|
|
|
|
2008-10-26 01:45:37 +04:00
|
|
|
# If we detected a failure, print the name of the test executable to the
|
|
|
|
# output file. This will cause it to compare as different with other runs
|
|
|
|
# of the same test even if they fail in the same way, because they'll have
|
|
|
|
# different command names.
|
|
|
|
if [ "${fail}" != "no" ]; then
|
|
|
|
echo "RunSafely.sh detected a failure with these command-line arguments: " \
|
|
|
|
"$ORIG_ARGS" >> $OUTFILE
|
2012-10-27 04:28:04 +04:00
|
|
|
if [ "$SHOW_ERRORS" = "1" ]; then
|
|
|
|
echo "error: command failed while generating $OUTFILE"
|
|
|
|
echo "---"
|
|
|
|
cat $OUTFILE
|
|
|
|
echo "---"
|
|
|
|
fi
|
2003-07-01 22:04:43 +04:00
|
|
|
fi
|
|
|
|
|
2008-10-26 01:45:37 +04:00
|
|
|
# Always return "successful" so that tests will continue to be run.
|
|
|
|
exit 0
|