298 lines
7.3 KiB
Bash
Executable File
298 lines
7.3 KiB
Bash
Executable File
#!/bin/bash
|
|
# vim: ft=sh ts=4 sw=4 et
|
|
#
|
|
# usage: run-test <prog> <filename>
|
|
#
|
|
# Ralph Becket <rafe@csse.unimelb.edu.au>
|
|
#
|
|
#
|
|
# Run program <prog> on <filename> and compare the results against the
|
|
# expected outputs. The solver is run with default time and memory limits
|
|
# which an be configured by setting TIMELIMIT (default 30 seconds) and
|
|
# MEMLIMIT (default 1000 megabytes).
|
|
#
|
|
# If G12PATH is set and $G12PATH/<prog> is executable then this file is
|
|
# run, otherwise PATH is used.
|
|
#
|
|
# <filename> should end in
|
|
# - .fzn for FlatZinc tests
|
|
# - .mzn for MiniZinc tests
|
|
# - .zinc for Zinc tests
|
|
# - .dzn for Zinc or MiniZinc tests (the prefix of <filename> up to
|
|
# the first '.' is used to identify the corresponding .mzn or .zinc model).
|
|
#
|
|
#
|
|
# TEST CASES
|
|
#
|
|
# A test case consists of the following:
|
|
#
|
|
# - a <model>.zinc or <model>.mzn or <model>.fzn file;
|
|
#
|
|
# - zero or more <model>.<testid>.dzn files (as an option for .zinc and .mzn
|
|
# tests which separate the data from the model);
|
|
#
|
|
# - an optional <model>.opt file containing command line options to be
|
|
# passed to <prog> for <model>;
|
|
#
|
|
# - an optional <model>.<prog>.opt file containing command line options
|
|
# specific to <prog> for <model>;
|
|
#
|
|
# - [where a test is not specified as a .dzn file] one or more <model>*.exp*
|
|
# or <model>*.err_exp* files specifying the expected output or error report
|
|
#
|
|
# - [where a test is specified as a .dzn file] one or more;
|
|
# <model>.<testid>*.exp* or <model>.<testid>*.err_exp* files specifying the
|
|
# expected output or error report.
|
|
#
|
|
#
|
|
# HOW TEST CASES ARE RUN
|
|
#
|
|
# The contents of any <model>.opts and <model>.<prog>.opts files are
|
|
# collected in $OPTS.
|
|
#
|
|
# Where a test is specified as a <model>.[fzn|mzn|zinc] file:
|
|
# $OUT is defined as <model>.<prog>.out
|
|
# $ERR is defined as <model>.<prog>.err
|
|
# The test is run under time-and-mem-limit as:
|
|
# <prog> $OPTS <model>.[fzn|mzn|zinc] >$OUT 2>$ERR
|
|
#
|
|
# Where a test is specified as a <model>.<testid>.dzn file:
|
|
# $OUT is defined as <model>.<testid>.<prog>.out
|
|
# $ERR is defined as <model>.<testid>.<prog>.err
|
|
# The test is run under time-and-mem-limit as:
|
|
# <prog> $OPTS -d <model>.<testid>.dzn <model>.[mzn|zinc] >$OUT 2>$ERR
|
|
#
|
|
# If the $OUT file matches a <model>*.exp* or <model>.<testid>.*exp* file
|
|
# or the $ERR file matches a <model>*.err_exp* or <model>.<testid>.*err_exp*
|
|
# file then the test is deemed to have passed and $OUT and $ERR are deleted.
|
|
# Otherwise an error message is printed and $OUT and $ERR are left for later
|
|
# review.
|
|
|
|
|
|
|
|
# Uncomment the next line for debugging:
|
|
# set -x
|
|
|
|
# Set default time and memory limits (seconds and megabytes respectively).
|
|
#
|
|
TIMELIMIT=${TIMELIMIT:-30}
|
|
MEMLIMIT=${MEMLIMIT:-8000}
|
|
|
|
# The name of this program as invoked.
|
|
#
|
|
THIS=$(basename $0)
|
|
|
|
# Parse the command line.
|
|
#
|
|
if [ $# -ne 2 ]
|
|
then
|
|
echo "usage: $THIS <prog> <filename>" >&2
|
|
echo " <filename> must be either " >&2
|
|
echo " <model>.<testid>.dzn " >&2
|
|
echo " or <model>.mzn" >&2
|
|
echo " or <model>.fzn" >&2
|
|
echo " or <model>.zinc" >&2
|
|
echo " Environmnent vars TIMELIMIT (default $TIMELIMIT seconds)" >&2
|
|
echo " and MEMLIMIT (default $MEMLIMIT megabytes) are recognised." >&2
|
|
exit 1
|
|
fi
|
|
|
|
PROG=$1
|
|
FILENAME=$2
|
|
|
|
if test "$G12PATH" -a -x "$G12PATH/$PROG"; then
|
|
PROG_EXEC="$G12PATH/$PROG"
|
|
else
|
|
PROG_EXEC="$PROG"
|
|
fi
|
|
|
|
# cd to the directory of the problem file if it is not present in the
|
|
# current working directory.
|
|
#
|
|
DIR=$(dirname $FILENAME)
|
|
if [ -n "$DIR" ]
|
|
then
|
|
cd $DIR >/dev/null 2>&1
|
|
FILENAME=$(basename $FILENAME)
|
|
fi
|
|
|
|
# get_exp_out_err_files X sets the OPTS, EXPS, ERREXPS, OUT and ERR variables
|
|
# for problem X. If no expected output files are found then exit.
|
|
#
|
|
function get_exp_out_err_files () {
|
|
|
|
X=$1
|
|
|
|
# Find the .exp files.
|
|
#
|
|
EXPS=$(find . -maxdepth 1 -name $X'*.exp*')
|
|
ERREXPS=$(find . -maxdepth 1 -name $X'*.err_exp*')
|
|
|
|
# If no .exp file exists for this model then do nothing.
|
|
#
|
|
if [ -z "$EXPS" -a -z "$ERREXPS" ]
|
|
then
|
|
echo "$THIS: skipping $FILENAME since it has no .exp files" >&2
|
|
exit 0
|
|
fi
|
|
|
|
# Read any special options for this model.
|
|
#
|
|
[ -e $X.opt ] && OPTS=$(cat $X.opt)
|
|
[ -e $X.$PROG.opt ] && OPTS=$OPTS" "$(cat $X.$PROG.opt)
|
|
|
|
# Construct the command to run the solver.
|
|
#
|
|
OUT=$X.$PROG.out
|
|
ERR=$X.$PROG.err
|
|
|
|
}
|
|
|
|
# Decide what to do with the given file.
|
|
#
|
|
case "$FILENAME" in
|
|
|
|
*.fzn)
|
|
X=$(basename $FILENAME .fzn)
|
|
FZN=$X.fzn
|
|
|
|
get_exp_out_err_files $X
|
|
|
|
# Construct the command to run the solver.
|
|
#
|
|
CMD="$PROG_EXEC $OPTS $FZN"
|
|
|
|
;;
|
|
|
|
*.mzn)
|
|
X=$(basename $FILENAME .mzn)
|
|
MZN=$X.mzn
|
|
|
|
# If a .dzn file exists for this model then do nothing.
|
|
#
|
|
if ls $X*.dzn >/dev/null 2>&1
|
|
then
|
|
exit 0
|
|
fi
|
|
|
|
get_exp_out_err_files $X
|
|
|
|
# Construct the command to run the solver.
|
|
#
|
|
CMD="$PROG_EXEC $OPTS $MZN"
|
|
|
|
;;
|
|
|
|
*.zinc)
|
|
X=$(basename $FILENAME .zinc)
|
|
ZINC=$X.zinc
|
|
|
|
# If a .dzn file exists for this model then do nothing.
|
|
#
|
|
if ls $X*.dzn >/dev/null 2>&1
|
|
then
|
|
exit 0
|
|
fi
|
|
|
|
get_exp_out_err_files $X
|
|
|
|
# Construct the command to run the solver.
|
|
#
|
|
CMD="$PROG_EXEC $OPTS $ZINC"
|
|
|
|
;;
|
|
|
|
*.dzn)
|
|
X=$(basename $FILENAME .dzn)
|
|
DZN=$X.dzn
|
|
MZN=$(echo $X | sed 's/[.].*//').mzn
|
|
ZINC=$(echo $X | sed 's/[.].*//').zinc
|
|
|
|
# Find the corresponding .mzn or .zinc file. Report an error if it
|
|
# doesn't exist.
|
|
#
|
|
MODEL=""
|
|
[ -e $MZN ] && MODEL=$MZN
|
|
[ -e $ZINC ] && MODEL=$ZINC
|
|
if [ -z $MODEL ]
|
|
then
|
|
echo "$THIS: no .mzn or .zinc file corresponding to $DZN" >&2
|
|
exit 1
|
|
fi
|
|
|
|
get_exp_out_err_files $X
|
|
|
|
# Construct the command to run the solver (give priority to
|
|
# zinc models).
|
|
#
|
|
CMD="$PROG_EXEC $OPTS -d $DZN $MODEL"
|
|
|
|
;;
|
|
|
|
*)
|
|
# Don't recognise this file, just ignore it.
|
|
#
|
|
echo "$THIS: ignoring unrecognised file $FILENAME" >&2
|
|
exit 1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
# Run the solver and generate the .out and .err files.
|
|
#
|
|
echo -n "$THIS: $CMD"
|
|
time-and-mem-limit $TIMELIMIT $MEMLIMIT $CMD >$OUT 2>$ERR
|
|
#ulimit -d $MEMLIMITKB -m $MEMLIMITKB -v $MEMLIMITKB -t $TIMELIMIT
|
|
#$CMD >$OUT 2>$ERR
|
|
|
|
# Compare the solver output against the expected output.
|
|
#
|
|
PASSFAIL=fail
|
|
|
|
if [ -n "$EXPS" ]
|
|
then
|
|
for EXP in $EXPS
|
|
do
|
|
if diff --brief --ignore-all-space \
|
|
-I 'minizinc.exe: flattening killed by signal.*' \
|
|
$OUT $EXP >/dev/null 2>&1
|
|
then
|
|
PASSFAIL=pass
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [ -n "$ERREXPS" ]
|
|
then
|
|
for ERREXP in $ERREXPS
|
|
do
|
|
if diff -I "^\(IBM \)\?ILOG.*CPLEX.*" --brief --ignore-all-space \
|
|
-I 'minizinc.exe: flattening killed by signal.*' \
|
|
$ERR $ERREXP >/dev/null 2>&1
|
|
then
|
|
PASSFAIL=pass
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Clean up after success or report failure.
|
|
#
|
|
if [ "$PASSFAIL" = "pass" ]
|
|
then
|
|
echo " ... passed"
|
|
rm -f $OUT $ERR
|
|
else
|
|
echo " ... failed"
|
|
echo "$THIS: no match against expected outputs"
|
|
echo "$THIS: ---- $OUT ----"
|
|
cat $OUT
|
|
echo "$THIS: ---- $ERR ----"
|
|
cat $ERR
|
|
echo "$THIS: ---- end of output ----"
|
|
exit 1
|
|
fi
|
|
|