aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/run-tests.sh
blob: 85bbf03f4e4b2b70694994fae4fa7cad55d19abe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#!/usr/bin/env sh
# run-tests.sh
#
# Runs the abstraction tests in sequence and reports one line each.
#
# Usage:
#   SpinePOD=../../markup/sisudoc-spine-samples/markup/pod-samples/pod \
#     ./test/run-tests.sh ./bin/spine-ldc
#
# sqlite3 is needed by two of the four. If it is not on PATH the script says
# so and re-runs itself inside a nix shell that has it, so this works:
#   SpinePOD=... ./test/run-tests.sh ./bin/spine-ldc
#
# Exit codes:
#   0  every test passed
#   n  the number of tests that failed
#   2  set-up problem (no $SpinePOD, no binary)
#
# Order, and what depends on what:
#
#   1 test-abstraction-ssp.sh            the abstraction has not changed
#   2 test-abstraction-ssp-roundtrip.sh  the .ssp can be read back whole
#   3 test-abstraction-db.sh             the two serialisations agree
#   4 test-abstraction-db-roundtrip.sh   the .db can be read back whole
#
# None of them calls another, and each can be run on its own. The order
# matters only for reading the result:
#
#   - 1 is first because it is the one that says whether the abstraction
#     itself moved. If it fails, the others are answering a different
#     question than you think, and its failure is the one to look at.
#   - 2 reads the committed reference set, so it is only a statement about
#     the current binary if 1 passes. Run together, they say: the abstraction
#     is unchanged, and this binary can read that abstraction back.
#   - 3 and 4 generate both artefacts themselves and depend on nothing
#     committed. Since the database is built from the .ssp, they are checks
#     on the reader rather than on two independent writers.

set -e

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SPINE_BIN="${1:-}"

if [ -z "$SpinePOD" ]; then
  echo "ERROR: \$SpinePOD is not set." >&2
  echo "  e.g. SpinePOD=../../markup/sisudoc-spine-samples/markup/pod-samples/pod" >&2
  exit 2
fi

if ! command -v sqlite3 > /dev/null 2>&1; then
  if command -v nix > /dev/null 2>&1; then
    echo "sqlite3 not on PATH, re-running inside nix shell \"nixpkgs#sqlite\""
    exec nix shell "nixpkgs#sqlite" -c "$0" "$@"
  fi
  echo "ERROR: sqlite3 not on PATH and nix not available." >&2
  exit 2
fi

TESTS="test-abstraction-ssp.sh
test-abstraction-ssp-roundtrip.sh
test-abstraction-db.sh
test-abstraction-db-roundtrip.sh"

PASSED=0
FAILED=0
RESULTS=""
LOG="${TMPDIR:-/tmp}/spine-run-tests.$$"

for t in $TESTS; do
  printf '%s\n' "── $t"
  # the status has to be the test's, not the last command of a pipeline:
  # "cmd | sed" reports sed's status, which is always 0, and a harness that
  # cannot fail is worse than no harness
  if sh "$SCRIPT_DIR/$t" $SPINE_BIN > "$LOG" 2>&1; then
    sed 's/^/   /' "$LOG"
    PASSED=$((PASSED + 1))
    RESULTS="$RESULTS
  ok    $t"
  else
    sed 's/^/   /' "$LOG"
    FAILED=$((FAILED + 1))
    RESULTS="$RESULTS
  FAIL  $t"
  fi
done
rm -f "$LOG"

echo ""
echo "summary:$RESULTS"
echo ""
if [ "$FAILED" -eq 0 ]; then
  echo "PASS: $PASSED of $PASSED"
  exit 0
else
  echo "FAIL: $FAILED of $((PASSED + FAILED))"
  exit "$FAILED"
fi