d817c37652
gates / consistency-and-conventions (push) Successful in 26s
17-point code-level audit executed via Explorer->Architect->Builder->Tester->Reviewer;
Reviewer accepted (APPROVE_WITH_NOTES; 3 block-list items resolved):
- security: telegram sender-owner AND-gate + TELEGRAM_OWNER_ID, matrix
MATRIX_ROOM_ID fail-closed, gpg --passphrase-fd 3 (no argv secret),
/dev/tcp positional-arg form (checkport/smb-client/share-lib/NET_PROBE),
eval deny-by-default + --no-command-execution carried by both chat bridges,
tty-gated --trust; config/{telegram,matrix}.env reference templates
- ai: all ExecStart flags validated against installed llama.cpp
(requested->error, default->omit+warn, CONFIG_REQUESTED_FLAGS); single-file
hf download failure rc=1 + no .hf-meta; LLAMACPP_HOST coherent;
POS_SUBCMDS + metadata gaps closed
- tooling: lint-conventions Bash-native rewrite (~24-30x faster, rules and
output byte-identical, :num restored); pos system uninstall covers all 12
libs + scale-tail + flags dir + systemd user units (|| true) + plugin
markers; anchored .bash_completion/.bashrc removal replaces sed -i '/pos/d'
- config: canonical load_env_file in lib/config-ui.sh (CRLF strip, env-wins,
XDG, LOADED_ENV_KEYS); 9 tools migrated; entertainment-lib collapsed to
wrappers; docker-compose deliberately unmigrated (source semantics)
- tests: first committed regression suite — tests/run-tests.sh zero-dep
runner + make test; 12 files / 179 checks / 0 skip / ~52s; hard skip
contract; systemd-analyze verify on generated unit PASS
Verified: make gen idempotent; make check green; make lint 0 FAIL, 0 WARN;
make test green; bash -n clean; git diff --check clean. Audit deliverables +
agent reports + AGENT_TODO Done entry included.
167 lines
6.0 KiB
Bash
Executable File
167 lines
6.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
# tests/run-tests.sh — zero-dependency Bash regression runner.
|
|
#
|
|
# Discovers tests/t-*.sh, runs each in an isolated subshell (temp sandbox per
|
|
# test, cleaned up automatically), collects PASS/FAIL/SKIP, prints a summary
|
|
# table, and exits non-zero when any check failed.
|
|
#
|
|
# Usage: tests/run-tests.sh [test-file ...]
|
|
# No args → run every tests/t-*.sh (sorted)
|
|
# With args → run only the named test files (path or bare name)
|
|
#
|
|
# Skip contract (hard): a test that cannot run in this environment MUST call
|
|
# skip_case "<desc>" "<reason>" — it prints `[SKIP] reason`, is counted in the
|
|
# summary, and never counts as PASS. A test file whose run_test() produced
|
|
# zero checks and zero skips is reported as FAIL ("no assertions") so a broken
|
|
# harness can never silently pass. Tests must never lie.
|
|
|
|
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
TEST_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
|
|
PASS=0; FAIL=0; SKIP=0
|
|
files_total=0; files_pass=0; files_fail=0; files_skip=0
|
|
declare -a FAILED_FILES=()
|
|
START_TS="$(date +%s)"
|
|
|
|
# ── per-test state set by the runner before sourcing a test file ──
|
|
TEST_NAME=""
|
|
TEST_TMP=""
|
|
TEST_TRAP_SET=0
|
|
|
|
cleanup_test_tmp() {
|
|
if [ -n "${TEST_TMP:-}" ] && [ -d "$TEST_TMP" ]; then
|
|
rm -rf "$TEST_TMP"
|
|
fi
|
|
TEST_TMP=""
|
|
}
|
|
|
|
# Run one test file in a subshell; stdout/stderr go to the per-test log.
|
|
# Returns 0 = no FAIL lines, 1 = FAIL, 2 = SKIP-only.
|
|
run_one() {
|
|
local test_file="$1"
|
|
local log="$TEST_TMP/$TEST_NAME.log"
|
|
local rc=0
|
|
|
|
# Run in a subshell; the exit status must be captured via `if` because a
|
|
# plain `( ... ); rc=$?` would let the subshell's failure trigger errexit
|
|
# in the parent (set -e applies to subshells as ordinary commands).
|
|
local rc=0
|
|
if (
|
|
# Isolated sandbox for this test.
|
|
TEST_NAME="$(basename "$test_file")"
|
|
TEST_TMP="$(mktemp -d "${TMPDIR:-/tmp}/pos-test-${TEST_NAME}.XXXXXX")"
|
|
export TEST_NAME TEST_TMP
|
|
trap cleanup_test_tmp EXIT
|
|
|
|
# Shared helpers + strict mode (the runner already has -euo pipefail;
|
|
# re-assert it in the subshell for belt-and-braces).
|
|
set -euo pipefail
|
|
source "$TEST_DIR/test-lib.sh"
|
|
source "$test_file"
|
|
run_test
|
|
) >"$log" 2>&1; then
|
|
rc=0
|
|
else
|
|
rc=$?
|
|
fi
|
|
|
|
local f_p=0 f_f=0 f_s=0
|
|
f_p="$(grep -c '^ PASS ' "$log" 2>/dev/null || true)"
|
|
f_f="$(grep -c '^ FAIL ' "$log" 2>/dev/null || true)"
|
|
f_s="$(grep -c '^ SKIP ' "$log" 2>/dev/null || true)"
|
|
PASS=$((PASS + f_p)); FAIL=$((FAIL + f_f)); SKIP=$((SKIP + f_s))
|
|
files_total=$((files_total + 1))
|
|
|
|
# A test that aborted (rc != 0) WITHOUT a checked FAIL is still a FAIL —
|
|
# set -e / errexit killed it mid-run.
|
|
if [ "$rc" -ne 0 ] && [ "$f_f" -eq 0 ]; then
|
|
f_f=1
|
|
FAIL=$((FAIL + 1))
|
|
printf '\n FAIL test aborted (exit %s) before a check failed — see log below\n' "$rc" >>"$log"
|
|
fi
|
|
|
|
if [ "$f_f" -gt 0 ]; then
|
|
files_fail=$((files_fail + 1))
|
|
FAILED_FILES+=("$test_file")
|
|
printf ' FAIL %s (%s checks, %s failed, %s skipped)\n' "$TEST_NAME" "$f_p" "$f_f" "$f_s"
|
|
elif [ "$f_p" -gt 0 ]; then
|
|
files_pass=$((files_pass + 1))
|
|
if [ "$f_s" -gt 0 ]; then
|
|
printf ' PASS %s (%s checks, %s skipped)\n' "$TEST_NAME" "$f_p" "$f_s"
|
|
else
|
|
printf ' PASS %s (%s checks)\n' "$TEST_NAME" "$f_p"
|
|
fi
|
|
elif [ "$f_s" -gt 0 ]; then
|
|
files_skip=$((files_skip + 1))
|
|
local reasons
|
|
reasons="$(grep '^ SKIP ' "$log" 2>/dev/null | sed 's/^ SKIP //' | tr '\n' '; ' )"
|
|
printf ' SKIP %s (%s reasons: %s)\n' "$TEST_NAME" "$f_s" "${reasons:-none}"
|
|
else
|
|
files_fail=$((files_fail + 1))
|
|
FAILED_FILES+=("$test_file")
|
|
printf ' FAIL %s (no assertions run — harness broken)\n' "$TEST_NAME"
|
|
fi
|
|
}
|
|
|
|
main() {
|
|
local tests=() f
|
|
if [ $# -gt 0 ]; then
|
|
for f in "$@"; do
|
|
case "$f" in
|
|
*/*) tests+=("$f") ;;
|
|
*)
|
|
if [ -f "$TEST_DIR/$f.sh" ]; then
|
|
tests+=("$TEST_DIR/$f.sh")
|
|
elif [ -f "$TEST_DIR/$f" ]; then
|
|
tests+=("$TEST_DIR/$f")
|
|
else
|
|
echo "No such test: $f" >&2
|
|
exit 2
|
|
fi
|
|
;;
|
|
esac
|
|
done
|
|
else
|
|
# Deterministic order: sorted by name.
|
|
while IFS= read -r f; do
|
|
tests+=("$f")
|
|
done < <(find "$TEST_DIR" -maxdepth 1 -name 't-*.sh' -type f | sort)
|
|
fi
|
|
|
|
[ "${#tests[@]}" -gt 0 ] || { echo "No test files found in $TEST_DIR" >&2; exit 1; }
|
|
|
|
echo "Running ${#tests[@]} test file(s) — strict mode: no network, no sudo, no system changes."
|
|
echo
|
|
|
|
local one
|
|
for one in "${tests[@]}"; do
|
|
TEST_NAME="$(basename "$one")"
|
|
TEST_TMP="$(mktemp -d "${TMPDIR:-/tmp}/pos-run.XXXXXX")"
|
|
run_one "$one"
|
|
# keep the per-test sandbox only on FAILURE for debugging
|
|
if [ -f "$TEST_TMP/$TEST_NAME.log" ]; then
|
|
if [ "$(grep -c '^ FAIL ' "$TEST_TMP/$TEST_NAME.log" 2>/dev/null || true)" -gt 0 ]; then
|
|
echo "─── $TEST_NAME log ───"
|
|
sed 's/^/ /' "$TEST_TMP/$TEST_NAME.log"
|
|
echo "──────────────────────"
|
|
fi
|
|
rm -f "$TEST_TMP/$TEST_NAME.log"
|
|
fi
|
|
rm -rf "$TEST_TMP"
|
|
done
|
|
TEST_TMP=""
|
|
|
|
local elapsed=$(( $(date +%s) - START_TS ))
|
|
echo
|
|
echo "──────────────────────────────────────────────"
|
|
echo "Summary: files ${files_pass} pass / ${files_fail} fail / ${files_skip} skip (of ${files_total})"
|
|
echo "Checks : ${PASS} pass / ${FAIL} fail / ${SKIP} skip"
|
|
echo "Runtime: ${elapsed}s"
|
|
if [ "${#FAILED_FILES[@]}" -gt 0 ]; then
|
|
printf 'Failed : %s\n' "${FAILED_FILES[*]}"
|
|
fi
|
|
[ "$FAIL" -eq 0 ] && [ "$files_fail" -eq 0 ]
|
|
}
|
|
|
|
main "$@" |