#!/usr/bin/env sh # test-abstraction-db-roundtrip.sh # # Reads each .ocda.db back into the abstraction, emits it as # .ssp, and requires the result to be byte identical to the .ssp written # from the same document. A database holds every language of its document, # so each language is asked for by name (--lang) and held against its own # .ssp, and a database of more than one language is required to refuse a # round trip that names none. # # What that proves: the two serialisations really do carry the same thing. # test-abstraction-db.sh counts fields and compares them; this reconstructs # the whole document from the database and holds it against the text. # # Usage (needs the sample documents, since both artefacts are generated): # SpinePOD=../../markup/sisudoc-spine-samples/markup/pod-samples/pod \ # ./test/test-abstraction-db-roundtrip.sh ./bin/spine-ldc # # Exit codes: # 0 every database re-emits its document's .ssp exactly # 1 one or more do not # 2 set-up problem set -e SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" SPINE_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" 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 SAMPLES_RAW="$SPINE_DIR/$SpinePOD" if [ -d "$SAMPLES_RAW" ]; then SAMPLES_DIR="$(cd "$SAMPLES_RAW" && pwd)" else SAMPLES_DIR="$SAMPLES_RAW" fi if [ ! -d "$SAMPLES_DIR" ]; then echo "ERROR: sample documents not found at $SAMPLES_DIR" >&2 exit 2 fi SPINE_BIN="${1:-}" if [ -z "$SPINE_BIN" ]; then if [ -x "$SPINE_DIR/result/bin/spine" ]; then SPINE_BIN="$SPINE_DIR/result/bin/spine" elif [ -x "$SPINE_DIR/bin/spine-ldc" ]; then SPINE_BIN="$SPINE_DIR/bin/spine-ldc" elif [ -x "$SPINE_DIR/bin/spine" ]; then SPINE_BIN="$SPINE_DIR/bin/spine" else echo "ERROR: spine binary not found. Specify path as argument." >&2 exit 2 fi fi OUT_DIR="$SCRIPT_DIR/current-db-roundtrip" rm -rf "$OUT_DIR" mkdir -p "$OUT_DIR" echo "spine binary: $SPINE_BIN" echo "samples: $SAMPLES_DIR" echo "Generating .ssp and .ocda.db ..." $SPINE_BIN --show-abstraction --ocda-db --skip-output \ --output="$OUT_DIR" "$SAMPLES_DIR"/* 2>&1 | tail -1 COUNT=0 DBS=0 FAILURES=0 # the database sits beside the pod (pod/.ocda.db), the .ssp files inside # it (pod//media/abstraction/..ssp). # # A database holds every language of its document, so one database answers # for as many .ssp files as the document has languages, and each has to be # asked for by name: --lang says which language to emit. With no language # named a database holding more than one refuses to choose, which is checked # too - a round trip that quietly emitted the first language would pass # against the first .ssp and say nothing about the other nine. for db in "$OUT_DIR"/pod/*.ocda.db; do [ -f "$db" ] || continue DBS=$((DBS + 1)) stem=$(basename "$db" .ocda.db) # the languages come from the .ssp files rather than from the database, so # that this script needs no sqlite3: each .ssp is a language the database # has to be able to re-emit. A language in the database with no .ssp beside # it is the other direction, and test-abstraction-db.sh checks that. langs=$(find "$OUT_DIR/pod" -name "$stem.*.ssp" 2>/dev/null \ | sed "s|.*/$stem\.||; s|\.ssp$||" | sort) if [ -z "$langs" ]; then echo "MISSING .ssp for $stem" FAILURES=$((FAILURES + 1)) continue fi n_langs=$(printf '%s\n' "$langs" | grep -c .) for lang in $langs; do base="$stem.$lang" ssp="$(find "$OUT_DIR/pod" -name "$base.ssp" 2>/dev/null | head -1)" COUNT=$((COUNT + 1)) if [ ! -f "$ssp" ]; then echo "MISSING .ssp for $base" FAILURES=$((FAILURES + 1)) continue fi if ! $SPINE_BIN --db-round-trip="$db" --lang="$lang" \ > "$OUT_DIR/from-db.ssp" 2> "$OUT_DIR/from-db.err"; then echo "ERROR: $base (spine exited non-zero)" head -3 "$OUT_DIR/from-db.err" FAILURES=$((FAILURES + 1)) continue fi if ! cmp -s "$ssp" "$OUT_DIR/from-db.ssp"; then echo "DIFFERS: $base ($(diff "$ssp" "$OUT_DIR/from-db.ssp" | grep -c '^[<>]') lines)" diff --unified=1 "$ssp" "$OUT_DIR/from-db.ssp" | head -12 echo " ..." FAILURES=$((FAILURES + 1)) fi done # more than one language and none named: it must refuse rather than pick if [ "$n_langs" -gt 1 ]; then if $SPINE_BIN --db-round-trip="$db" > /dev/null 2> /dev/null; then echo "$stem" echo " ACCEPTED a round trip with no language named, holding $n_langs" FAILURES=$((FAILURES + 1)) fi fi done rm -rf "$OUT_DIR" if [ "$FAILURES" -eq 0 ]; then echo "PASS: $DBS databases re-emit all $COUNT of their documents' .ssp exactly" exit 0 else echo "FAIL: $FAILURES of $COUNT do not" exit 1 fi