From 93a466c8e44ba46494436095479f051165975a26 Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Sun, 19 Jul 2026 19:06:23 +0200 Subject: [PATCH] Run shell tests in CI and repair three broken by a reorg The shell tests under linux_configuration/tests/ never ran anywhere: no workflow executed them, so they rotted silently. Three referenced script paths that moved under scripts/periodic_background/ in an earlier reorganisation, and test_android_guardian_service.sh created its temp worktree at a different path from the one it copied into, so its cp could never succeed. The new workflow runs the bats suites plus an explicit allowlist of side-effect-free tests. Roughly eight others drive pacman, /etc, systemd or adb and need root plus an Arch container, so they stay out. Repairing the paths uncovered two genuine failures, deliberately left out of the allowlist because they look like real regressions in the scripts they cover rather than stale assertions: - test_music_parallelism.sh expects idle mode to wait IDLE_CHECK_INTERVAL (30s); the daemon waits 15s, so it wakes twice as often as intended when idle. - test_usage_monitoring_installer_efficiency.sh expects the logger template to sleep between day-rollover checks. Both need a fix in the covered scripts, not in the tests. --- .github/workflows/shell-tests.yml | 56 +++++++++++++++++++ .../evidence/shell-tests-ci-2026-07-19.json | 40 +++++++++++++ .../tests/test_android_guardian_service.sh | 2 +- .../tests/test_music_parallelism.sh | 2 +- ...t_usage_monitoring_installer_efficiency.sh | 2 +- 5 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/shell-tests.yml create mode 100644 docs/superpowers/evidence/shell-tests-ci-2026-07-19.json diff --git a/.github/workflows/shell-tests.yml b/.github/workflows/shell-tests.yml new file mode 100644 index 00000000..8a960f3f --- /dev/null +++ b/.github/workflows/shell-tests.yml @@ -0,0 +1,56 @@ +name: Shell tests + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + shell-tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Install bats + run: sudo apt-get update && sudo apt-get install -y bats + + - name: Run bats suites + run: bats linux_configuration/tests/*.bats + + # Only the side-effect-free tests run here. The rest of + # linux_configuration/tests/ drives pacman, /etc, systemd or adb and + # cannot run on an Ubuntu runner without root and an Arch container -- + # see docs note in the accompanying evidence artifact. + # + # Deliberately NOT in this list (both fail today, and both look like they + # are catching real polling-efficiency regressions rather than being + # stale -- they need a fix in the scripts they cover, not in the tests): + # test_music_parallelism.sh + # 'idle mode uses the idle interval' expects 30s but the daemon + # waits 15s, i.e. it wakes twice as often as intended when idle. + # test_usage_monitoring_installer_efficiency.sh + # 'logger template must sleep between day rollover checks'. + - name: Run side-effect-free shell tests + run: | + set -euo pipefail + tests=( + test_android_guardian_post_fs_data.sh + test_android_guardian_service.sh + test_i3blocks_persist_common.sh + test_setup_dns_blocker.sh + ) + failed=0 + for t in "${tests[@]}"; do + printf '\n=== %s ===\n' "$t" + if bash "linux_configuration/tests/$t"; then + printf 'PASS %s\n' "$t" + else + printf 'FAIL %s\n' "$t" + failed=$((failed + 1)) + fi + done + if [ "$failed" -gt 0 ]; then + printf '\n%d shell test(s) failed\n' "$failed" + exit 1 + fi diff --git a/docs/superpowers/evidence/shell-tests-ci-2026-07-19.json b/docs/superpowers/evidence/shell-tests-ci-2026-07-19.json new file mode 100644 index 00000000..df24c91b --- /dev/null +++ b/docs/superpowers/evidence/shell-tests-ci-2026-07-19.json @@ -0,0 +1,40 @@ +{ + "intent": "Run the repo's shell tests in CI instead of leaving them manual-only, and repair the ones broken by an earlier directory reorganisation so they can participate.", + "scope": [ + ".github/workflows/shell-tests.yml (new): runs the bats suites plus the side-effect-free .sh tests on ubuntu-latest", + "linux_configuration/tests/test_android_guardian_service.sh, test_music_parallelism.sh, test_usage_monitoring_installer_efficiency.sh: stale path repairs", + "Non-goal: running the ~8 Arch-specific tests (pacman, /etc, systemd, adb). They need root and an Arch container; excluded with a comment in the workflow.", + "Non-goal: fixing the two efficiency regressions these repairs uncovered — those are bugs in the covered scripts, not in the tests." + ], + "changes": [ + "New Shell tests workflow, mirroring the existing pre-commit.yml style: checkout, apt-install bats, run all *.bats, then run an explicit allowlist of side-effect-free .sh tests, accumulating failures so one bad test does not mask the rest.", + "test_music_parallelism.sh and test_usage_monitoring_installer_efficiency.sh pointed at scripts// paths that moved under scripts/periodic_background/ in an earlier reorganisation; both now resolve.", + "test_android_guardian_service.sh created its temp worktree at scripts/single_use/utils/android_guardian while copying into scripts/periodic_background/utils/android_guardian, so the cp always failed. The mkdir now matches the cp target and the test passes." + ], + "verification": [ + { + "command": "bats linux_configuration/tests/*.bats", + "result": "pass", + "evidence": "1..30, all ok." + }, + { + "command": "bash linux_configuration/tests/", + "result": "pass", + "evidence": "test_android_guardian_post_fs_data.sh, test_android_guardian_service.sh, test_i3blocks_persist_common.sh, test_setup_dns_blocker.sh — 0 failures. Before this change test_android_guardian_service.sh failed with 'cp: cannot create regular file ... No such file or directory'." + }, + { + "command": "local simulation of the workflow's two run steps", + "result": "pass", + "evidence": "Both steps exit 0, so the workflow should be green on first run." + } + ], + "risks": [ + "Two repaired tests still fail and are deliberately excluded from CI, because they appear to catch genuine polling-efficiency regressions rather than being stale: test_music_parallelism.sh asserts idle mode waits IDLE_CHECK_INTERVAL (30s) but the daemon waits 15s — it wakes twice as often as intended when idle, contrary to the repo's polling guidance; test_usage_monitoring_installer_efficiency.sh asserts the logger template sleeps between day-rollover checks. Both need a fix in the scripts they cover. Until then the exclusion list hides two known-red tests, which is why it is commented in the workflow rather than left implicit.", + "The allowlist is manual: a new .sh test will not run in CI until someone adds it. Chosen over a glob because most tests in that directory cannot run on an Ubuntu runner.", + "Ubuntu's bats may lag the Arch version used locally (1.13.0); the suite uses only core bats features, no bats-assert or bats-support." + ], + "rollback": [ + "git revert this commit: CI stops running shell tests and the three path repairs are undone, restoring the spurious 'No such file' failure in test_android_guardian_service.sh.", + "Validate after rollback: .github/workflows/shell-tests.yml is absent and the three tests reference their pre-reorganisation paths again." + ] +} diff --git a/linux_configuration/tests/test_android_guardian_service.sh b/linux_configuration/tests/test_android_guardian_service.sh index 49c2ff5c..41e1fc18 100755 --- a/linux_configuration/tests/test_android_guardian_service.sh +++ b/linux_configuration/tests/test_android_guardian_service.sh @@ -28,7 +28,7 @@ cleanup() { trap cleanup EXIT WORKTREE="$TMP_DIR/worktree" -mkdir -p "$WORKTREE/scripts/single_use/utils/android_guardian" +mkdir -p "$WORKTREE/scripts/periodic_background/utils/android_guardian" cp "$TARGET_SCRIPT" "$WORKTREE/scripts/periodic_background/utils/android_guardian/service.sh" printf 'Checking skip-main avoids boot side effects...\n' diff --git a/linux_configuration/tests/test_music_parallelism.sh b/linux_configuration/tests/test_music_parallelism.sh index 08c7758a..60ab34f2 100755 --- a/linux_configuration/tests/test_music_parallelism.sh +++ b/linux_configuration/tests/test_music_parallelism.sh @@ -5,7 +5,7 @@ set -euo pipefail SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) REPO_DIR=$(cd -- "$SCRIPT_DIR/.." && pwd) -TARGET_SCRIPT="$REPO_DIR/scripts/digital_wellbeing/music_parallelism.sh" +TARGET_SCRIPT="$REPO_DIR/scripts/periodic_background/digital_wellbeing/music_parallelism.sh" fail() { printf 'FAIL: %s\n' "$1" >&2 diff --git a/linux_configuration/tests/test_usage_monitoring_installer_efficiency.sh b/linux_configuration/tests/test_usage_monitoring_installer_efficiency.sh index d93ffd2d..0f660e63 100755 --- a/linux_configuration/tests/test_usage_monitoring_installer_efficiency.sh +++ b/linux_configuration/tests/test_usage_monitoring_installer_efficiency.sh @@ -5,7 +5,7 @@ set -euo pipefail SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd) REPO_DIR=$(cd -- "$SCRIPT_DIR/.." && pwd) -INSTALLER="$REPO_DIR/scripts/system-maintenance/bin/install_usage_monitoring.sh" +INSTALLER="$REPO_DIR/scripts/periodic_background/system-maintenance/bin/install_usage_monitoring.sh" fail() { printf 'FAIL: %s\n' "$1" >&2