blob: cb245a46ed4d270d14c2e2c6edcebba3fce28e0b [file] [log] [blame]
#!/bin/sh
MYDIR=$(dirname "$0")
sequence=$1
result=$2
cd "$MYDIR"
await()
{
while [ ! -e "llt_$1.tmp" ]; do
:
done
}
run()
{
./loglinear ./loglinear_test "$1"
touch "llt_e$1.tmp"
}
check_sequence()
{
while read header magic val; do
echo "check: $header $magic $val"
if [ "$magic" = "START" -o "$magic" = "STOP" ]; then
if [ "$val" = "$1" ]; then
shift
else
echo "FAILED: expected '$1', got '$val'" >&2
return 1
fi
fi
done
if [ $# != 0 ]; then
echo "FAILED: remaining sequence not found: '$*'" >&2
return 2
fi
}
main()
{
# This requires a bit of explanation.
#
# First, remember the goal: we want to print logs that pass first, so that
# failures end up near the end. And "inner" failures come after "outer"
# failures: if a parent and his child both fail, we mostly care about the
# child, because the parent probably only failed because the child failed,
# and the child will have the most specific error message. Other than this
# restriction, we want to generally keep things in chronological order.
#
# So our test works like this:
# 1 runs 2a/2b. 2a runs 3a/3b. 2b runs 3c.
# We print logs from steps that succeed first: that's 2b, 3a, 3b.
# 2b is dragged downwards, however, because its child, 3c, fails, so the
# other two are printed before it.
# So 3a and 3b first. 3b is set to wait for 3a, so 3a prints before 3b.
#
# 1, 2a, and 3c all fail. 3c is owned by 2b, though, which didn't fail,
# so 2b is not as important as 2a, which failed. Thus we print 2b
# before 2a. We print parents before their failing children, so 2b
# comes before 3c.
# Now 1 and 2a are left. They both failed, and 1 is 2a's parent, so
# it comes first, followed by 2a.
#
# Obviously, right?
EXPECT="s3a e3a s3b e3b s2b e2b s3c e3c s1 e1 s2a e2a"
echo
echo
rm -f llt_*.tmp
(
echo -n "MAIN "
run 1 2>&1
) | check_sequence $EXPECT
}
echo "START s$sequence"
touch "llt_s$sequence.tmp"
rv=101
case "$sequence" in
1) run 2a & (await s2a; run 2b) & wait; rv=1 ;;
2a) run 3a & (await s3a; run 3b) & wait; rv=2 ;;
2b) run 3c; rv=0 ;;
3a) rv=0 ;;
3b) await e3a; rv=0 ;;
3c) rv=5 ;;
"")
# we were run with no parameters: initial startup.
# Run main() several times in case the test has race conditions.
if main && main && main && main && main; then
echo
echo "Passed!"
exit 0
else
rv=$?
echo
echo "Failed: code $rv"
exit $rv
fi
;;
*)
echo "Unexpected sequence number: '$sequence'" >&2
exit 98
;;
esac
echo "STOP e$sequence"
exit $rv