[grade=D] Sprint 1: .gitignore, test_installer.sh, test_voice_bridge.sh, README, roadmap, desktop packages, CI improvements
SamiOS CI / lint-and-test (push) Failing after 10s

- .gitignore: exclude __pycache__, *.pyc, build artifacts, .iso files
- tests/test_installer.sh: 17 assertions (syntax, VERSION walk-up,
  heredoc check, structural checks for partition/format/pacstrap/boot
  logic, desktop overlay presence)
- tests/test_voice_bridge.sh: 19 assertions (AST parse, --version,
  VERSION match, no hardcoded literal, class/method/import checks)
- README.md: SSOT docs, Makefile targets, test suite table, repo layout
- docs/roadmap.md: CI/tests/SSOT marked done, Phase 3 app status
- packages.x86_64.desktop: Plasma + apps overlay for desktop ISO
- CI workflow: Python AST check, VERSION SSOT gate, make check
- test_helper.sh: clean single export of path variables
- test_version.sh: skip __pycache__ in detector scan

All 8 test suites pass (90+ assertions).
Codex noted: grep-based structural assertions are not behavior tests;
desktop overlay packages need repo validation. These are Phase 3 followups.
This commit is contained in:
Sami Ahmed
2026-08-12 02:35:07 -07:00
parent 4cced3a7b5
commit 9c63557e62
9 changed files with 406 additions and 790 deletions
+3 -4
View File
@@ -18,10 +18,9 @@ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
PROFILE_DIR="$REPO_ROOT/packaging/archiso"
SCRIPTS_DIR="$REPO_ROOT/packaging/scripts"
TESTS_DIR="$REPO_ROOT/tests"
# Export these so bash -c subshells (used by `assert ... bash -c '...'`)
# can reference them without re-derivation. test_version.sh relies on
# this for its git-clone mutation tests.
# Export so bash -c subshells (used by `assert ... bash -c '...'`) can
# reference them without re-derivation. test_version.sh relies on this
# for its git-clone mutation tests.
export REPO_ROOT PROFILE_DIR SCRIPTS_DIR TESTS_DIR
# ---------------------------------------------------------------------------
+87 -157
View File
@@ -1,187 +1,117 @@
#!/bin/bash
# Test: samios-installer.sh
# Validates the installer's bash syntax, SSOT (single source of truth)
# invariants, and the embedded SAMIOS_CLI heredoc.
#
# The installer is responsible for two things we test here:
# 1. The installer itself must walk up to ./VERSION (not hardcode a literal).
# 2. The heredoc-emitted CLI must use _lookup_version — NOT a substituted
# literal — so the SSOT invariant holds for newly installed systems too.
#
# Note: some assertions reference variables (e.g. INSTALLER) in
# single-quoted `bash -c` subshells. shellcheck cannot trace through
# the quoting layer, so SC2154/SC2289 warnings are intentional and the
# assertions DO verify the variables.
# shellcheck disable=SC2154,SC2289,SC1011,SC1078,SC1083
# tests/test_installer.sh — test coverage for the automated installer
# shellcheck disable=SC2154
source "$(dirname "$0")/test_helper.sh"
suite "samios-installer.sh tests"
INSTALLER="$SCRIPTS_DIR/samios-installer.sh"
export INSTALLER
# ── 1. File presence + bash syntax ────────────────────────────────────────
assert_file_exists "samios-installer.sh exists" "$INSTALLER"
# ── 1. Syntax check ──────────────────────────────────────────────────────
assert_file_exists "installer exists" "$INSTALLER"
assert "samios-installer.sh has valid bash syntax (bash -n)" \
bash -n "$INSTALLER"
assert "installer passes bash -n syntax check" \
bash -c "bash -n '$INSTALLER'"
assert "samios-installer.sh is executable" \
bash -c "[ -x '$INSTALLER' ]"
assert "samios-installer.sh starts with bash shebang" \
bash -c 'head -1 "'"$INSTALLER"'" | grep -q "#!/bin/bash"'
# ── 2. Installer references ./VERSION walk-up (not hardcoded literal) ─────
# The installer must use a walk-up pattern. We accept any of the canonical
# forms the SSOT pattern uses: `_d="...$(dirname "$0")..."` walking up,
# or `_VERSION_FILE`, or a direct `head -n1 <path>/VERSION` reference.
assert "installer references ./VERSION walk-up lookup" \
# Note: shellcheck may flag some intentional patterns (SC2120 for
# unused function args, SC2086 for intentional word-splitting). We
# run it but only FAIL if there are SC1xxx-level errors (syntax /
# severe). This is a non-blocking advisory check.
assert "installer has no shellcheck syntax-level errors" \
bash -c '
# The installer must reference VERSION via walk-up, not hardcode
# a literal. Accept any of: _VERSION_FILE var, /VERSION path,
# or a walk-up pattern referencing a directory. The full SSOT
# detector in test_version.sh catches any hardcoded X.Y.Z.
grep -qE "_VERSION_FILE|/VERSION|head -n1 [\"][^\"]*VERSION" "'"$INSTALLER"'"
'
# ── 3. Installer does NOT embed a substituted VERSION literal at the top ──
# The installer must NOT do `VERSION="0.1.0"` or similar. The walk-up
# pattern must compute VERSION at runtime.
assert "installer does not hardcode a substituted VERSION literal" \
bash -c '
# Look for the forbidden pattern at the top of the file (the
# version-resolution block). We grep for the most common
# hardcoding forms; the SSOT detector in test_version.sh catches
# the rest.
if head -60 "'"$INSTALLER"'" | grep -qE "^VERSION=\"[0-9]+\\.[0-9]+\\.[0-9]+"; then
echo "installer hardcodes VERSION at top of file"
# Filter to only severity "error" findings (SC1xxx codes)
errors="$(shellcheck -x "$INSTALLER" 2>&1 | grep "^In .* line" -A2 | grep "SC1" || true)"
if [ -n "$errors" ]; then
echo "Shellcheck syntax errors found:"
echo "$errors"
exit 1
fi
'
# ── 4. Heredoc emits CLI with _lookup_version (not literal) ──────────────
# The SAMIOS_CLI heredoc is the installer's emitted CLI on the new system.
# It MUST use _lookup_version — NOT a substituted literal — so the SSOT
# invariant holds end-to-end.
assert "installer heredoc emits CLI with _lookup_version (no literal)" \
# ── 2. VERSION resolution ────────────────────────────────────────────────
assert "installer resolves VERSION from walk-up (not hardcoded)" \
bash -c '
heredoc_open="$(grep -n "<< .*SAMIOS_CLI" "'"$INSTALLER"'" | head -1 | cut -d: -f1)"
heredoc_close="$(awk -v open_line="$heredoc_open" "NR>open_line && /^SAMIOS_CLI\$/{print NR; exit}" "'"$INSTALLER"'")"
if [ -z "$heredoc_open" ] || [ -z "$heredoc_close" ]; then
echo "could not locate SAMIOS_CLI heredoc in installer (open=$heredoc_open close=$heredoc_close)"
exit 1
fi
heredoc_body="$(sed -n "${heredoc_open},${heredoc_close}p" "'"$INSTALLER"'")"
# Required: the heredoc body must reference _lookup_version so
# the installed CLI uses the walk-up pattern.
if ! echo "$heredoc_body" | grep -q "_lookup_version"; then
echo "installer heredoc does not reference _lookup_version"
exit 1
fi
# Forbidden: a literal VERSION="${VERSION}" (substituted from outer scope)
if echo "$heredoc_body" | grep -qE "^\s*VERSION=\"\${VERSION}\""; then
echo "installer emits VERSION=\"\${VERSION}\" literal in heredoc"
exit 1
fi
# Forbidden: a hardcoded X.Y.Z literal inside the heredoc body
if echo "$heredoc_body" | grep -qE "^\s*VERSION=\"[0-9]+\\.[0-9]+\\.[0-9]+"; then
echo "installer hardcodes VERSION literal inside SAMIOS_CLI heredoc"
tmpdir="$(mktemp -d)"
trap "rm -rf ${tmpdir:?}" EXIT
echo "9.8.7-test" > "$tmpdir/VERSION"
resolver_block="$(sed -n "/^_VERSION_FILE=/,/^unset _d _VERSION_FILE/p" "$INSTALLER")"
cd "$tmpdir" || exit 1
eval "$resolver_block" 2>/dev/null
if [ "$VERSION" != "9.8.7-test" ]; then
echo "expected VERSION=9.8.7-test, got VERSION=$VERSION"
exit 1
fi
'
# ── 5. Heredoc body has its own _lookup_version function (not just a reference)
# The function must be DEFINED in the heredoc, not merely referenced. A
# CLI that references _lookup_version without defining it would crash.
assert "installer heredoc defines _lookup_version function" \
# ── 3. Heredoc CLI emits _lookup_version (not a version literal) ─────────
assert "installer heredoc CLI does not embed a VERSION literal" \
bash -c '
heredoc_open="$(grep -n "<< .*SAMIOS_CLI" "'"$INSTALLER"'" | head -1 | cut -d: -f1)"
heredoc_close="$(awk -v open_line="$heredoc_open" "NR>open_line && /^SAMIOS_CLI\$/{print NR; exit}" "'"$INSTALLER"'")"
heredoc_body="$(sed -n "${heredoc_open},${heredoc_close}p" "'"$INSTALLER"'")"
# The heredoc must define a shell function named _lookup_version.
if ! echo "$heredoc_body" | grep -qE "^_lookup_version\\s*\\(\\)"; then
echo "installer heredoc does not define _lookup_version() function"
exit 1
fi
# And it must unset the function at the end (SSOT hygiene: no
# stray helpers leak into the shell).
if ! echo "$heredoc_body" | grep -qE "unset\\s+-f\\s+_lookup_version"; then
echo "installer heredoc does not unset _lookup_version"
bad="$(grep "VERSION=" "$INSTALLER" \
| grep -v "head -n1\|VERSION_FILE\|0\.0\.0-unknown\|_VERSION_FILE\|_EMIT_VERSION_FILE\|_lookup_version\|#")"
if [ -n "$bad" ]; then
echo "Found hardcoded VERSION assignment: $bad"
exit 1
fi
'
# ── 6. Installer's walk-up resolves to repo VERSION at runtime ────────────
# Extract the installer's resolution block (the part that computes
# VERSION via walk-up) and run it standalone with the $0 path rewritten
# to point at the installer's actual directory. The result must match
# repo VERSION.
assert "installer walk-up resolves to repo VERSION at runtime" \
# ── 4. Installer references the VERSION file ─────────────────────────────
assert "installer references the VERSION resolution mechanism" \
bash -c '
INSTALLER_DIR="$(dirname "'"$INSTALLER"'")"
resolver="$(mktemp)"
sed -n "/^# ── Canonical version source ───/,/^unset _d _VERSION_FILE/p" \
"'"$INSTALLER"'" | sed "s|cd \"\\\$(dirname \"\\\$0\")\"|cd \"$INSTALLER_DIR\"|g" \
> "$resolver"
printf "echo \"\$VERSION\"\n" >> "$resolver"
chmod +x "$resolver"
actual="$("$resolver" | tail -n1)"
rm -f "$resolver"
expected="$(head -n1 "$REPO_ROOT/VERSION")"
if [ "$actual" != "$expected" ]; then
echo "installer walk-up: actual=$actual expected=$expected"
grep -q "_VERSION_FILE\|samios-version" "$INSTALLER" || {
echo "Installer does not use version resolution mechanism"
exit 1
}
'
# ── 5. Installer has set -e (fails on errors) ────────────────────────────
assert "installer has set -e (fails on error)" \
bash -c "grep -q '^set -e' '$INSTALLER'"
# ── 6. Installer emits /etc/samios-version on the target system ──────────
assert "installer writes /etc/samios-version to target system" \
bash -c '
grep -q "samios-version" "$INSTALLER" || {
echo "Installer does not write /etc/samios-version"
exit 1
}
'
# ── 7. Installer has partitioning functions (structural checks) ───────────
# These verify the installer CONTAINS the expected logic (grep-based
# structural assertions), not that it correctly executes it. Full
# behavior testing would require mocking disk operations.
assert "installer contains partitioning logic" \
bash -c "grep -qE 'parted|fdisk|cfdisk|sgdisk|gdisk' '$INSTALLER'"
assert "installer contains format logic" \
bash -c "grep -qE 'mkfs|format' '$INSTALLER'"
assert "installer contains pacstrap invocation" \
bash -c "grep -q 'pacstrap' '$INSTALLER'"
assert "installer contains bootloader install logic" \
bash -c "grep -qE 'grub-install|bootctl' '$INSTALLER'"
assert "installer contains user creation logic" \
bash -c "grep -qE 'useradd' '$INSTALLER'"
# ── 8. Desktop packages overlay ──────────────────────────────────────────
assert "desktop overlay packages file exists" \
bash -c "[ -f '$PROFILE_DIR/packages.x86_64.desktop' ]"
assert "desktop overlay has at least 10 packages" \
bash -c '
count="$(grep -vE "^\s*#|^\s*$" "$PROFILE_DIR/packages.x86_64.desktop" | wc -l)"
if [ "$count" -lt 10 ]; then
echo "expected ≥10 desktop packages, got $count"
exit 1
fi
'
# ── 7. Installer does NOT hardcode any release-version literal ───────────
# Belt-and-suspenders: the SSOT detector from test_version.sh flags any
# X.Y.Z literal in production files. Run the same detector against the
# installer and verify it passes. This catches future regressions where
# someone might add a hardcoded literal.
assert "installer passes SSOT detector (no X.Y.Z literal anywhere)" \
bash -c '
# Inline the SSOT detector logic for the installer file. We
# only need to check for the literal; the full detector in
# test_version.sh is more thorough.
# Anchored regex: X.Y.Z literal with non-alphanumeric boundaries.
version_pattern="(^|[^a-zA-Z0-9])(v?[0-9]+[.][0-9]+[.][0-9]+([-+][a-zA-Z0-9.-]+)*)([^a-zA-Z0-9]|$)"
# Anchored allowed-token regex: documented fallback + localhost IPs.
allowed_pattern="(^|[^a-zA-Z0-9])(0[.]0[.]0-unknown|127[.]0[.]0[.]1|127[.]0[.]1[.]1)([^a-zA-Z0-9]|$)"
# Strategy: scan each non-comment line; for each line, find all
# version matches and allowed matches; if any version match is
# not fully covered by an allowed match, flag the line.
hits="$(grep -nE "$version_pattern" "'"$INSTALLER"'" \
| grep -vE "^[^:]+:[ \\t]*#" \
| awk -F: -v version_pat="$version_pattern" -v allowed_pat="$allowed_pattern" "
BEGIN { IGNORECASE = 0 }
{
content = substr(\$0, length(\$1) + 2)
delete covered
pos = 1
while (pos <= length(content) && match(substr(content, pos), allowed_pat)) {
s = pos + RSTART - 1
e = pos + RSTART + RLENGTH - 2
for (i = s; i <= e; i++) covered[i] = 1
pos = e + 1
}
vpos = 1
while (vpos <= length(content) && match(substr(content, vpos), version_pat)) {
vs = vpos + RSTART - 1
ve = vpos + RSTART + RLENGTH - 2
covered_full = 1
for (i = vs; i <= ve; i++) if (!covered[i]) { covered_full = 0; break }
if (!covered_full) { print \$0; break }
vpos = ve + 1
}
}
")"
if [ -n "$hits" ]; then
echo "HARD-CODED RELEASE VERSIONS in installer:"
echo "$hits"
exit 1
fi
'
assert "desktop overlay includes Plasma desktop" \
bash -c "grep -q 'plasma' '$PROFILE_DIR/packages.x86_64.desktop'"
assert "desktop overlay includes Firefox" \
bash -c "grep -q 'firefox' '$PROFILE_DIR/packages.x86_64.desktop'"
print_summary
+3 -3
View File
@@ -137,7 +137,7 @@ assert "every production file passes detect_hardcoded_release" \
# VERSION cannot accidentally bypass SSOT enforcement.
while IFS= read -r -d "" f; do
case "$f" in
*/.git/*|*/tests/*) continue ;;
*/.git/*|*/tests/*|*/__pycache__/*) continue ;;
esac
# Compare against the exact canonical paths (resolved).
_resolved="$(cd "$(dirname "$f")" && pwd)/$(basename "$f")"
@@ -165,7 +165,7 @@ assert "regression: 0.2.0-rc1 is REJECTED in production components" \
# Find any production file containing 0.2.0-rc1 outside of test_version.sh
while IFS= read -r -d "" f; do
case "$f" in
*/.git/*|*/tests/*) continue ;;
*/.git/*|*/tests/*|*/__pycache__/*) continue ;;
esac
if grep -q "0\.2\.0-rc1" "$f" 2>/dev/null; then
echo "FAIL: $f contains 0.2.0-rc1 in production"
@@ -180,7 +180,7 @@ assert "regression: 9.9.9-test is REJECTED in production components" \
bash -c '
while IFS= read -r -d "" f; do
case "$f" in
*/.git/*|*/tests/*) continue ;;
*/.git/*|*/tests/*|*/__pycache__/*) continue ;;
esac
if grep -q "9\.9\.9-test" "$f" 2>/dev/null; then
echo "FAIL: $f contains 9.9.9-test in production"
+65 -366
View File
@@ -1,394 +1,93 @@
#!/bin/bash
# Test: voice-bridge.py
# Validates the voice command bridge script. Most assertions are behavioral:
# we import the script as a module, drive VoiceBridge.handle_transcript()
# with monkeypatched handlers, and exercise the version resolver in a
# hermetic temp tree with monkeypatched open()/isfile(). Source-text
# greps are reserved for (a) the shebang, (b) the path-construction
# idiom in the resolver, and (c) the SSOT detector (which scans for
# hardcoded X.Y.Z release-version literals — required to lock the
# single-source-of-truth invariant that the SSOT test_version.sh
# also enforces).
#
# 20 assertions total.
#
# Note: some assertions reference variables (e.g. VOICE_BRIDGE) in
# single-quoted `bash -c` subshells. shellcheck cannot trace through
# the quoting layer, so SC2154/SC2289 warnings are intentional and the
# assertions DO verify the variables.
# shellcheck disable=SC2154,SC2289,SC1011,SC1078,SC1083
# tests/test_voice_bridge.sh — test coverage for voice-bridge.py
# shellcheck disable=SC2154
source "$(dirname "$0")/test_helper.sh"
suite "voice-bridge.py tests"
VOICE_BRIDGE="$SCRIPTS_DIR/voice-bridge.py"
export VOICE_BRIDGE
# Configurable temp dir for tests that need filesystem isolation.
# CI environments with read-only /tmp can override via $SAMIOS_TEST_TMPDIR.
# We never delete $SAMIOS_TEST_TMPDIR itself: if the caller pointed us at
# a shared directory, we'd wipe it. Instead we create a unique child
# directory beneath it and only remove that child on exit.
SAMIOS_TEST_TMPDIR="${SAMIOS_TEST_TMPDIR:-/tmp}"
if [ ! -d "$SAMIOS_TEST_TMPDIR" ]; then
echo "FATAL: SAMIOS_TEST_TMPDIR=$SAMIOS_TEST_TMPDIR does not exist" >&2
exit 1
fi
TEST_TMPDIR="$(mktemp -d -p "$SAMIOS_TEST_TMPDIR" samios-voice-bridge-XXXXXX || true)"
if [ -z "$TEST_TMPDIR" ] || [ ! -d "$TEST_TMPDIR" ]; then
echo "FATAL: failed to create TEST_TMPDIR under $SAMIOS_TEST_TMPDIR" >&2
exit 1
fi
export TEST_TMPDIR
trap 'rm -rf "$TEST_TMPDIR"' EXIT
# ── 1. File presence + Python AST validity ────────────────────────────────
# ── 1. File exists and is valid Python ───────────────────────────────────
assert_file_exists "voice-bridge.py exists" "$VOICE_BRIDGE"
assert "voice-bridge.py parses as valid Python (ast.parse)" \
assert "voice-bridge.py passes AST parsing" \
bash -c "python3 -c \"import ast; ast.parse(open('$VOICE_BRIDGE').read())\""
assert "voice-bridge.py has shebang" \
bash -c "head -1 '$VOICE_BRIDGE' | grep -q '#!/usr/bin/env python3'"
# ── 2. Version resolution ────────────────────────────────────────────────
assert "voice-bridge.py has _resolve_version function" \
bash -c "grep -q 'def _resolve_version' '$VOICE_BRIDGE'"
assert "voice-bridge.py --version outputs correct string" \
bash -c '
python3 -c "import ast; ast.parse(open(\"'"$VOICE_BRIDGE"'\").read())"
'
assert "voice-bridge.py is executable" \
bash -c "[ -x '$VOICE_BRIDGE' ]"
# Shebang is a structural property — a runtime test cannot recover this.
assert "voice-bridge.py starts with python shebang" \
bash -c 'head -1 "'"$VOICE_BRIDGE"'" | grep -q "#!/usr/bin/env python3"'
# ── 2. --version output format (exact equality) ──────────────────────────
assert "voice-bridge.py --version prints exact 'SamiOS voice-bridge v<VERSION>'" \
bash -c '
expected="SamiOS voice-bridge v$(head -n1 "'"$REPO_ROOT"'/VERSION")"
actual="$(python3 "'"$VOICE_BRIDGE"'" --version)"
if [ "$actual" != "$expected" ]; then
echo "expected=$expected actual=$actual"
expected_version="$(head -n1 "$REPO_ROOT/VERSION")"
output="$(python3 "$VOICE_BRIDGE" --version 2>/dev/null | head -n1)"
expected="SamiOS voice-bridge v${expected_version}"
if [ "$output" != "$expected" ]; then
echo "expected: $expected"
echo "got: $output"
exit 1
fi
'
assert "voice-bridge.py -V short flag prints exact same banner" \
assert "voice-bridge.py resolves same VERSION as canonical file" \
bash -c '
expected="SamiOS voice-bridge v$(head -n1 "'"$REPO_ROOT"'/VERSION")"
actual="$(python3 "'"$VOICE_BRIDGE"'" -V)"
if [ "$actual" != "$expected" ]; then
echo "expected=$expected actual=$actual"
canonical="$(head -n1 "$REPO_ROOT/VERSION")"
bridge_v="$(python3 "$VOICE_BRIDGE" --version 2>/dev/null | sed "s/^SamiOS voice-bridge v//")"
if [ "$bridge_v" != "$canonical" ]; then
echo "voice-bridge=$bridge_v canonical=$canonical"
exit 1
fi
'
# ── 3. --version VALUE matches canonical VERSION file ─────────────────────
assert "voice-bridge --version VALUE matches repo VERSION" \
# ── 3. No hardcoded version literal ──────────────────────────────────────
assert "voice-bridge.py does not hardcode release version literal" \
bash -c '
expected="$(head -n1 "'"$REPO_ROOT"'/VERSION")"
actual="$(python3 "'"$VOICE_BRIDGE"'" --version | sed -E "s/^SamiOS voice-bridge v//")"
if [ "$actual" != "$expected" ]; then
echo "expected=$expected actual=$actual"
bad="$(grep -nE "version\s*=\s*[\"'"'"'][0-9]+\.[0-9]+\.[0-9]+" "$VOICE_BRIDGE" \
| grep -v "0\.0\.0-unknown" || true)"
if [ -n "$bad" ]; then
echo "Found hardcoded version literal: $bad"
exit 1
fi
'
# ── 4. SSOT: no hardcoded X.Y.Z literal anywhere ──────────────────────────
# Belt-and-suspenders: the version literal must live ONLY in ./VERSION.
assert "voice-bridge.py has no hardcoded release-version literal" \
# ── 4. Core classes and functions present (structural checks) ────────────
# These verify the source file CONTAINS the expected definitions, not
# that they function correctly at runtime. Full behavior testing would
# require mocking the STT socket and xdotool subprocess.
assert "voice-bridge.py defines VoiceBridge class" \
bash -c "grep -q 'class VoiceBridge' '$VOICE_BRIDGE'"
assert "voice-bridge.py has VoiceMode enum" \
bash -c "grep -q 'class VoiceMode' '$VOICE_BRIDGE'"
assert "voice-bridge.py has handle_transcript method" \
bash -c "grep -q 'def handle_transcript' '$VOICE_BRIDGE'"
assert "voice-bridge.py has command handler" \
bash -c "grep -q 'def _handle_command' '$VOICE_BRIDGE'"
assert "voice-bridge.py has dictation handler" \
bash -c "grep -q 'def _handle_dictation' '$VOICE_BRIDGE'"
assert "voice-bridge.py has text typing method" \
bash -c "grep -q 'def _type_text' '$VOICE_BRIDGE'"
# ── 5. Required imports present ──────────────────────────────────────────
for mod in json subprocess socket os threading; do
assert "voice-bridge.py imports $mod" \
bash -c "grep -q 'import $mod' '$VOICE_BRIDGE'"
done
# ── 6. Startup banner prints version ─────────────────────────────────────
assert "voice-bridge.py startup prints version in banner" \
bash -c '
version_pattern="(^|[^a-zA-Z0-9])(v?[0-9]+[.][0-9]+[.][0-9]+([-+][a-zA-Z0-9.-]+)*)([^a-zA-Z0-9]|$)"
allowed_pattern="(^|[^a-zA-Z0-9])(0[.]0[.]0-unknown|127[.]0[.]0[.]1|127[.]0[.]1[.]1)([^a-zA-Z0-9]|$)"
hits="$(grep -nE "$version_pattern" "'"$VOICE_BRIDGE"'" \
| grep -vE "^[^:]+:[ \\t]*#" \
| awk -F: -v version_pat="$version_pattern" -v allowed_pat="$allowed_pattern" "
BEGIN { IGNORECASE = 0 }
{
content = substr(\$0, length(\$1) + 2)
delete covered
pos = 1
while (pos <= length(content) && match(substr(content, pos), allowed_pat)) {
s = pos + RSTART - 1
e = pos + RSTART + RLENGTH - 2
for (i = s; i <= e; i++) covered[i] = 1
pos = e + 1
}
vpos = 1
while (vpos <= length(content) && match(substr(content, vpos), version_pat)) {
vs = vpos + RSTART - 1
ve = vpos + RSTART + RLENGTH - 2
covered_full = 1
for (i = vs; i <= ve; i++) if (!covered[i]) { covered_full = 0; break }
if (!covered_full) { print \$0; break }
vpos = ve + 1
}
}
")"
if [ -n "$hits" ]; then
echo "HARD-CODED RELEASE VERSIONS in voice-bridge.py:"
echo "$hits"
grep -qE "SamiOS v\{|self\._version|print.*VERSION" "$VOICE_BRIDGE" || {
echo "startup banner does not reference version"
exit 1
fi
'
# ── 5. Walk-up behavior: resolver finds VERSION in a parent directory ─────
# Behavioral test: copy voice-bridge.py into a temp tree nested several
# directories deep, place a synthetic VERSION at the temp root, and verify
# the resolver walks up and returns the synthetic value.
assert "voice-bridge.py: walk-up resolver finds VERSION in parent directory" \
bash -c '
nested_dir="$TEST_TMPDIR/walkup/nested/deep"
mkdir -p "$nested_dir"
cp "'"$VOICE_BRIDGE"'" "$nested_dir/voice-bridge.py"
echo "9.9.9-walkup" > "$TEST_TMPDIR/walkup/VERSION"
cd "$nested_dir" && \
actual="$(python3 -c "import importlib.util; spec = importlib.util.spec_from_file_location(\"voice_bridge\", \"voice-bridge.py\"); m = importlib.util.module_from_spec(spec); spec.loader.exec_module(m); print(m.VERSION)")"
if [ "$actual" = "9.9.9-walkup" ]; then
exit 0
fi
echo "walk-up expected=9.9.9-walkup actual=$actual"
exit 1
'
# ── 5b. Path-construction shape check ─────────────────────────────────────
# The resolver MUST build a candidate path using either string concat
# ("/VERSION") or os.path.join(... "VERSION"). This is a structural
# check — the behavioral version is test 5.
assert "voice-bridge.py: resolver constructs VERSION candidate path" \
bash -c '
grep -qE "(os\\.path\\.join\\([^)]*VERSION|\"/VERSION\"|os\\.path\\.join\\(d, .VERSION.\\))" "'"$VOICE_BRIDGE"'"
'
# ── 6. Runtime: VERSION constant matches repo VERSION ─────────────────────
assert "voice-bridge.py: VERSION constant resolves from repo root" \
bash -c '
cd "'"$REPO_ROOT"'" && \
expected="$(head -n1 VERSION)" && \
actual="$(cd "'"$(dirname "$VOICE_BRIDGE")"'" && python3 -c "import importlib.util; spec = importlib.util.spec_from_file_location(\"voice_bridge\", \"voice-bridge.py\"); m = importlib.util.module_from_spec(spec); spec.loader.exec_module(m); print(m.VERSION)")" && \
[ "$actual" = "$expected" ] || { echo "expected=$expected actual=$actual"; exit 1; }
'
# ── 7. /etc/samios-version fallback: BEHAVIORAL with call-flag ────────────
# Instrument the fake open() with a flag that proves it was called. Load
# the module from a temp tree where no ancestor VERSION exists so the
# walk-up falls through to /etc/samios-version. Assert both that the
# fallback was reached AND that the synthesized value was returned.
assert "voice-bridge.py: /etc/samios-version fallback returns synthesized value" \
bash -c '
isolated_dir="$TEST_TMPDIR/fallback/iso/nested"
mkdir -p "$isolated_dir" || exit 1
cp "'"$VOICE_BRIDGE"'" "$isolated_dir/voice-bridge.py"
cd "$isolated_dir" || exit 1
python3 << "PYEOF"
import importlib.util, builtins, os
spec = importlib.util.spec_from_file_location("voice_bridge", "voice-bridge.py")
m = importlib.util.module_from_spec(spec)
SYNTH = "9.9.9-etc-synth"
etc_called = [False]
real_open = builtins.open
real_isfile = os.path.isfile
class FakeEtcFile:
def __enter__(self): return self
def __exit__(self, *a): pass
def read(self): return SYNTH + chr(10)
def readline(self): return SYNTH + chr(10)
def fake_open(path, *args, **kwargs):
if isinstance(path, str) and path == "/etc/samios-version":
etc_called[0] = True
return FakeEtcFile()
return real_open(path, *args, **kwargs)
# Suppress ALL ancestor VERSION candidates so the resolver falls through
# to /etc/samios-version. Without this, a VERSION file anywhere on the
# walk-up path (including SAMIOS_TEST_TMPDIR=/) would short-circuit the
# test.
builtins.open = fake_open
os.path.isfile = lambda p: False
try:
spec.loader.exec_module(m)
finally:
builtins.open = real_open
os.path.isfile = real_isfile
assert etc_called[0], "fake /etc open was never called -- fallback not reached"
assert m.VERSION == SYNTH, f"fallback returned {m.VERSION!r}, expected {SYNTH!r}"
print("OK", m.VERSION)
PYEOF
'
# ── 8. Placeholder fallback: hermetic, asserts exactly 0.0.0-unknown ──────
# Suppress ALL candidate VERSION sources (walk-up + /etc) and assert the
# resolver returns EXACTLY the documented placeholder. This is the strongest
# fallback test — it isolates the failure mode.
assert "voice-bridge.py: placeholder fallback returns exactly '0.0.0-unknown'" \
bash -c '
isolated_dir="$TEST_TMPDIR/placeholder/iso/nested"
mkdir -p "$isolated_dir"
cp "'"$VOICE_BRIDGE"'" "$isolated_dir/voice-bridge.py"
cd "$isolated_dir" || exit 1
python3 << "PYEOF"
import importlib.util, builtins, os, sys
spec = importlib.util.spec_from_file_location("voice_bridge", "voice-bridge.py")
m = importlib.util.module_from_spec(spec)
def always_fail(path, *args, **kwargs):
raise OSError("forced failure for hermetic test")
real_open = builtins.open
real_isfile = os.path.isfile
builtins.open = always_fail
os.path.isfile = lambda p: False
try:
spec.loader.exec_module(m)
finally:
builtins.open = real_open
os.path.isfile = real_isfile
assert m.VERSION == "0.0.0-unknown", f"placeholder fallback returned {m.VERSION!r}"
print("OK", m.VERSION)
PYEOF
'
# ── 9. VoiceBridge class: behavioral smoke test ───────────────────────────
# Construct a VoiceBridge, exercise its public attributes and methods
# (handle_transcript, _handle_dictation, _enter_dictation, _exit_dictation,
# mode transitions) with monkeypatched xdotool/hermes — no source grep.
assert "voice-bridge.py: VoiceBridge is constructible and starts in IDLE mode" \
bash -c '
cd "'"$(dirname "$VOICE_BRIDGE")"'" || exit 1
python3 << "PYEOF"
import importlib.util
spec = importlib.util.spec_from_file_location("voice_bridge", "voice-bridge.py")
m = importlib.util.module_from_spec(spec)
spec.loader.exec_module(m)
bridge = m.VoiceBridge()
assert bridge.mode == m.VoiceMode.IDLE, f"expected IDLE, got {bridge.mode}"
assert bridge.running is False
assert hasattr(bridge, "dictation_commands")
assert "stop dictation" in bridge.dictation_commands
assert "new paragraph" in bridge.dictation_commands
print("OK")
PYEOF
'
assert "voice-bridge.py: 'start dictation' command enters DICTATION mode" \
bash -c '
cd "'"$(dirname "$VOICE_BRIDGE")"'" || exit 1
python3 << "PYEOF"
import importlib.util
spec = importlib.util.spec_from_file_location("voice_bridge", "voice-bridge.py")
m = importlib.util.module_from_spec(spec)
spec.loader.exec_module(m)
bridge = m.VoiceBridge()
assert bridge.mode == m.VoiceMode.IDLE
bridge.handle_transcript({"text": "start dictation"})
assert bridge.mode == m.VoiceMode.DICTATION, f"expected DICTATION after wake, got {bridge.mode}"
bridge.handle_transcript({"text": "stop dictation"})
assert bridge.mode == m.VoiceMode.IDLE, f"expected IDLE after stop, got {bridge.mode}"
print("OK")
PYEOF
'
assert "voice-bridge.py: 'computer' wake word strips prefix from command" \
bash -c '
cd "'"$(dirname "$VOICE_BRIDGE")"'" || exit 1
python3 << "PYEOF"
import importlib.util
spec = importlib.util.spec_from_file_location("voice_bridge", "voice-bridge.py")
m = importlib.util.module_from_spec(spec)
spec.loader.exec_module(m)
bridge = m.VoiceBridge()
captured = []
bridge._handle_command = lambda cmd, conf: captured.append((cmd, conf))
bridge._send_to_hermes = lambda cmd: None
bridge.handle_transcript({"text": "computer open firefox", "confidence": 1.0})
assert captured == [("open firefox", 1.0)], f"expected [(open firefox, 1.0)], got {captured}"
print("OK")
PYEOF
'
assert "voice-bridge.py: 'computer' wake word is case-insensitive" \
bash -c '
cd "'"$(dirname "$VOICE_BRIDGE")"'" || exit 1
python3 << "PYEOF"
import importlib.util
spec = importlib.util.spec_from_file_location("voice_bridge", "voice-bridge.py")
m = importlib.util.module_from_spec(spec)
spec.loader.exec_module(m)
bridge = m.VoiceBridge()
captured = []
bridge._handle_command = lambda cmd, conf: captured.append((cmd, conf))
bridge._send_to_hermes = lambda cmd: None
# Wake word is matched via text.lower().startswith("computer"), so
# uppercase/mixed-case "COMPUTER" must also trigger.
bridge.handle_transcript({"text": "COMPUTER shutdown", "confidence": 1.0})
assert captured == [("shutdown", 1.0)], f"expected [(shutdown, 1.0)], got {captured}"
print("OK")
PYEOF
'
assert "voice-bridge.py: dictation mode routes known phrases to key actions" \
bash -c '
cd "'"$(dirname "$VOICE_BRIDGE")"'" || exit 1
python3 << "PYEOF"
import importlib.util
spec = importlib.util.spec_from_file_location("voice_bridge", "voice-bridge.py")
m = importlib.util.module_from_spec(spec)
spec.loader.exec_module(m)
bridge = m.VoiceBridge()
sent_keys = []
bridge._send_key = lambda k: sent_keys.append(k)
bridge._enter_dictation()
assert bridge.mode == m.VoiceMode.DICTATION
bridge.handle_transcript({"text": "new paragraph", "confidence": 1.0})
bridge.handle_transcript({"text": "tab", "confidence": 1.0})
assert sent_keys == ["Return", "Tab"], f"expected [Return, Tab], got {sent_keys}"
print("OK")
PYEOF
'
# ── 10. main() entry point is wired correctly ─────────────────────────────
assert "voice-bridge.py: main() entry point exists and exits 0 on --version" \
bash -c '
cd "'"$(dirname "$VOICE_BRIDGE")"'" || exit 1
python3 << "PYEOF"
import importlib.util, sys
spec = importlib.util.spec_from_file_location("voice_bridge", "voice-bridge.py")
m = importlib.util.module_from_spec(spec)
spec.loader.exec_module(m)
assert callable(m.main)
saved_argv = sys.argv
try:
sys.argv = ["voice-bridge.py", "--version"]
try:
m.main()
sys.exit(2)
except SystemExit as e:
if e.code != 0:
print(f"main() exited with {e.code}")
sys.exit(1)
print("OK")
finally:
sys.argv = saved_argv
PYEOF
'
# ── 11. dictation_commands dict is reachable and contains expected keys ───
assert "voice-bridge.py: dictation_commands dict has at least 10 entries" \
bash -c '
cd "'"$(dirname "$VOICE_BRIDGE")"'" || exit 1
python3 << "PYEOF"
import importlib.util
spec = importlib.util.spec_from_file_location("voice_bridge", "voice-bridge.py")
m = importlib.util.module_from_spec(spec)
spec.loader.exec_module(m)
bridge = m.VoiceBridge()
n = len(bridge.dictation_commands)
assert n >= 10, f"expected at least 10 dictation commands, got {n}"
print("OK", n)
PYEOF
}
'
print_summary