###--------------------------------------------------------------------------
### Scaffolding for running a TrIPE server.
+## WITH_TRIPEX(dir, args, body)
m4_define([WITH_TRIPEX], [
+## If this directory doesn't exist then Bad Things will happen.
+if test ! -d $1; then
+ echo >&2 "server directory \`$1' doesn't exist"
+ exit 99
+fi
+
## Remove the status file. This is how we notice that the server's died.
rm -f $1/server-status
> $1/expected-server-output
> $1/expected-server-errors
-## Keep Autotest writes crap to standard output, which we don't want going to
-## the server. So keep a copy of the standard output, do the pipe, and
-## recover the old stdout inside the group.
+## Autotest writes crap to standard output, which we don't want going to the
+## server. So keep a copy of the standard output, do the pipe, and recover
+## the old stdout inside the group.
exec 3>&1
{ (
exec 1>&3 3>&-
## Wait for the socket to appear. Watch for the server crashing during
## initialization. Busy waiting is evil, but it's the best I can do and
## not sleep for ages. (Yes, a second on each test group is a long time.)
-while test ! -r $1//server-status && test ! -S $1/admin; do :; done
+while test ! -r $1/server-status && test ! -S $1/admin; do :; done
+
+## Make the port number availale.
+AT_CHECK([TRIPECTL -d$1 PORT],, [stdout])
+mv stdout $1/port
## Test body...
$3
-## End of the test, now run the server.
+## End of the test, now run the server. There's an awful hack here. If a
+## process running under strace exits with a signal, then strace will kill
+## itself with the same signal -- and therefore clobber the original
+## process's core file. So we arrange to run strace in one directory and
+## have the child process run in another.
) && :; } | {
cd $1
+ mkdir -p strace-hack/
echo TRIPE $2 >&2
- strace -f -o tripe.trace TRIPE $2 >server-output 2>server-errors
+ (cd strace-hack/
+ ulimit -c hard >/dev/null 2>&1
+ strace -f -o ../tripe.trace \
+ TRIPE -d.. $2 >../server-output.full 2>../server-errors)
stat=$?
echo $stat >server-status
if test $stat -ne 0; then
echo "exit status: $stat" >>server-errors
fi
+
+ ## We interrupt this relatively sensible macro for an especially awful
+ ## hack. The tripe server emits warnings which are often caused by lack of
+ ## synchronization between two peers. These are harmless and shouldn't
+ ## cause test failures. But we shouldn't just trim out all messages that
+ ## look like the spurious ones: if they appear when we're not expecting
+ ## them, that's bad and they should properly cause a test failure.
+ ##
+ ## So we use the WARN command to insert magic directives into the server's
+ ## message stream. The directives begin with `WARN USER test'; remaining
+ ## tokens may be as follows.
+ ##
+ ## PUSH Introduce a new layer of nesting. Settings between
+ ## this PUSH and the matching POP will be forgotten
+ ## following the POP.
+ ##
+ ## POP End a layer of nesting. See PUSH above.
+ ##
+ ## IGNORE tokens Ignore lines which begin with the tokens.
+ ##
+ ## Token comparison isn't done very well, but it's good enough for these
+ ## purposes.
+ ##
+ ## We also trim out trace lines here, since it's useful to produce them for
+ ## debugging purposes and changing or introducing more of them shouldn't
+ ## cause failures.
+ awk '
+ BEGIN {
+ sp = 0;
+ npat = 0;
+ }
+ $[]1 == "TRACE" { next; }
+ $[]1 == "WARN" && $[]2 == "USER" && $[]3 == "test" {
+ if ($[]4 == "PUSH")
+ npatstk[[sp++]] = npat;
+ else if ($[]4 == "IGNORE") {
+ s = "";
+ p = "";
+ for (i = 5; i <= NF; i++) {
+ p = p s $[]i;
+ s = " ";
+ }
+ pat[[npat++]] = p;
+ } else if ($[]4 == "POP")
+ npat = npatstk[[--sp]];
+ next;
+ }
+ {
+ for (i = 0; i < npat; i++) {
+ n = length(pat[[i]]);
+ if (substr($[]0, 0, n) == pat[[i]])
+ next;
+ }
+ print $[]0;
+ }
+ ' server-output.full >server-output
}
exec 3>&-
[expout], [experr])
])
+## WITH_TRIPE(args, body)
m4_define([WITH_TRIPE], [WITH_TRIPEX([.], [$1], [$2])])
+## WITH_2TRIPES(adir, bdir, bothargs, aargs, bargs, body)
m4_define([WITH_2TRIPES],
[WITH_TRIPEX([$1], [$3 $4], [WITH_TRIPEX([$2], [$3 $5], [$6])])])
+## COMMS_EPING(adir, aname, bdir, bname)
+m4_define([COMMS_EPING], [
+ AT_CHECK([TRIPECTL -d$1 EPING $4],, [ignore])
+ AT_CHECK([TRIPECTL -d$3 EPING $2],, [ignore])
+])
+
+## COMMS_SLIP(adir, aname, bdir, bname)
+m4_define([COMMS_SLIP], [
+ AT_CHECK([echo "from $1" | USLIP -p $1/$4])
+ AT_CHECK([USLIP -g $3/$2],, [from $1[]nl])
+ AT_CHECK([echo "from $3" | USLIP -p $3/$2])
+ AT_CHECK([USLIP -g $1/$4],, [from $3[]nl])
+])
+
+## AWAIT_KXDONE(adir, aname, bdir, bname, body)
+m4_define([AWAIT_KXDONE], [
+
+ ## Ignore some reports caused by races.
+ TRIPECTL -d$3 WARN test PUSH
+ TRIPECTL -d$3 WARN test IGNORE WARN KX $2 incorrect cookie
+ TRIPECTL -d$3 WARN test IGNORE WARN KX $2 unexpected pre-challenge
+
+ ## Watch for the key-exchange completion announcement in the background.
+ COPROCESSES([wait-$1], [
+ echo WATCH +n
+ while read line; do
+ set x $line; shift
+ echo >&2 ">>> $line"
+ case "$[]1:$[]2:$[]3" in
+ OK::) ;;
+ NOTE:KXDONE:$4) break ;;
+ NOTE:*) ;;
+ *) exit 63 ;;
+ esac
+ done
+ ], [
+ TRIPECTL -d$1
+ ]) & waiter_$1=$!
+
+ $5
+
+ ## Collect the completion announcement.
+ wait $waiter_$1; waitrc=$?
+ AT_CHECK([echo $waitrc],, [0[]nl])
+
+ ## Be interested in key-exchange warnings again.
+ TRIPECTL -d$4 WARN test POP
+])
+
+## ESTABLISH(adir, aname, aopts, bdir, bname, bopts)
+m4_define([ESTABLISH], [
+
+ ## Set up the establishment.
+ AWAIT_KXDONE([$1], [$2], [$4], [$5], [
+ AT_CHECK([TRIPECTL -d$1 ADD -cork $6 $5 INET 127.0.0.1 $(cat $4/port)])
+ AT_CHECK([TRIPECTL -d$4 ADD $3 $2 INET 127.0.0.1 $(cat $1/port)])
+ ])
+
+ ## Check transport pinging.
+ AT_CHECK([TRIPECTL -d$1 PING $5],, [ignore])
+ AT_CHECK([TRIPECTL -d$4 PING $2],, [ignore])
+
+ ## Check communication works.
+ COMMS_EPING([$1], [$2], [$4], [$5])
+ COMMS_SLIP([$1], [$2], [$4], [$5])
+])
+
###--------------------------------------------------------------------------
### Very unpleasant coprocess handling.
## TRIPECTL_INTERACT(ARGS, SHELLSTUFF)
m4_define([TRIPECTL_INTERACT], [
- exec 3<&1
- COPROCESSES([client], [exec 4>&1 1>&3 $2], [TRIPECTL $1])
+ exec 3>&1
+ COPROCESSES([client], [exec 4>&1 1>&3 $1], [TRIPECTL $2])
])
## TRIPECTL_COMMAND(CMD, EXPECT)
for i in alice bob; do (mkdir $i; cd $i; SETUPDIR([ec])); done
WITH_2TRIPES([alice], [bob], [-nslip], [-talice], [-tbob], [
-
- AT_CHECK([TRIPECTL -dalice PORT],, [stdout])
- mv stdout alice/port
-
- AT_CHECK([TRIPECTL -dbob PORT],, [stdout])
- mv stdout bob/port
-
- ## Watch for the key-exchange completion announcement, and then exit.
- COPROCESSES([wait], [
- echo WATCH +n
- while read line; do
- case "$line" in
- OK) ;;
- "NOTE KXDONE "*) break ;;
- NOTE*) ;;
- *) exit 63 ;;
- esac
- done
- ], [
- TRIPECTL -dalice
- ]) &
-
- ## Don't panic if you don't see the unexpected-source warning. It happens
- ## for me, but it's not important either way.
- AT_CHECK([TRIPECTL -dalice ADD bob INET 127.0.0.1 $(cat bob/port)])
- echo >>bob/expected-server-output \
- "WARN PEER - unexpected-source INET 127.0.0.1 $(cat alice/port)"
- AT_CHECK([TRIPECTL -dbob ADD -key alice not-alice \
- INET 127.0.0.1 $(cat alice/port)])
-
- ## Check transport pinging.
- AT_CHECK([TRIPECTL -dalice PING bob],, [ignore])
- AT_CHECK([TRIPECTL -dbob PING not-alice],, [ignore])
-
- ## Wait for the completion announcement.
- wait
-
- ## Check encrypted pinging.
- AT_CHECK([TRIPECTL -dalice EPING bob],, [ignore])
- AT_CHECK([TRIPECTL -dbob EPING not-alice],, [ignore])
-
- ## Check that packets can flow from one to the other.
- AT_CHECK([echo "from alice" | USLIP -p alice/bob])
- AT_CHECK([USLIP -g bob/not-alice],, [from alice[]nl])
-
- AT_CHECK([echo "from bob" | USLIP -p bob/not-alice])
- AT_CHECK([USLIP -g alice/bob],, [from bob[]nl])
+ ESTABLISH([alice], [not-alice], [-key alice],
+ [bob], [bob], [])
])
AT_CLEANUP
read line
case "$line" in
OK)
- ;;
+ ;;
*)
- echo >&2 "SVCCLAIM failed: $line"
+ echo >&2 "SVCCLAIM failed: $line"
exit 1
;;
esac
case "$[]1,$[]2,$[]3,$[]4" in
SVCCANCEL,$tag,,) break ;;
SVCJOB,*,test,ESCAPE)
- echo >&2 "attempt to escape from alkatraz"
+ echo >&2 "attempt to escape from alkatraz"
exit 1
;;
esac