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 the accompanying evidence artifacts for the full list. - 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_music_parallelism.sh test_setup_dns_blocker.sh test_usage_monitoring_installer_efficiency.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 # Tests that assume Arch: they exercise the pacman wrapper, makepkg wrapper # and hosts-guard hooks, so they need an Arch userland rather than Ubuntu. # They run as root here, which is what lets them touch /etc safely — the # container is disposable. arch-tests: runs-on: ubuntu-latest container: image: archlinux:base-devel # test_i3blocks_efficiency.sh counts execve calls with strace, which needs # ptrace. Without these the trace file is never produced. options: --cap-add=SYS_PTRACE --security-opt seccomp=unconfined steps: # base-devel ships none of these: git (actions/checkout needs it), strace # (execve counting), or jq (the claude_usage block parses its cache with # it, and without jq that block degrades to "no data" and its assertions # fail). - name: Install dependencies run: pacman -Sy --noconfirm --needed git strace jq - uses: actions/checkout@v4 # The complete Arch-dependent set. All eight verified locally in # `docker run --cap-add=SYS_PTRACE archlinux:base-devel`. # # test_security_hardening.sh inspects a configured machine (chattr flags, # systemd guard units, /usr/local payloads). It detects that it is not on # one and reports those checks as skipped, while still running its # repository checks — so it is meaningful here AND on the real host, # where it continues to fail loudly if a guard unit is down. - name: Run Arch-specific shell tests run: | set -euo pipefail tests=( test_hosts_file_monitor.sh test_hosts_guard_pacman_integration.sh test_i3blocks_efficiency.sh test_makepkg_capped.sh test_makepkg_wrapper.sh test_pacman_wrapper_security.sh test_security_hardening.sh test_shutdown_timer_monitor.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