Beware, syntax and semantics of many config options was changed.
Evaluator
~~~~~~~~~
-!!! timed-out interactive tasks !!!
-lepsi time limity
-zkopirovat *.ok i kdyz program spadne na run-time error
-konfigurovatelne vstupni a vystupni soubory
-konfigurovatelny pristup k timerum a /proc/self/stat (pripadne /proc/self/fd)
-better formatting of the score table
-online ukazovani runtime a memory
+box: konfigurovatelny pristup k timerum a /proc/self/stat (pripadne /proc/self/fd)
+score: better formatting of the score table
score: alignment of table cells
-input files shouldn't be mandatory (esp. for interactive tasks)
stdio tasks: don't allow them to read the files
-interactive tasks: allow logging to the main log?
interactive tasks: solve deadlocks?
-weird characters in checker command descriptions: use automatic escaping?
-moving handling of points file to bin/ev
+interactive tasks: logging of messages
+a tool for creating accounts with passwords (according to userlist?) ; replace UID ranges completely?
+fix mo-* to use mo-get-users
+post-sandbox hook
-better messages on failed submit
+guide: compile <file>, not only <task>
+guide: status
Environment
~~~~~~~~~~~
#!/bin/bash
# The Evaluator -- Master Control Script
-# (c) 2001--2003 Martin Mares <mj@ucw.cz>
+# (c) 2001--2004 Martin Mares <mj@ucw.cz>
set -e
if [ ! -f config -o ! -f bin/lib ] ; then
. bin/lib
. config
-# Set up environment:
-# HDIR home dir of the evaluator
-# PDIR problem specific data
-# SDIR contestant's solution
-# TDIR test results
-# BOXDIR sandbox
-# PROBLEM problem we're evaluating
-
-[ -n "$2" ] || die "Usage: ev <contestant> <problem> [<program>]"
+[ -n "$2" -a -z "$4" ] || die "Usage: ev <contestant> <problem> [<program>]"
CONTESTANT=$1
PROBLEM=$2
dir-init
locate-source $3
compile || true
-# Perform the tests
+# Initialize the points file
PTSFILE=$TDIR/points
+>$PTSFILE
+
+function test-verdict
+{
+ if [ $1 == 0 ] ; then
+ pend "$2"
+ else
+ pend "$2 ($1 points)"
+ fi
+ echo >>$PTSFILE "$TEST $1 $2"
+ exit 0
+}
+
+# Perform the tests
for TEST in $TESTS ; do
(
[ -f $PDIR/$TEST.config ] && . $PDIR/$TEST.config
exec >$TDIR/$TEST.log
pstart "Test $TEST... "
- echo "Test $TEST"
- echo >>$PTSFILE -n "$TEST "
- if [ ! -f $TDIR/$PROBLEM ] ; then
- echo >>$PTSFILE "0 Compile error."
- die "No executable file"
- fi
- test-run || exit 0
- syntax-check || exit 0
- output-check || exit 0
- if [ -f $TDIR/$TEST.pts ] ; then
- PTS=`cat $TDIR/$TEST.pts`
- else
- PTS=$POINTS_PER_TEST
- fi
- echo "Test completed OK ($PTS points)"
- echo >>$PTSFILE "$PTS OK"
- pend "OK, $PTS points"
+ echo "Test $TEST ($POINTS_PER_TEST points)"
+ test-run
+ syntax-check
+ output-check
+ die "You must never see this message."
)
done
#!/bin/bash
# The Evaluator for Open Data Problems
-# (c) 2001 Martin Mares <mj@ucw.cz>
+# (c) 2001--2004 Martin Mares <mj@ucw.cz>
set -e
if [ ! -f config -o ! -f bin/lib ] ; then
. bin/lib
. config
-# Set up environment:
-# HDIR home dir of the evaluator
-# PDIR problem specific data
-# SDIR contestant's solution
-# TDIR test results
-# BOXDIR sandbox
-# PROBLEM problem we're evaluating
-
[ -n "$2" ] || die "Usage: ev-open <contestant> <problem>"
CONTESTANT=$1
PROBLEM=$2
log-init
. $PDIR/config
+# Initialize the points file
+PTSFILE=$TDIR/points
+>$PTSFILE
+
+function test-verdict
+{
+ if [ $1 == 0 ] ; then
+ pend "$2"
+ else
+ pend "$2 ($1 points)"
+ fi
+ echo >>$PTSFILE "$TEST $1 $2"
+ exit 0
+}
+
# Perform the tests
PTSFILE=$TDIR/points
for TEST in $TESTS ; do
(
[ -f $PDIR/$TEST.config ] && . $PDIR/$TEST.config
exec >$TDIR/$TEST.log
- pstart "Test $TEST ($POINTS_PER_TEST points)... "
+ pstart "Test $TEST... "
echo "Test $TEST ($POINTS_PER_TEST points)"
- echo >>$PTSFILE -n "$TEST "
- if [ ! -f $SDIR/$TEST.out ] ; then
- echo >>$PTSFILE "0 No solution."
- die "No solution."
- fi
- syntax-check || exit 0
- output-check || exit 0
- echo "Test completed OK ($POINTS_PER_TEST points)"
- echo >>$PTSFILE "$POINTS_PER_TEST OK"
- pend "OK"
+ [ -f $SDIR/$TEST.out ] || test-result 0 "No solution."
+ ln $SDIR/$TEST.out $TDIR/$TEST.out
+ syntax-check
+ output-check
+ die "You must never see this message."
)
done
# The Evaluator -- Shell Function Library
-# (c) 2001 Martin Mares <mj@ucw.cz>
+# (c) 2001--2004 Martin Mares <mj@ucw.cz>
# General settings
shopt -s dotglob
function die
{
+ # Report an internal error
+ echo >&2 "$@"
+ [ -n "$HAVE_LOG" ] && echo "Fatal error: $@"
+ exit 2
+}
+
+function fatal
+{
+ # Report a fatal error in the program being tested
echo >&2 "$@"
[ -n "$HAVE_LOG" ] && echo "Fatal error: $@"
exit 1
function box-init
{
pstart "Preparing sandbox... "
- [ -n "$TEST_USER" ] || die "TEST_USER not set. Please fix."
- if [ $TEST_USER == $EVAL_USER ] ; then
+ if [ -z "$TEST_USER" -o "$TEST_USER" == $EVAL_USER ] ; then
pcont "running locally (INSECURE), "
+ TEST_USER=$EVAL_USER
BOXDIR=box
BOXCMD=bin/box
mkdir -p box
PDIR=problems/$PROBLEM
SDIR=solutions/$CONTESTANT/$PROBLEM
TDIR=testing/$CONTESTANT/$PROBLEM
+ TMPDIR=tmp
[ -d $PDIR ] || die "Problem $PROBLEM not known"
- [ -d $SDIR ] || die "Solution of $PROBLEM not found"
- mkdir -p $TDIR
- rm -rf $TDIR
- cp -a $SDIR $TDIR
+ [ -d $SDIR ] || fatal "Solution of $PROBLEM not found"
+ mkdir -p $TDIR $TMPDIR
+ rm -rf $TDIR $TMPDIR
+ mkdir -p $TDIR $TMPDIR
cat >$TDIR/log <<EOF
Testing solution of $PROBLEM by $CONTESTANT
Test started at `date`
Problem directory: $PDIR
Testing directory: $TDIR
EOF
- >$TDIR/points
pend "OK"
}
SRCEXT=$a
fi
done
- [ -n "$SRCN" ] || die "NOT FOUND"
+ [ -n "$SRCN" ] || fatal "NOT FOUND"
pend $SRCN
echo "Found source file: $SDIR/$SRCN"
}
-# Compilation (compile SDIR/SRCN with PDIR/EXTRAS to EXE=TDIR/PROBLEM)
+# Compilation (compile SDIR/SRCN with PDIR/COMP_EXTRAS to EXE=TDIR/PROBLEM)
function compile
{
pstart "Compiling... "
cp -a $SDIR/$SRCN $TDIR/$SRCN
- if [ -n "$EXTRAS" ] ; then
- echo "Extras: $EXTRAS"
- for a in $EXTRAS ; do cp $PDIR/$a $TDIR/ ; done
+ if [ -n "$COMP_EXTRAS" ] ; then
+ echo "Extras: $COMP_EXTRAS"
+ for a in $COMP_EXTRAS ; do cp $PDIR/$a $TDIR/ ; done
fi
box-clean
- for a in $SRCN $EXTRAS ; do cp $TDIR/$a $BOXDIR/ ; done
+ for a in $SRCN $COMP_EXTRAS ; do cp $TDIR/$a $BOXDIR/ ; done
SRC=$SRCN
EXE=$PROBLEM
CCMD=COMP_$SRCEXT
pend "OK"
}
-# Running of test program according to current task type
+# Running of test program according to current task type (returns exit code and TEST_MSG)
function test-run
{
test-run-$TASK_TYPE
}
-# Running of test program with file input/output
+function test-result
+{
+ P=$1
+ M=$2
+ if [ -s $TDIR/$TEST.pts ] ; then
+ P=`cat $TDIR/$TEST.pts`
+ rm $TDIR/$TEST.pts
+ fi
+ echo "Verdict: $M"
+ echo "Points: $P"
+ test-verdict $P "$M"
+}
-function test-run-file
+function test-prolog
{
pcont "<init> "
box-clean
echo "Executable file: $TDIR/$PROBLEM"
+ if [ ! -x $TDIR/$PROBLEM ] ; then
+ test-result 0 "Compile error."
+ fi
cp $TDIR/$PROBLEM $BOXDIR/
- echo "Input: $TDIR/$PROBLEM"
- ln $PDIR/$TEST.in $TDIR/$TEST.in
- cp $PDIR/$TEST.in $BOXDIR/$PROBLEM.in
- eval $SANDBOX_INIT
- echo "Input files:"
- ls -Al $BOXDIR
-
- pcont "<run> "
+ BOX_EXTRAS=
+ IN_TYPE=${IN_TYPE:-$IO_TYPE}
+ OUT_TYPE=${OUT_TYPE:-$IO_TYPE}
+ case $IN_TYPE in
+ file) echo "Input file: $PROBLEM.in (from $PDIR/$TEST.in)"
+ ln $PDIR/$TEST.in $TDIR/$TEST.in
+ cp $PDIR/$TEST.in $BOXDIR/$PROBLEM.in
+ BOX_EXTRAS="$BOX_EXTRAS -i/dev/null"
+ ;;
+ stdio) echo "Input file: <stdin> (from $PDIR/$TEST.in)"
+ ln $PDIR/$TEST.in $TDIR/$TEST.in
+ cp $PDIR/$TEST.in $BOXDIR/$PROBLEM.in
+ BOX_EXTRAS="$BOX_EXTRAS -i$PROBLEM.in"
+ ;;
+ none) echo "Input file: <none>"
+ ;;
+ *) die "Unknown IN_TYPE $IN_TYPE"
+ ;;
+ esac
+ case $OUT_TYPE in
+ file) echo "Output file: $PROBLEM.out"
+ BOX_EXTRAS="$BOX_EXTRAS -o/dev/null"
+ ;;
+ stdio) echo "Output file: <stdout>"
+ BOX_EXTRAS="$BOX_EXTRAS -o$PROBLEM.out"
+ ;;
+ none) echo "Output file: <none>"
+ ;;
+ *) die "Unknown OUT_TYPE $OUT_TYPE"
+ ;;
+ esac
echo "Timeout: $TIME_LIMIT s"
echo "Memory: $MEM_LIMIT KB"
- BOXOPTS=`eval echo $TEST_SANDBOX_OPTS`
- echo "Sandbox options: $BOXOPTS"
- if ! $BOXCMD $BOXOPTS -- ./$PROBLEM 2>$TDIR/exec.out ; then
- TEST_MSG="`head -1 $TDIR/exec.out`"
- pend "$TEST_MSG"
- cat $TDIR/exec.out
- rm $TDIR/exec.out
- echo >>$PTSFILE "0 $TEST_MSG"
- return 1
- fi
- cat $TDIR/exec.out
- rm $TDIR/exec.out
- test-fetch-output || return 1
+ eval $SANDBOX_INIT
+ echo "Sandbox contents before start:"
+ ls -Al $BOXDIR
}
-function test-fetch-output
+function test-epilog
{
- echo "Output files:"
+ echo "Sandbox contents after exit:"
ls -Al $BOXDIR
- if [ ! -f $BOXDIR/$PROBLEM.out ] ; then
- pend "No output file."
- echo "No output file."
- echo >>$PTSFILE "0 No output."
- return 1
+ case ${OUT_TYPE:-$IO_TYPE} in
+ file) [ -f $BOXDIR/$PROBLEM.out ] || test-result 0 "No output file."
+ cp $BOXDIR/$PROBLEM.out $TDIR/$TEST.out
+ ;;
+ stdio) [ -f $BOXDIR/$PROBLEM.out ] || test-result 0 "No output file."
+ cp $BOXDIR/$PROBLEM.out $TDIR/$TEST.out
+ ;;
+ esac
+}
+
+# Running of test program with file input/output
+
+function test-run-file
+{
+ test-prolog
+ pcont "<run> "
+ BOXOPTS="`eval echo $TEST_SANDBOX_OPTS`$BOX_EXTRAS"
+ echo "Sandbox options: $BOXOPTS"
+ if ! $BOXCMD $BOXOPTS -- ./$PROBLEM 2>$TMPDIR/exec.out ; then
+ MSG=`head -1 $TMPDIR/exec.out`
+ test-result 0 "$MSG"
fi
- cp $BOXDIR/$PROBLEM.out $TDIR/$TEST.out
+ cat $TMPDIR/exec.out
+ test-epilog
}
# Running of interactive test programs
function test-run-interactive
{
- pcont "<init> "
- box-clean
- echo "Executable file: $TDIR/$PROBLEM"
- cp $TDIR/$PROBLEM $BOXDIR/
- echo "Input: $TDIR/$PROBLEM"
- ln $PDIR/$TEST.in $TDIR/$TEST.in
- cp $PDIR/$TEST.in $BOXDIR/$PROBLEM.in
- eval $SANDBOX_INIT
- echo "Input files:"
- ls -Al $BOXDIR
-
+ test-prolog
pcont "<run> "
- echo "Timeout: $TIME_LIMIT s"
- echo "Memory: $MEM_LIMIT KB"
- BOXOPTS=`eval echo $TEST_SANDBOX_OPTS`
+ BOXOPTS="`eval echo $TEST_SANDBOX_OPTS`$BOX_EXTRAS"
echo "Sandbox options: $BOXOPTS"
ICCMD=`eval echo $IA_CHECK`
echo "Interactive checker: $ICCMD"
- if ! $HDIR/bin/iwrapper $BOXCMD $BOXOPTS -- ./$PROBLEM @@ $ICCMD 2>$TDIR/exec.out ; then
- TEST_MSG="`head -1 $TDIR/exec.out`"
- pend "$TEST_MSG"
- cat $TDIR/exec.out
- rm $TDIR/exec.out
- echo "$TEST_MSG"
- echo >>$PTSFILE "0 $TEST_MSG"
- return 1
+ if ! $HDIR/bin/iwrapper $BOXCMD $BOXOPTS -- ./$PROBLEM @@ $ICCMD 2>$TMPDIR/exec.out ; then
+ MSG="`head -1 $TMPDIR/exec.out`"
+ test-result 0 "$MSG"
fi
- cat $TDIR/exec.out
- rm $TDIR/exec.out
- [ -z "$OUTPUT_CHECK" ] || test-fetch-output || return 1
+ cat $TMPDIR/exec.out
+ test-epilog
}
# Syntax checks
pcont "<syntax> "
SCHECK=`eval echo $SYNTAX_CHECK`
echo "Syntax check command: $SCHECK"
- eval $SCHECK && return 0
- pend "Wrong syntax."
- echo "Wrong syntax."
- echo >>$PTSFILE "0 Wrong syntax."
- return 1
+ if ! eval $SCHECK 2>$TMPDIR/exec.out ; then
+ MSG=`head -1 $TMPDIR/exec.out`
+ if [ -z "$MSG" ] ; then MSG="Wrong syntax." ; fi
+ test-result 0 "$MSG"
+ fi
+ cat $TMPDIR/exec.out
}
# Output checks
[ -f $PDIR/$TEST.out ] && ln $PDIR/$TEST.out $TDIR/$TEST.ok
OCHECK=`eval echo $OUTPUT_CHECK`
echo "Output check command: $OCHECK"
- eval $OCHECK && return 0
- pend "Wrong answer."
- echo "Wrong answer."
- echo >>$PTSFILE "0 Wrong answer."
- return 1
+ if ! eval $OCHECK 2>$TMPDIR/exec.out ; then
+ MSG=`head -1 $TMPDIR/exec.out`
+ if [ -z "$MSG" ] ; then MSG="Wrong answer." ; fi
+ test-result 0 "$MSG"
+ fi
+ MSG=`head -1 $TMPDIR/exec.out`
+ if [ -z "$MSG" ] ; then MSG="OK" ; fi
+ test-result $POINTS_PER_TEST "$MSG"
}
# Setup of public commands
PDIR=$MO_PUBLIC/problems/$PROBLEM
SDIR=.
TDIR=~/.test
+ TMPDIR=~/.test
[ -d $PDIR ] || die "Unknown problem $PROBLEM"
pstart "Initializing... "
{
[ -f $PDIR/$TEST.in ] || die "Unknown test $TEST"
SRCN=$SDIR/$PROBLEM$TEST.out
- [ -f $SRCN ] || die "Output file $SRCN not found"
+ [ -f $SRCN ] || fatal "Output file $SRCN not found"
}
awk -F: </etc/passwd "{ gsub(\",.*\",\"\",\$5); OFS=\"\t\"; if (\$3 >= $CT_UID_MIN && \$3 <= $CT_UID_MAX) print $FORM; }"
else
if [ "$1" = --full ] ; then
- cat $CT_USER_LIST
+ cut -d ' ' -f 1,2 <$CT_USER_LIST
else
cut -d ' ' -f 1 <$CT_USER_LIST
fi
-# Configuration file for MO Evaluator
-# (c) 2001 Martin Mares <mj@ucw.cz>
+# Configuration file for the MO Evaluator
+# (c) 2001--2004 Martin Mares <mj@ucw.cz>
-# Directories and users
+# The root of the whole directory hierarchy
MO_ROOT=/aux/mo
+
+# User and group used by the evaluator itself
EVAL_USER=mo-eval
EVAL_GROUP=mo-eval
-TEST_USERS="mo-test1 mo-test2"
-
-# UID range assigned to contestants
-CT_UID_MIN=65100
-CT_UID_MAX=65199
-# If the contestants are not present in /etc/passwd on the evaluating machine,
-# we need a list of them (username<tab>fullname).
-#CT_USER_LIST=userlist
+# Test user for the sandbox. You can let mo-setup create more test users
+# and then run several evaluators in parallel, each in its own sandbox.
+# For testing, you can also leave TEST_USER undefined and run the sandbox
+# with EVAL_USER privileges, but beware, this is INSECURE.
+#TEST_USER=${TEST_USER:-mo-test1}
+TEST_USERS="mo-test1 mo-test2"
-# Test user for sandboxing
-TEST_USER=${TEST_USER:mo-test1}
+# Sometimes we need to get a list of all contestants (not in the evaluator
+# itself, but in various auxiliary scripts). In such cases we call mo-get-users,
+# which either scans /etc/passwd for users with UID in the following range,
+# or uses an explicit list of contestants CT_USER_LIST (username<tab>fullname).
+#CT_UID_MIN=65100
+#CT_UID_MAX=65199
+CT_USER_LIST=userlist
-### all of the following variables can be overriden in per-task config file
+### Per-task configuration variables (default values, override in per-task config)
-# Default task type (file or interactive)
-TASK_TYPE=file
+## Compiler settings:
# Known source file extensions
EXTENSIONS="c C cpp p pas"
# Sandbox initializaton commands for compilation
COMP_SANDBOX_INIT=
+# List of extra files needed for compilation. They are copied to the compiler
+# sandbox from the problem's directory.
+#COMP_EXTRAS="extras.h"
+
+## Tester settings (most can be overriden in per-test config):
+
+# The following variables are automatically set by the evaluator:
+# PROBLEM name of the problem
+# HDIR home directory of the evaluator (i.e., this file is $HDIR/config)
+# PDIR directory containing problem data
+# SDIR directory containing contestant's solution
+# TDIR directory containing testing results
+# TMPDIR directory containing temporary files
+# TEST name of the current test
+
+# Task type:
+# offline off-line task
+# interactive interactive task communicating via stdio with a testing program
+# open-data open-data task (i.e., we don't submit program, but output files)
+TASK_TYPE=file
+
+# I/O type (IO_TYPE sets defaults for IN_TYPE and OUT_TYPE)
+# file input from $PROBLEM.in, output to $PROBLEM.out (possible even for interactive tasks)
+# stdio input from stdin, output to stdout
+# none no input/output
+IO_TYPE=stdio
+#IN_TYPE=stdio
+#OUT_TYPE=stdio
+
+# A list of all tests
+TESTS="1 2 3 4 5 6 7 8 9 10"
+
+# A list of public tests (executed by submit and check scripts)
+SAMPLE_TESTS="0"
+
+# Number of points per test
+POINTS_PER_TEST=1
+
+# Time limit in seconds
+TIME_LIMIT=10
+
+# Memory limit in kilobytes
+MEM_LIMIT=16384
+
+# Command used to check output syntax (optional)
+# Returns exit code 1 if syntax is wrong, 0 if correct
+# fd1 is connect to evaluator log, feel free to log anything
+# fd2 is an optional one-line verdict
+#SYNTAX_CHECK='grep -v -- - $TDIR/$TEST.out'
+
+# Command used to check output correctness
+# Returns exit code 1 if output is incorrect, 0 if correct
+# fd1 is connect to evaluator log, feel free to log anything
+# fd2 is an optional one-line verdict
+# The checker can generate $TDIR/$TEST.pts to assign points irregularly
+OUTPUT_CHECK='diff -bBu $TDIR/$TEST.ok $TDIR/$TEST.out'
+
+# Checker for interactive tasks
+# Returns exit code 1 if test failed, 0 if passed
+# fd1 is connect to evaluator log, feel free to log anything
+# fd2 is an optional one-line verdict
+# The checker can generate $TDIR/$TEST.pts to assign points irregularly
+#IC_CHECK='$PDIR/checker $PDIR/$TEST.in $PDIR/$TEST.chk'
+
# Sandbox options used when testing
TEST_SANDBOX_OPTS='-a2 -f -m$MEM_LIMIT -t$TIME_LIMIT'
# -w for wall clock measuring
-# For stdio tasks append '-i$PROBLEM.in -o$PROBLEM.out'
+
+# Sandbox initialization commands
SANDBOX_INIT=
# The Evaluator -- Public Checking Script
-# (c) 2001 Martin Mares <mj@ucw.cz>
+# (c) 2001--2004 Martin Mares <mj@ucw.cz>
set -e
[ -n "$MO_PUBLIC" -a -d "$MO_PUBLIC" ] || { echo >&2 "MO_PUBLIC not set, giving up." ; exit 1 ; }
. $MO_PUBLIC/bin/lib
. $MO_PUBLIC/config
-[ -n "$1" ] || die "Usage: check <problem> [<file>]"
+[ -n "$1" ] || die "Usage: check <problem> [<test-number>]"
PROBLEM=$1
public-setup
. $PDIR/config
-PTSFILE=$TDIR/points
-if [ -n "$OPEN_DATA_PROBLEM" ] ; then
+
+function test-verdict
+{
+ pend "$2"
+ exit 0
+}
+
+if [ $TASK_TYPE == open-data ] ; then
[ -n "$2" ] || die "You need to specify test number for open data problems."
TEST=$2
- open-locate
pstart "Checking $TEST: "
+ open-locate
+ ln $SRCN $TDIR/$TEST.out
syntax-check
- pend "OK"
+ test-result 1 OK
else
- [ -z "$2" ] || die "No test number should be specified for normal problems."
+ [ -z "$2" ] || die "Test number should be given only for open data problems."
locate-source
compile
for TEST in $SAMPLE_TESTS ; do
+ (
pstart "Checking on sample input $TEST: "
test-run
syntax-check
output-check
- pend "OK"
+ )
done
fi
--- /dev/null
+# The Evaluator -- Public Status Script
+# (c) 2004 Martin Mares <mj@ucw.cz>
+
+set -e
+[ -n "$MO_PUBLIC" -a -d "$MO_PUBLIC" ] || { echo >&2 "MO_PUBLIC not set, giving up." ; exit 1 ; }
+. $MO_PUBLIC/bin/lib
+. $MO_PUBLIC/config
+
+[ -z "$1" ] || die "Usage: status"
+
+echo -e "Submitted tasks:\n"
+
+for PROBLEM in `cd $MO_PUBLIC/problems/ ; echo *` ; do
+ (
+ PDIR=$MO_PUBLIC/problems/$PROBLEM
+ SUBDIR=~/.submit/$PROBLEM
+ [ -f $PDIR/config ] || exit 0
+ echo -n "$PROBLEM: "
+ . $PDIR/config
+ if [ -d $SUBDIR ] ; then
+ if [ $TASK_TYPE == open-data ] ; then
+ for X in $TESTS ; do
+ [ -f $SUBDIR/$X.out ] && echo -n "$X " || echo -n "- "
+ done
+ echo
+ else
+ C=0
+ for X in $EXTENSIONS ; do
+ if [ -f $SUBDIR/$PROBLEM.$X ] ; then
+ echo -n `basename $SUBDIR/$PROBLEM.$X`
+ C=$(($C+1))
+ fi
+ done
+ if [ $C == 0 ] ; then
+ echo ---
+ elif [ $C == 1 ] ; then
+ echo
+ else
+ echo "INCONSISTENT (you probably modified $SUBDIR manually)"
+ fi
+ fi
+ else
+ echo ---
+ fi
+ )
+done
# The Evaluator -- Public Submit Script
-# (c) 2001 Martin Mares <mj@ucw.cz>
+# (c) 2001--2004 Martin Mares <mj@ucw.cz>
set -e
[ -n "$MO_PUBLIC" -a -d "$MO_PUBLIC" ] || { echo >&2 "MO_PUBLIC not set, giving up." ; exit 1 ; }
FORCE=1
shift
fi
-[ -n "$1" -o "$1" = "--help" ] || die "Usage: submit [--force] <problem> [<test>]"
+[ -n "$1" -o "$1" = "--help" ] || die "Usage: submit [--force] <problem> [<test-number>]"
PROBLEM=$1
public-setup
. $PDIR/config
-PTSFILE=$TDIR/points
+
+function test-verdict
+{
+ pend "$2"
+ [ $1 == 0 ] && exit 1 || exit 0
+}
+
FAILED=0
-if [ -n "$OPEN_DATA_PROBLEM" ] ; then
+if [ $TASK_TYPE == open-data ] ; then
[ -n "$2" ] || die "You need to specify test number for open data problems."
TEST=$2
+ pstart "Test case $TEST: "
open-locate
- syntax-check || FAILED=1
+ (
+ ln $SRCN $TDIR/$TEST.out
+ syntax-check
+ test-result 1 OK
+ ) || FAILED=1
else
- [ -z "$2" ] || die "No test number should be specified for normal problems."
+ [ -z "$2" ] || die "Test number should be given only for open data problems."
locate-source
compile
for TEST in $SAMPLE_TESTS ; do
+ (
pstart "Checking on sample input $TEST: "
- if test-run && syntax-check && output-check ; then
- pend "OK"
- else
- FAILED=$(($FAILED+1))
- fi
+ test-run
+ syntax-check
+ output-check
+ die "How could I get there? It's a buuuuug!"
+ ) || FAILED=$(($FAILED+1))
done
fi
-pstart "Submitting... "
+
if [ $FAILED != 0 ] ; then
if [ $FORCE != 0 ] ; then
- pcont "(tests failed, but --force given) "
+ pend "TESTS FAILED, but --force given, so submitting anyway."
else
- pend "TESTS FAILED Use submit --force if you really want to submit a wrong solution."
+ pend "TESTS FAILED. Nothing has been submitted!"
+ pend "Use submit --force if you really want to submit a WRONG solution."
exit 1
fi
fi
+
+pstart "Submitting... "
mkdir -p ~/.submit
-[ -z "$OPEN_DATA_PROBLEM" ] && rm -rf ~/.submit/$PROBLEM
-mkdir -p ~/.submit/$PROBLEM
-cp $SRCN ~/.submit/$PROBLEM/
+if [ $TASK_TYPE == open-data ] ; then
+ mkdir -p ~/.submit/$PROBLEM
+ cp $SRCN ~/.submit/$PROBLEM/$TEST.out
+else
+ rm -rf ~/.submit/$PROBLEM
+ mkdir -p ~/.submit/$PROBLEM
+ cp $SRCN ~/.submit/$PROBLEM/
+fi
pend "OK"