]> mj.ucw.cz Git - eval.git/blob - bin/lib
537bf58764c8d81ed514e65bf49d1c71b3967c97
[eval.git] / bin / lib
1 # The Evaluator -- Shell Function Library
2 # (c) 2001 Martin Mares <mj@ucw.cz>
3
4 # General settings
5 shopt -s dotglob
6
7 # Logging functions.
8 # File handles used: fd1=log, fd2=progress
9
10 function log-init
11 {
12         exec >>$TDIR/log
13         HAVE_LOG=1
14 }
15
16 function pstart
17 {
18         echo >&2 -n "$@"
19 }
20
21 function pcont
22 {
23         echo >&2 -n "$@"
24 }
25
26 function pend
27 {
28         echo >&2 "$@"
29 }
30
31 function die
32 {
33         echo >&2 "$@"
34         [ -n "$HAVE_LOG" ] && echo "Fatal error: $@"
35         exit 1
36 }
37
38 # Sandbox subroutines
39
40 function box-init
41 {
42         pstart "Preparing sandbox... "
43         [ -n "$TEST_USER" ] || die "TEST_USER not set. Please fix."
44         if [ $TEST_USER == $EVAL_USER ] ; then
45                 pcont "running locally (INSECURE), "
46                 BOXDIR=box
47                 BOXCMD=bin/box
48                 mkdir -p box
49         else
50                 pcont "used account $TEST_USER, "
51                 BOXDIR=$MO_ROOT/eval/$TEST_USER
52                 BOXCMD=bin/box-$TEST_USER
53         fi
54         [ -d $BOXDIR -a -f $BOXCMD ] || die "Sandbox set up incorrectly"
55         BOXCMD="$BOXCMD -c$BOXDIR"
56         echo "Sandbox directory: $BOXDIR"
57         echo "Sandbox command: $BOXCMD"
58         box-clean
59         pend "OK"
60 }
61
62 function box-clean
63 {
64         [ -n "$BOXCMD" ] || die "box-init not called"
65         rm -rf $BOXDIR/*
66 }
67
68 # Initialization of testing directories
69
70 function dir-init
71 {
72         pstart "Initializing... "
73         HDIR=.
74         PDIR=problems/$PROBLEM
75         SDIR=solutions/$CONTESTANT/$PROBLEM
76         TDIR=testing/$CONTESTANT/$PROBLEM
77         [ -d $PDIR ] || die "Problem $PROBLEM not known"
78         [ -d $SDIR ] || die "Solution of $PROBLEM not found"
79         mkdir -p $TDIR
80         rm -rf $TDIR
81         cp -a $SDIR $TDIR
82         cat >$TDIR/log <<EOF
83 Testing solution of $PROBLEM by $CONTESTANT
84 Test started at `date`
85 Contestant's solution directory: $SDIR
86 Problem directory: $PDIR
87 Testing directory: $TDIR
88 EOF
89         >$TDIR/points
90         pend "OK"
91 }
92
93 # Locating source file in SDIR, pass name in SRCN (without path) and extension in SRCEXT
94
95 function locate-source
96 {
97         pstart "Finding source... "
98         SBASE=${1:-$PROBLEM}
99         for a in $EXTENSIONS ; do
100                 if [ -f $SDIR/$SBASE.$a ] ; then
101                         [ -z "$SRCN" ] || die "Multiple source files found: $SDIR/$PROBLEM.$a and $SDIR/$SRCN. Please fix."
102                         SRCN=$SBASE.$a
103                         SRCEXT=$a
104                 fi
105         done
106         [ -n "$SRCN" ] || die "NOT FOUND"
107         pend $SRCN
108         echo "Found source file: $SDIR/$SRCN"
109 }
110
111 # Compilation (compile SDIR/SRCN with PDIR/EXTRAS to EXE=TDIR/PROBLEM)
112
113 function compile
114 {
115         pstart "Compiling... "
116         cp -a $SDIR/$SRCN $TDIR/$SRCN
117         if [ -n "$EXTRAS" ] ; then
118                 echo "Extras: $EXTRAS"
119                 for a in $EXTRAS ; do cp $PDIR/$a $TDIR/ ; done
120         fi
121         box-clean
122         for a in $SRCN $EXTRAS ; do cp $TDIR/$a $BOXDIR/ ; done
123         SRC=$SRCN
124         EXE=$PROBLEM
125         CCMD=COMP_$SRCEXT
126         CCMD=`eval echo ${!CCMD}`
127         COMP_SANDBOX_OPTS=`eval echo $COMP_SANDBOX_OPTS`
128         echo "Compiler command: $CCMD"
129         echo "Compiler sandbox options: $COMP_SANDBOX_OPTS"
130         eval $COMP_SANDBOX_INIT
131
132         echo "Compiler input files:"
133         ls -Al $BOXDIR
134         echo "Compiler output:"
135         if ! $BOXCMD $COMP_SANDBOX_OPTS -- $CCMD 2>$TDIR/compile.out ; then
136                 COMPILE_MSG="`cat $TDIR/compile.out`"
137                 pend "FAILED: $COMPILE_MSG"
138                 echo "$COMPILE_MSG"
139                 return 1
140         fi
141         cat $TDIR/compile.out
142         rm $TDIR/compile.out
143         echo "Compiler output files:"
144         ls -Al $BOXDIR
145         if [ ! -f $BOXDIR/$PROBLEM ] ; then
146                 pend "FAILED: Missing executable file"
147                 echo "Missing executable file"
148                 return 1
149         fi
150         EXE=$TDIR/$PROBLEM
151         cp -a $BOXDIR/$PROBLEM $EXE
152         echo "Compiled OK, result copied to $EXE"
153         pend "OK"
154 }
155
156 # Running of test program according to current task type
157
158 function test-run
159 {
160         test-run-$TASK_TYPE
161 }
162
163 # Running of test program with file input/output
164
165 function test-run-file
166 {
167         pcont "<init> "
168         box-clean
169         echo "Executable file: $TDIR/$PROBLEM"
170         cp $TDIR/$PROBLEM $BOXDIR/
171         echo "Input: $TDIR/$PROBLEM"
172         ln $PDIR/$TEST.in $TDIR/$TEST.in
173         cp $PDIR/$TEST.in $BOXDIR/$PROBLEM.in
174         eval $SANDBOX_INIT
175         echo "Input files:"
176         ls -Al $BOXDIR
177
178         pcont "<run> "
179         echo "Timeout: $TIME_LIMIT s"
180         echo "Memory: $MEM_LIMIT KB"
181         BOXOPTS=`eval echo $TEST_SANDBOX_OPTS`
182         echo "Sandbox options: $BOXOPTS"
183         if ! $BOXCMD $BOXOPTS -- ./$PROBLEM 2>$TDIR/exec.out ; then
184                 TEST_MSG="`head -1 $TDIR/exec.out`"
185                 pend "$TEST_MSG"
186                 cat $TDIR/exec.out
187                 rm $TDIR/exec.out
188                 echo >>$PTSFILE "0 $TEST_MSG"
189                 return 1
190         fi
191         cat $TDIR/exec.out
192         rm $TDIR/exec.out
193         test-fetch-output || return 1
194 }
195
196 function test-fetch-output
197 {
198         echo "Output files:"
199         ls -Al $BOXDIR
200         if [ ! -f $BOXDIR/$PROBLEM.out ] ; then
201                 pend "No output file."
202                 echo "No output file."
203                 echo >>$PTSFILE "0 No output."
204                 return 1
205         fi
206         cp $BOXDIR/$PROBLEM.out $TDIR/$TEST.out
207 }
208
209 # Running of interactive test programs
210
211 function test-run-interactive
212 {
213         pcont "<init> "
214         box-clean
215         echo "Executable file: $TDIR/$PROBLEM"
216         cp $TDIR/$PROBLEM $BOXDIR/
217         echo "Input: $TDIR/$PROBLEM"
218         ln $PDIR/$TEST.in $TDIR/$TEST.in
219         cp $PDIR/$TEST.in $BOXDIR/$PROBLEM.in
220         eval $SANDBOX_INIT
221         echo "Input files:"
222         ls -Al $BOXDIR
223
224         pcont "<run> "
225         echo "Timeout: $TIME_LIMIT s"
226         echo "Memory: $MEM_LIMIT KB"
227         BOXOPTS=`eval echo $TEST_SANDBOX_OPTS`
228         echo "Sandbox options: $BOXOPTS"
229         ICCMD=`eval echo $IA_CHECK`
230         echo "Interactive checker: $ICCMD"
231         if ! $HDIR/bin/iwrapper $BOXCMD $BOXOPTS -- ./$PROBLEM @@ $ICCMD 2>$TDIR/exec.out ; then
232                 TEST_MSG="`head -1 $TDIR/exec.out`"
233                 pend "$TEST_MSG"
234                 cat $TDIR/exec.out
235                 rm $TDIR/exec.out
236                 echo "$TEST_MSG"
237                 echo >>$PTSFILE "0 $TEST_MSG"
238                 return 1
239         fi
240         cat $TDIR/exec.out
241         rm $TDIR/exec.out
242         [ -z "$OUTPUT_CHECK" ] || test-fetch-output || return 1
243 }
244
245 # Syntax checks
246
247 function syntax-check
248 {
249         [ -n "$SYNTAX_CHECK" ] || return 0
250         pcont "<syntax> "
251         SCHECK=`eval echo $SYNTAX_CHECK`
252         echo "Syntax check command: $SCHECK"
253         eval $SCHECK && return 0
254         pend "Wrong syntax."
255         echo "Wrong syntax."
256         echo >>$PTSFILE "0 Wrong syntax."
257         return 1
258 }
259
260 # Output checks
261
262 function output-check
263 {
264         [ -n "$OUTPUT_CHECK" ] || return 0
265         pcont "<check> "
266         [ -f $PDIR/$TEST.out ] && ln $PDIR/$TEST.out $TDIR/$TEST.ok
267         OCHECK=`eval echo $OUTPUT_CHECK`
268         echo "Output check command: $OCHECK"
269         eval $OCHECK && return 0
270         pend "Wrong answer."
271         echo "Wrong answer."
272         echo >>$PTSFILE "0 Wrong answer."
273         return 1
274 }
275
276 # Setup of public commands
277
278 function public-setup
279 {
280         HDIR=$MO_PUBLIC
281         PDIR=$MO_PUBLIC/problems/$PROBLEM
282         SDIR=.
283         TDIR=~/.test
284         [ -d $PDIR ] || die "Unknown problem $PROBLEM"
285
286         pstart "Initializing... "
287         mkdir -p $TDIR
288         rm -rf $TDIR/*
289         BOXDIR=~/.box
290         mkdir -p $BOXDIR
291         rm -rf $BOXDIR/*
292         BOXCMD="$MO_PUBLIC/bin/box -c$BOXDIR"
293         exec >log
294         pend "OK  (see 'log' for details)"
295 }
296
297 # Locate output of open data problem, test case TEST
298
299 function open-locate
300 {
301         [ -f $PDIR/$TEST.in ] || die "Unknown test $TEST"
302         SRCN=$SDIR/$PROBLEM$TEST.out
303         [ -f $SRCN ] || die "Output file $SRCN not found"
304 }