client: Unbreak standalone build
[empserver] / tests / test-common.sh
1 export EMPIREHOST=127.0.0.1 LOGNAME=tester
2
3 if [ -x ./config.status ] && ./config.status --version | grep -q '^Wolfpack Empire'
4 then :
5 else echo "$0: Must be run in root of build tree" >&2; exit 1
6 fi
7
8 test=${0##*/}
9 test=${test%-test}
10
11 failed=
12 trap 'if [ "$pid" ]; then kill -9 "$pid" 2>/dev/null || true; fi; [ "$failed" ] && exit 1' EXIT
13
14 # Abbreviations
15 testdir="$srcdir/tests/$test"
16 econfig=sandbox/etc/empire/econfig
17 schedule=sandbox/etc/empire/schedule
18 data=sandbox/var/empire
19 empdump="src/util/empdump -e $econfig"
20 files="src/util/files -e $econfig"
21 fairland="src/util/fairland -e $econfig"
22
23 # GNU libc memory allocation checking, see mallopt(3)
24 # $RANDOM isn't portable
25 malloc_perturb=${EMPIRE_CHECK_MALLOC_PERTURB:-$(perl -e 'print int(rand(255))')}
26 env="MALLOC_CHECK_=3 MALLOC_PERTURB_=$malloc_perturb"
27
28 empthread=`sed -n 's/empthread *:= *\(.*\)/\1/p' <GNUmakefile`
29 warn_empthread=y
30
31 check_empthread()
32 {
33     if [ "$warn_empthread" ] && [ "$empthread" != "LWP" ]
34     then
35         echo "Warning: test not expected to work with thread package $empthread!" >&2
36         warn_empthread=
37     fi
38 }
39
40 create_sandbox()
41 {
42     rm -rf sandbox
43     mkdir -p sandbox/etc/empire sandbox/share/empire/builtin $data
44     echo $malloc_perturb >sandbox/malloc-perturb
45     touch $schedule
46     cat >$econfig <<EOF
47 data "../../var/empire"
48 info "../../../../info.nr"
49 builtin "../../share/empire/builtin"
50 listen_addr "$EMPIREHOST"
51 keep_journal 2
52 GODNEWS 0
53 running_test_suite 1
54 EOF
55     cp `perl "$srcdir"/src/scripts/ls-sources.pl "$srcdir"/src/lib/global '\.config$'` sandbox/share/empire/builtin
56 }
57
58 copy_tables()
59 {
60     local t
61
62     for t
63     do [ -e sandbox/etc/empire/"$t".config ] || cp "$srcdir"/src/lib/global/$t.config sandbox/etc/empire
64     done
65 }
66
67 # sed -i isn't portable...
68 sed_i()
69 {
70     local script="$1"
71     shift
72     for i
73     do sed "$script" "$i" >sandbox/$$ && mv sandbox/$$ "$i"
74     done
75 }
76
77 customize()
78 {
79     local key
80     for key
81     do
82         case $key in
83         big-city)
84             copy_tables sect
85             sed_i '/"c" .* "capital"/d;/^#.*"c" .* "city"/s/^#/ /;/"c" .* norm/d;/^#.*"c" .* cana/s/^#/ /' sandbox/etc/empire/sect.config
86             ;;
87         trade-ship)
88             copy_tables ship
89             sed_i '/"ts   trade ship"//^#/ /' sandbox/etc/empire/ship.config
90         esac
91     done
92     echo "custom_tables \"`cd sandbox/etc/empire && echo *.config`\"" >>$econfig
93 }
94
95 run_and_cmp()
96 {
97     run "$@"
98     cmp_run "$1"
99 }
100
101 run()
102 {
103     local name=$1 ret
104     shift
105     set +e
106     env $env "$@" >>sandbox/$name.out 2>>sandbox/$name.err
107     ret=$?
108     set -e
109     echo $ret >>sandbox/$name.status
110 }
111
112 now()
113 {
114     # date +%s isn't portable...
115     perl -e 'printf "%s\n", time'
116 }
117
118 start_server()
119 {
120     local pidfile=$data/server.pid
121     local timeout
122
123     #
124     # Currently expected to work only with thread package LWP,
125     # because:
126     #
127     # - Thread scheduling is reliably deterministic only with LWP
128     # - Shell builtin kill appears not to do the job in MinGW
129     # - The Windows server tries to run as service when -d isn't
130     #   specified
131     # - The Windows server does not implement -E crash-dump
132     #
133     # TODO address these shortcomings.
134     #
135     check_empthread
136
137     pid=
138     env $env src/server/emp_server -e $econfig -R 1 -s -E crash-dump
139     timeout=$((`now`+5))
140     until pid=`cat $pidfile 2>/dev/null` && [ -n "$pid" ]
141     do
142         if [ `now` -gt $timeout ]
143         then
144             echo "Timed out waiting for server to create $pidfile" >&2
145             exit 1
146         fi
147     done
148     while src/client/empire red herring 2>&1 | grep -q "Connection refused"
149     do
150         if [ `now` -gt $timeout ]
151         then
152             echo "Timed out waiting for server to accept connections" >&2
153             exit 1
154         fi
155     done
156 }
157
158 stop_server()
159 {
160     local timeout
161     kill "$pid"
162     timeout=$((`now`+5))
163     while kill -0 "$pid" 2>/dev/null
164     do
165         if [ `now` -gt $timeout ]
166         then
167             echo "Timed out waiting for server to terminate" >&2
168             exit 1
169         fi
170     done
171 }
172
173 feed_input()
174 {
175     c=$1
176     r=$2
177     shift 2
178     sed '/^|/d' "$@" | src/client/empire "$c" "$r" >/dev/null
179 }
180
181 feed_files()
182 {
183     local i
184
185     for i
186     do
187         c="${i##*/*-}"
188         r=`echo $c | sed 's/^POGO$/peter/'`
189         feed_input "$c" "$r" "$i"
190     done
191 }
192
193 feed_dir()
194 {
195     feed_files `perl "$srcdir"/src/scripts/ls-sources.pl "$@" '/[0-9][0-9]-[^/]*$'`
196 }
197
198 begin_test()
199 {
200     $files -f >/dev/null
201     local xd=
202     case "$1" in
203     *.xdump)
204         xd="$1"
205         $empdump -i "$xd"
206         shift
207         ;;
208     esac
209     if [ -z "$xd" ] || [ "$#" -ne 0 ]
210     then
211         cp -r $data/tel $data/empty.tel
212         start_server
213         if [ "$#" -eq 0 ]
214         then feed_input POGO peter
215         else feed_files "$@"
216         fi
217         echo 'edit c * ?tgms>0 t 0' | feed_input POGO peter
218         stop_server
219         mv $data/tel $data/setup.tel
220         mv $data/empty.tel $data/tel
221         mv $data/news $data/setup.news
222         >$data/news
223         mv $data/lostitems $data/setup.lostitems
224         >$data/lostitems
225         mv $data/journal.log $data/setup.journal.log
226         normalize sandbox/var/empire/setup.journal.log
227         mv $data/server.log $data/setup.server.log
228         normalize sandbox/var/empire/setup.server.log
229     fi
230     start_server
231 }
232
233 end_test ()
234 {
235     stop_server
236     $empdump -x >sandbox/final.xdump
237 }
238
239 cmp_run()
240 {
241     local i j exp
242
243     for i
244     do
245         for j in status out err
246         do cmp_out "$i.$j"
247         done
248     done
249 }
250
251 cmp_logs_xdump()
252 {
253     cmp_out var/empire/server.log var/empire/journal.log final.xdump
254 }
255
256 cmp_out()
257 {
258     local i
259
260     for i
261     do cmp_out1 "$i"
262     done
263 }
264
265 normalize()
266 {
267     local act="$1"
268     local nrm="${2-sandbox/normalized-${1##*/}}"
269
270     case "$act" in
271     *journal.log)
272         perl "$srcdir"/tests/normalize.pl -j "$act" ;;
273     *server.log)
274         perl "$srcdir"/tests/normalize.pl -s "$act" ;;
275     *.xdump)
276         perl "$srcdir"/tests/normalize.pl "$act" ;;
277     *.err)
278         perl -pe 's/\s+$/\n/;' -e "s,\Q$srcdir/tests\E,tests," "$act" ;;
279     *)
280         perl -pe 's/\s+$/\n/;' "$act" ;;
281     esac >"$nrm"
282 }
283
284 cmp_out1()
285 {
286     local i=$1 master="${2-$testdir/${1##*/}}"
287     local exp="$master"
288     local act="sandbox/$i"
289     local nrm="sandbox/normalized-${i##*/}"
290
291     if [ ! -e "$exp" ]
292     then
293         case "$i" in
294         *.status)
295             exp=sandbox/ok.status
296             echo 0 >sandbox/ok.status
297             ;;
298         *)
299             [ ! -e "$act" ] && return
300             exp=/dev/null
301             ;;
302         esac
303     fi
304
305     normalize "$act" "$nrm"
306     if diff -u "$exp" "$nrm" >"$nrm.diff"
307     then
308         echo "$i OK"
309     elif [ "$EMPIRE_CHECK_ACCEPT" ]
310     then
311         echo "$i CHANGED"
312         cp "$nrm" "$master"
313     else
314         failed=y
315         echo "$i FAIL"
316     fi
317 }