#!/bin/sh # Run augeas's upstream test suite -- everything tests/Makefile declares in # TESTS = $(check_SCRIPTS) $(check_PROGRAMS) -- and report one PASS:/FAIL:/SKIP: # line each, which is the protocol ptest-runner reads. # # THIS IS NOT `make check`, AND IT CANNOT BE. automake's check-TESTS needs make, # a shell test-driver and the whole build tree; the image ships none of those and # the tree does not survive packaging. What automake would do with these entries # is exactly what the loop below does -- run each one, exit status is the verdict, # with 77 meaning skip and 99 meaning a harness error -- so the suite's own # semantics are preserved while the harness around it is not. # # THE ENVIRONMENT IS UPSTREAM'S OWN. tests/Makefile.am sets TESTS_ENVIRONMENT to # PATH=$(abs_top_builddir)/src:$PATH, abs_top_builddir, abs_top_srcdir and # LANG=en_US, and every script and every C programme in the suite reads those # four and nothing else. They are reproduced here exactly, with the automake # srcdir/builddir split put to its proper use: # # abs_top_srcdir = the ptest directory. Read-only, and it holds precisely # what a source tree holds for these tests -- tests/root, # tests/modules, tests/test-augtool, xpath.tests, # run.tests, and a `lenses` symlink at the INSTALLED lens # directory (${datadir}/augeas/lenses/dist), so the 224 # lens cases parse the lenses the image actually ships. # abs_top_builddir = a fresh writable scratch directory under $TMPDIR. Every # test that writes does so under $abs_top_builddir/build/, # which is upstream's own convention, so nothing needs a # writable ptest directory. The deployed rootfs is read-only # at browser runtime, so this is not merely tidiness. # # $abs_top_builddir/src is populated with symlinks to the installed augtool, # augparse and augmatch. That is not a convenience: test-interpreter.sh resolves # AUGPARSE as ${abs_top_builddir}/src/augparse by path, not through PATH. # # THE GROUP ARGUMENT IS THE SPAWN BUDGET. 253 upstream entries is 253 fresh wasm # module instantiations, and the guest does not return memory on process exit, so # one boot cannot hold the whole suite -- see the brintos-selftests packager # README. `run-ptest lens` runs the 224 lens-*.sh, `run-ptest other` runs # everything else, and each brintos-selftests file drives one group in its own # guest. No argument (which is how ptest-runner invokes it) runs all of it, which # is what a host with memory to spare should do. # # THE FOUR ROOT-GATED UPSTREAM TESTS SKIP THEMSELVES, and they do so here for a # reason worth stating: their guard is `[ "$UID" != 0 -o ... ]`, and $UID is a # bash variable. On this image /bin/sh is not bash, so $UID is unset and the # guard takes its skip branch -- the same verdict an unprivileged native run # gives, reached a different way. Neither bind mounts nor chattr exist here in # any case. They are reported SKIP by name, from upstream's own exit 77. set -u pdir=$(cd "$(dirname "$0")" && pwd) tdir=$pdir/tests group=${1:-all} case "$group" in all|lens|other) ;; *) echo "FAIL: augeas-ptest-setup (unknown group '$group'; want all|lens|other)"; exit 1 ;; esac work=$(mktemp -d "${TMPDIR:-/tmp}/augeas-ptest.XXXXXX" 2>/dev/null) \ || { work="${TMPDIR:-/tmp}/augeas-ptest.$$"; mkdir -p "$work"; } [ -d "$work" ] || { echo "FAIL: augeas-ptest-setup (no writable scratch dir)"; exit 1; } mkdir -p "$work/build" "$work/src" 2>/dev/null \ || { echo "FAIL: augeas-ptest-setup (cannot populate $work)"; exit 1; } for t in augtool augparse augmatch; do p=$(command -v "$t" 2>/dev/null) || continue ln -sf "$p" "$work/src/$t" done export abs_top_srcdir="$pdir" export abs_top_builddir="$work" export PATH="$work/src:$PATH" export LANG=en_US # Every test resolves its inputs from the two variables above, so the working # directory only has to be writable -- and must not be the read-only ptest dir. cd "$work" || { echo "FAIL: augeas-ptest-setup (cannot enter $work)"; exit 1; } # automake's verdict mapping, which is the whole of what its test-driver does # with a plain (non-TAP) test: 0 pass, 77 skip, 99 hard error, anything else # fail. run_one() { _name=$1 shift "$@" >/dev/null 2>&1 _rc=$? case "$_rc" in 0) echo "PASS: $_name" ;; 77) echo "SKIP: $_name" ;; *) echo "FAIL: $_name" ;; esac } # check_SCRIPTS first, then check_PROGRAMS -- upstream's own TESTS order, read # from the lists do_install_ptest staged out of the generated tests/Makefile. if [ "$group" != "other" ]; then while read -r s; do [ -n "$s" ] || continue case "$s" in lens-*) ;; *) continue ;; esac run_one "$s" sh "$tdir/$s" done < "$pdir/tests-scripts" fi if [ "$group" != "lens" ]; then while read -r s; do [ -n "$s" ] || continue case "$s" in lens-*) continue ;; esac run_one "$s" sh "$tdir/$s" done < "$pdir/tests-scripts" while read -r p; do [ -n "$p" ] || continue run_one "$p" "$tdir/progs/$p" done < "$pdir/tests-progs" fi cd / rm -rf "$work" # The per-test verdicts above are the report; ptest-runner tallies them itself # and a non-zero exit here would be counted a second time as a harness failure. exit 0