Files
archy/scripts/test-gashboard-isolated.sh
T
archipelago 64f0bc36dc test: qualify Gashboard through fixed backend isolation target
Add ARCHY_TEST_PACKAGE=gashboard with hardcoded Node test entry, synthetic data settings, private network/PID namespace and wallet/container/app tmpfs masks. Reject arbitrary command arguments and conflicting fixture modes; keep existing Rust/C01/container paths intact. Retain only the Rust runner DAC traversal capability for the read-only worktree.

Six runner regressions pass, including existing modes; update the existing C01 test sudo mock for its exec-profile inventory call. Nine actual Gashboard API regressions pass in the new isolated systemd namespace with patched Zod/Express dependencies. Initial namespace file-access failure preserved before aligning traversal capability. No production app entry or installed service was run.
2026-11-09 17:04:12 -05:00

35 lines
2.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# Fixed Node API qualification target. Invoked only by test-backend-isolated.sh.
set -euo pipefail
[[ $# == 1 ]] || { echo 'Expected repository root only' >&2; exit 2; }
[[ ${ARCHY_TEST_ISOLATOR:-systemd} == systemd ]] || {
echo 'Gashboard tests require the systemd fixture namespace' >&2; exit 2;
}
REPO=$(cd "$1" && pwd)
node_binary=$(realpath -- "$(command -v node)")
[[ -x $node_binary && -f $REPO/scripts/tests/gashboard-isolated-entry.mjs &&
-d $REPO/docker/gashboard/apps/api/node_modules/tsx ]] || {
echo 'Install the frozen Gashboard dependencies before isolated testing' >&2; exit 2;
}
command -v systemd-run >/dev/null
command -v unshare >/dev/null
command -v setpriv >/dev/null
sudo -n true || { echo 'Isolated Gashboard tests require noninteractive sudo for namespaces' >&2; exit 1; }
unit="archy-gashboard-tests-$(date +%s)-$$"
# Match the Rust runner's wallet, bus, container, PID and network boundaries.
# Retain only the Rust runner's DAC traversal capability for the read-only home/worktree.
# Also hide container app paths, including default Gashboard data/provider paths.
filesystems='/run:rw /var/lib/archipelago:rw /var/lib/containers:rw /root:rw /var/lib/tor:rw,size=64m /tmp:rw,size=512M,mode=1777 /var/tmp:rw,size=64M,mode=1777 /data:rw,size=64M /app:rw,size=16M'
sudo -n systemd-run --unit="$unit" --wait --pipe --collect \
--property=RuntimeMaxSec=120 --property=CPUQuota=100% --property=MemoryMax=2G --property=MemorySwapMax=0 \
--property="WorkingDirectory=$REPO/docker/gashboard/apps/api" \
--property="BindReadOnlyPaths=$REPO" \
--property=PrivateNetwork=yes --property=PrivateTmp=no --property=PrivateDevices=yes \
--property=ProtectSystem=strict --property=ProtectHome=read-only \
--property=NoNewPrivileges=yes \
--property="TemporaryFileSystem=$filesystems" \
--setenv=ARCHY_TEST_ISOLATED=1 --setenv=NODE_OPTIONS= --setenv=TSX_DISABLE_CACHE=1 \
/usr/bin/unshare --pid --fork --mount-proc --kill-child \
/usr/bin/setpriv --bounding-set=-all,+dac_override \
"$node_binary" "$REPO/scripts/tests/gashboard-isolated-entry.mjs"