mirror of
https://github.com/DeusData/codebase-memory-mcp.git
synced 2026-11-04 10:48:20 +00:00
fix(test): isolate smoke harness daemon runtime
scripts/smoke-test.sh retires the account daemon from seven call sites, but its wrappers sandbox only HOME/TMPDIR/CBM_CACHE_DIR and only CBM_RUNTIME_DIR moves the daemon rendezvous, so every retirement reached the operator's live daemon. Source scripts/test-runtime.sh so every product process runs under a harness-owned runtime and cache, and clean that root up from the EXIT trap. Add tests/test_smoke_runtime_isolation_contract.sh, which fails before this change, and wire it into scripts/test.sh. Part of #1696. Signed-off-by: Anton Standrik <astandrik@yandex-team.ru>
This commit is contained in:
1 parent
def38f3ebc
commit
183cd727be
3 files changed
+99
-3
No files matched your search
+14
-3
@@ -22,6 +22,8 @@ they stage the release fixture, start the fixture server, and sandbox
|
||||
HOME/TEMP/agent-config destinations. Called bare, the download/checksum/
|
||||
install-script phases (12-13) SKIP for lack of a fixture server, and the run
|
||||
mutates the REAL profile — the venue-parity contract forbids that in any venue.
|
||||
The daemon runtime and cache are private to the run either way: every product
|
||||
process is started under a CBM_RUNTIME_DIR/CBM_CACHE_DIR this harness owns.
|
||||
|
||||
Arguments:
|
||||
<binary-path> product binary to smoke
|
||||
@@ -41,6 +43,15 @@ if [ -n "$SMOKE_MODE" ] && [ "$SMOKE_MODE" != "--agent-config-only" ]; then
|
||||
fi
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]:-$0}")/.." && pwd)"
|
||||
|
||||
# Every product process below — the phases, the install/update E2E and the
|
||||
# daemon retirements — must reach a daemon rendezvous this run owns. Only
|
||||
# CBM_RUNTIME_DIR moves that rendezvous; the wrappers' HOME/TMPDIR/CBM_CACHE_DIR
|
||||
# sandbox does not, so without this the retirements land on the operator's live
|
||||
# account daemon (#1691, #1696).
|
||||
# shellcheck source=test-runtime.sh
|
||||
source "$REPO_ROOT/scripts/test-runtime.sh"
|
||||
cbm_test_runtime_init
|
||||
|
||||
smoke_mktemp_file() {
|
||||
if [ -n "${SMOKE_TEMP_ROOT:-}" ]; then
|
||||
mktemp "$SMOKE_TEMP_ROOT/cbm-smoke.XXXXXX"
|
||||
@@ -100,8 +111,8 @@ copy_smoke_binary() {
|
||||
cp "$BINARY" "$destination"
|
||||
}
|
||||
|
||||
# Retire the shared account daemon (if one is running) and wait until it
|
||||
# reports not-running. Install/uninstall flows leave an ephemeral daemon
|
||||
# Retire this run's private account daemon (if one is running) and wait until
|
||||
# it reports not-running. Install/uninstall flows leave an ephemeral daemon
|
||||
# draining asynchronously whose mapped generation backing and open logs
|
||||
# block rm on Windows (POSIX rm doesn't care) — so every cleanup of a
|
||||
# fixture HOME that received an install, and the final cache removal, must
|
||||
@@ -149,7 +160,7 @@ CODEX_LIFECYCLE_HOME=""
|
||||
if command -v cygpath &>/dev/null; then
|
||||
TMPDIR=$(cygpath -m "$TMPDIR")
|
||||
fi
|
||||
trap 'smoke_rmtree "$TMPDIR" "${DRYRUN_HOME:-}" "${CODEX_LIFECYCLE_HOME:-}"' EXIT
|
||||
trap 'smoke_rmtree "$TMPDIR" "${DRYRUN_HOME:-}" "${CODEX_LIFECYCLE_HOME:-}"; cbm_test_runtime_cleanup "$BINARY"' EXIT
|
||||
|
||||
CLI_STDERR=$(smoke_mktemp_file)
|
||||
# 10 of the cli call sites assign directly (VAR=$(cli ...)). Under
|
||||
|
||||
@@ -272,6 +272,9 @@ bash "$ROOT/tests/test_release_gate_chain_contract.sh"
|
||||
echo "=== Step 0t: test runtime isolation contract (#1691) ==="
|
||||
bash "$ROOT/tests/test_runtime_isolation_contract.sh"
|
||||
|
||||
echo "=== Step 0t2: smoke harness runtime isolation contract (#1696) ==="
|
||||
bash "$ROOT/tests/test_smoke_runtime_isolation_contract.sh"
|
||||
|
||||
echo "=== Step 0u: shell line-ending contract ==="
|
||||
bash "$ROOT/tests/test_shell_line_endings.sh"
|
||||
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Runtime-isolation contract for the smoke harness (#1696, follow-up to #1691).
|
||||
#
|
||||
# scripts/smoke-test.sh is the process that actually starts the product during
|
||||
# a smoke run, and it retires "the account daemon" seven times through
|
||||
# `daemon stop`. Its wrappers sandbox HOME/XDG/TMPDIR and CBM_CACHE_DIR, but
|
||||
# only CBM_RUNTIME_DIR moves the daemon rendezvous (docs/CONFIGURATION.md), so
|
||||
# without a private runtime every one of those stops lands on the operator's
|
||||
# live daemon. Drive the harness with an environment-probe fixture and require
|
||||
# that no product process ever receives the caller's runtime or cache.
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
WORKDIR="$(mktemp -d)"
|
||||
trap 'rm -rf "$WORKDIR"' EXIT
|
||||
|
||||
fail() {
|
||||
echo "FAIL: $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
normalize_path() {
|
||||
local path=${1%$'\r'}
|
||||
if command -v cygpath >/dev/null 2>&1; then
|
||||
cygpath -u "$path" 2>/dev/null && return 0
|
||||
fi
|
||||
printf '%s\n' "${path//\\//}"
|
||||
}
|
||||
|
||||
ENV_PROBE="$WORKDIR/environment-probe"
|
||||
cat > "$ENV_PROBE" <<'EOF'
|
||||
#!/usr/bin/env bash
|
||||
printf '%s\t%s\n' "${CBM_CACHE_DIR-}" "${CBM_RUNTIME_DIR-}" >> "$CBM_SMOKE_ENV_PROBE"
|
||||
case "${1-}" in
|
||||
--version) echo "v0.0.0-probe"; exit 0 ;;
|
||||
daemon) [[ "${2-}" == status ]] && exit 1; exit 0 ;;
|
||||
esac
|
||||
echo '{}'
|
||||
exit 0
|
||||
EOF
|
||||
chmod +x "$ENV_PROBE"
|
||||
|
||||
CALLER_CACHE="$WORKDIR/caller-cache"
|
||||
CALLER_RUNTIME="$WORKDIR/caller-runtime"
|
||||
ENV_LOG="$WORKDIR/environment.log"
|
||||
mkdir -p "$CALLER_CACHE" "$CALLER_RUNTIME"
|
||||
|
||||
# The fixture answers nothing beyond --version, so the smoke fails early; only
|
||||
# the environment it handed to the product is under test here.
|
||||
CBM_CACHE_DIR="$CALLER_CACHE" \
|
||||
CBM_RUNTIME_DIR="$CALLER_RUNTIME" \
|
||||
CBM_SMOKE_ENV_PROBE="$ENV_LOG" \
|
||||
"$ROOT/scripts/smoke-test.sh" "$ENV_PROBE" > "$WORKDIR/smoke.out" 2>&1 || true
|
||||
|
||||
[[ -s "$ENV_LOG" ]] || fail "smoke-test did not execute the environment-probe fixture"
|
||||
|
||||
CALLER_CACHE_NORMALIZED=$(normalize_path "$CALLER_CACHE")
|
||||
CALLER_RUNTIME_NORMALIZED=$(normalize_path "$CALLER_RUNTIME")
|
||||
private_root=""
|
||||
while IFS=$'\t' read -r child_cache_raw child_runtime_raw; do
|
||||
child_cache=$(normalize_path "$child_cache_raw")
|
||||
child_runtime=$(normalize_path "$child_runtime_raw")
|
||||
if [[ -z "$child_runtime" || "$child_runtime" == "$CALLER_RUNTIME_NORMALIZED" ]]; then
|
||||
fail "smoke-test exposed the caller CBM_RUNTIME_DIR to a product process"
|
||||
fi
|
||||
if [[ -z "$child_cache" || "$child_cache" == "$CALLER_CACHE_NORMALIZED" ]]; then
|
||||
fail "smoke-test exposed the caller CBM_CACHE_DIR to a product process"
|
||||
fi
|
||||
if [[ "${child_runtime%/*}" != "${child_cache%/*}" ||
|
||||
"${child_runtime##*/}" != "runtime" || "${child_cache##*/}" != "cache" ]]; then
|
||||
fail "smoke runtime/cache were not isolated beneath one private root"
|
||||
fi
|
||||
if [[ -n "$private_root" && "$private_root" != "${child_runtime%/*}" ]]; then
|
||||
fail "smoke-test switched private roots mid-run"
|
||||
fi
|
||||
private_root="${child_runtime%/*}"
|
||||
done < "$ENV_LOG"
|
||||
|
||||
[[ ! -e "$private_root" ]] || fail "smoke-test left its private root behind: $private_root"
|
||||
|
||||
echo "PASS: smoke harness isolates its daemon runtime and cache from the caller"
|
||||
Reference in new issue
Block a user