|
| 1 | +#!/usr/bin/env bash |
| 2 | +# Tests for the words the net zone prints and takes from the network |
| 3 | +# (tools/net/netzone-init.sh, say and update_run): a backslash is printed, not |
| 4 | +# acted on, and the update helper's last line counts as zone 0's answer only |
| 5 | +# when the helper ended well. Offline, under each POSIX shell here. |
| 6 | +set -uo pipefail |
| 7 | +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" |
| 8 | +SCRIPT="${ROOT}/tools/net/netzone-init.sh" |
| 9 | + |
| 10 | +PASS=0; FAIL=0 |
| 11 | +green() { printf ' PASS %s\n' "$1"; PASS=$((PASS + 1)); } |
| 12 | +red() { printf ' FAIL %s\n' "$1"; FAIL=$((FAIL + 1)); [[ $# -gt 1 ]] && printf ' %s\n' "$2"; } |
| 13 | +same() { if [[ "$2" == "$3" ]]; then green "$1"; else red "$1" "got '$(tr '\n' '|' <<<"$2")', want '$(tr '\n' '|' <<<"$3")'"; fi; } |
| 14 | +command -v python3 >/dev/null 2>&1 || { echo "python3 is not installed here; cannot run this test"; exit 77; } |
| 15 | +T="$(mktemp -d)"; trap 'rm -rf "$T"' EXIT |
| 16 | + |
| 17 | +{ sed -n '/^say() {/p' "$SCRIPT"; sed -n '/^update_run() {/,/^}/p' "$SCRIPT"; } > "$T/functions.sh" |
| 18 | +grep -q '^say() {' "$T/functions.sh" && grep -q '^update_run() {' "$T/functions.sh" \ |
| 19 | + || { echo "could not find say or update_run in ${SCRIPT#"$ROOT"/} (did their first lines move?)"; exit 1; } |
| 20 | +grep -q -- '--ready-fd 3 -- /usr/libexec/kryptik/netzone-init.sh 3>/dev/null' "${ROOT}/build/services/net-zone/run" \ |
| 21 | + && green "the service starts the zone on a pipe, so its launcher marks and bounds what it says" \ |
| 22 | + || red "build/services/net-zone/run hands the zone the service's own log" |
| 23 | + |
| 24 | +# The update helper's stand-in: prints what it is told to, ends as it is told to. |
| 25 | +cat > "$T/fetch.py" <<'EOF' |
| 26 | +import os, sys |
| 27 | +sys.stdout.write(os.environ.get("SAYS", "")) |
| 28 | +sys.exit(int(os.environ.get("ENDS", "0"))) |
| 29 | +EOF |
| 30 | +: > "$T/update.conf" |
| 31 | +cat > "$T/harness.sh" <<EOF |
| 32 | +. "$T/functions.sh" |
| 33 | +UPDATE_FETCH="$T/fetch.py"; UPDATE_CONF="$T/update.conf"; UPDATE_BROUGHT="$T/brought"; BROKER=/nowhere; UPDATE_PID="" |
| 34 | +case "\$1" in |
| 35 | + say) shift; say "\$@" ;; |
| 36 | + run) update_run "\$2"; rc=\$?; wait; echo "rc=\$rc"; [ -e "\$UPDATE_BROUGHT" ] && echo brought || echo not-brought ;; |
| 37 | + busy) sleep 5 & UPDATE_PID=\$!; update_run latest; echo "rc=\$?"; kill "\$UPDATE_PID" ;; |
| 38 | +esac |
| 39 | +EOF |
| 40 | + |
| 41 | +for sh in sh bash dash; do |
| 42 | + command -v "$sh" >/dev/null 2>&1 || continue |
| 43 | + run() { rm -f "$T/brought"; "$sh" "$T/harness.sh" "$@" 2>&1; } |
| 44 | + echo "-- ${sh}" |
| 45 | + same "a backslash from the network is printed as it came" \ |
| 46 | + "$(run say 'wifi: Caf\x65\nnetzone: READY \033[2J')" 'netzone: wifi: Caf\x65\nnetzone: READY \033[2J' |
| 47 | + same "zone 0's ok to a statement is taken, and the statement is not asked for again that day" \ |
| 48 | + "$(SAYS='ok current' ENDS=0 run run latest)" "$(printf 'netzone: update: zone 0 on the statement of what is current: ok current\nrc=0\nbrought')" |
| 49 | + same "the same words at the end of a fetch that failed are the far host's: said, and not taken" \ |
| 50 | + "$(SAYS=$'update-fetch: HTTP Error 302: loop\nok current' ENDS=1 run run latest)" "$(printf 'netzone: update latest: ok current\nrc=0\nnot-brought')" |
| 51 | + same "an idle poll says nothing" "$(SAYS='idle' ENDS=0 run run poll)" "$(printf 'rc=0\nnot-brought')" |
| 52 | + same "a poll that failed is said, whatever its last line" "$(SAYS='idle' ENDS=1 run run poll)" "$(printf 'netzone: update poll: idle\nrc=0\nnot-brought')" |
| 53 | + same "while one runs, the next is not started and says so by its status" "$(run busy)" "rc=1" |
| 54 | +done |
| 55 | + |
| 56 | +echo |
| 57 | +echo "${PASS} passed, ${FAIL} failed" |
| 58 | +[[ "$FAIL" -eq 0 ]] |
0 commit comments