fix(installer): fail closed on test enumeration errors
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
# shellcheck source=tools/test-enumeration-assertions.sh
|
||||
source "$ROOT/tools/test-enumeration-assertions.sh"
|
||||
TMP="$(mktemp -d "${TMPDIR:-/tmp}/mosaic-next-install-test-XXXXXX")"
|
||||
trap 'rm -rf "$TMP"' EXIT
|
||||
export TMPDIR="$TMP/runtime-tmp"
|
||||
@@ -15,6 +17,31 @@ STATE="$TMP/state"
|
||||
LOG="$TMP/npm.log"
|
||||
mkdir -p "$FAKE_BIN" "$HOME_DIR" "$STATE"
|
||||
|
||||
if [[ "${MOSAIC_TEST_ENUMERATION_FAILURE_CHILD:-0}" != "1" ]]; then
|
||||
printf '[test] enumeration failure cannot mask a planted in-progress transaction\n'
|
||||
set +e
|
||||
if [[ "$(/usr/bin/id -u)" -eq 0 ]]; then
|
||||
enumeration_control_output="$(
|
||||
su -s /bin/bash nobody -c \
|
||||
"TMPDIR=/tmp MOSAIC_TEST_ENUMERATION_FAILURE_CHILD=1 bash '$0'" 2>&1
|
||||
)"
|
||||
enumeration_control_status=$?
|
||||
else
|
||||
enumeration_control_output="$(MOSAIC_TEST_ENUMERATION_FAILURE_CHILD=1 bash "$0" 2>&1)"
|
||||
enumeration_control_status=$?
|
||||
fi
|
||||
set -e
|
||||
printf '%s\n' "$enumeration_control_output" > "$TMP/enumeration-failure-control.log"
|
||||
if [[ "$enumeration_control_status" -eq 0 ]]; then
|
||||
echo '[test] FAIL: planted in-progress transaction plus failed enumeration passed the full suite' >&2
|
||||
exit 1
|
||||
fi
|
||||
grep -qF '[test] ERROR: P2 fault-state enumeration failed' "$TMP/enumeration-failure-control.log" || {
|
||||
echo '[test] FAIL: failed fault-state enumeration was not named' >&2
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
|
||||
# Model the supported non-root/glibc target explicitly even when this harness
|
||||
# itself runs as root in Alpine/BusyBox CI.
|
||||
cat > "$FAKE_BIN/id" <<'FAKE_ID'
|
||||
@@ -518,9 +545,9 @@ fi
|
||||
if [[ "$(cat "$TMP/canary-observed" 2>/dev/null || true)" != "$canary" ]]; then
|
||||
echo 'credential canary positive control was not exercised' >&2; exit 1
|
||||
fi
|
||||
if find "$TMPDIR" -maxdepth 1 -type f \( -name 'mosaic-phase-redacted.*' -o -name 'mosaic-post-redacted.*' \) -print -quit | grep -q .; then
|
||||
echo 'redacted diagnostic staging file survived normal completion' >&2; exit 1
|
||||
fi
|
||||
test_assert_find_empty 'redacted diagnostic staging files' \
|
||||
"$TMPDIR" -maxdepth 1 -type f \
|
||||
\( -name 'mosaic-phase-redacted.*' -o -name 'mosaic-post-redacted.*' \) || exit 1
|
||||
|
||||
printf '[test] framework nested capture redacts the same canary and URL variants\n'
|
||||
framework_test_home="$TMP/framework-redact-home"
|
||||
@@ -577,9 +604,15 @@ for phase in P2 P3 P4 P5 P6 P7 P8; do
|
||||
[[ -s "$LOG" ]] || { echo "$phase fault never entered the real action path" >&2; exit 1; }
|
||||
[[ "$(tree_fingerprint "$HOME_DIR")" == "$before" ]] || { echo "$phase real rollback mismatch" >&2; exit 1; }
|
||||
grep -q "phase=$phase" "$TMP/fault-$phase.log"
|
||||
if find "$TMP/fault-$phase" -type f -exec grep -l '"status"[[:space:]]*:[[:space:]]*"in-progress"' {} + 2>/dev/null | grep -q .; then
|
||||
echo "$phase left an in-progress transaction" >&2; exit 1
|
||||
if [[ "${MOSAIC_TEST_ENUMERATION_FAILURE_CHILD:-0}" == "1" && "$phase" == "P2" ]]; then
|
||||
mkdir -p "$TMP/fault-$phase/blocked"
|
||||
printf '{"status":"in-progress"}\n' > "$TMP/fault-$phase/blocked/planted-in-progress.json"
|
||||
chmod 0666 "$TMP/fault-$phase/blocked/planted-in-progress.json"
|
||||
chmod 0100 "$TMP/fault-$phase/blocked"
|
||||
trap 'chmod 0700 "$TMP/fault-P2/blocked" 2>/dev/null || true; rm -rf "$TMP"' EXIT
|
||||
fi
|
||||
test_assert_no_file_content_match "$phase fault-state" \
|
||||
'"status"[[:space:]]*:[[:space:]]*"in-progress"' "$TMP/fault-$phase" || exit 1
|
||||
done
|
||||
|
||||
printf '[test] stale projection is preserved while the real fault path acquires a free OS lock\n'
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
set -uo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
# shellcheck source=tools/test-enumeration-assertions.sh
|
||||
source "$ROOT/tools/test-enumeration-assertions.sh"
|
||||
TMP="$(mktemp -d "${TMPDIR:-/tmp}/mosaic-install-state-test.XXXXXX")"
|
||||
trap 'rm -rf "$TMP"' EXIT
|
||||
failures=0
|
||||
@@ -396,7 +398,8 @@ set -e
|
||||
grep -q '^\[P0\] FAIL:.*unsafe context' "$TMP/symlink-target.log" \
|
||||
&& pass_case 'symlinked rollback parent was rejected by P0' \
|
||||
|| fail_case 'symlinked rollback parent lacked an attributable P0 failure'
|
||||
[[ -z "$(find "$symlink_outside" -mindepth 1 -print -quit)" ]] || fail_case 'symlink target was mutated'
|
||||
test_assert_find_empty 'symlink target mutation check' "$symlink_outside" -mindepth 1 \
|
||||
|| fail_case 'symlink target was mutated or could not be enumerated'
|
||||
|
||||
printf '[test] case: journal initialization failure is fatal before mutation\n'
|
||||
journal_home="$TMP/journal-failure/home"
|
||||
|
||||
@@ -1 +1 @@
|
||||
4cd391b0974d3cce6c2a98455420d45bc2a04cb624e3c4bf43a813b8e28693e6 install.sh
|
||||
e59cb441a2f37ae9150f8eae470238e9d858a1816df93343d9784a6796676096 install.sh
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env bash
|
||||
# Fail-closed filesystem-enumeration assertions for shell test harnesses.
|
||||
|
||||
# Usage: test_assert_find_empty <label> <find arguments...>
|
||||
test_assert_find_empty() {
|
||||
local label="$1"
|
||||
shift
|
||||
local inventory
|
||||
|
||||
inventory="$(mktemp "${TMPDIR:-/tmp}/mosaic-test-find.XXXXXX")" || {
|
||||
printf '[test] ERROR: %s inventory allocation failed\n' "$label" >&2
|
||||
return 2
|
||||
}
|
||||
|
||||
if ! find "$@" -print0 > "$inventory"; then
|
||||
rm -f "$inventory"
|
||||
printf '[test] ERROR: %s enumeration failed\n' "$label" >&2
|
||||
return 2
|
||||
fi
|
||||
|
||||
if [[ -s "$inventory" ]]; then
|
||||
rm -f "$inventory"
|
||||
printf '[test] FAIL: %s was not empty\n' "$label" >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
rm -f "$inventory"
|
||||
return 0
|
||||
}
|
||||
|
||||
# Usage: test_assert_no_file_content_match <label> <extended-regex> <find roots/options...>
|
||||
test_assert_no_file_content_match() {
|
||||
local label="$1"
|
||||
local pattern="$2"
|
||||
shift 2
|
||||
local inventory path grep_status result=0
|
||||
|
||||
inventory="$(mktemp "${TMPDIR:-/tmp}/mosaic-test-find.XXXXXX")" || {
|
||||
printf '[test] ERROR: %s inventory allocation failed\n' "$label" >&2
|
||||
return 2
|
||||
}
|
||||
|
||||
if ! find "$@" -type f -print0 > "$inventory"; then
|
||||
rm -f "$inventory"
|
||||
printf '[test] ERROR: %s enumeration failed\n' "$label" >&2
|
||||
return 2
|
||||
fi
|
||||
|
||||
while IFS= read -r -d '' path; do
|
||||
grep_status=0
|
||||
grep -Eq -- "$pattern" "$path" || grep_status=$?
|
||||
if [[ "$grep_status" -eq 0 ]]; then
|
||||
result=1
|
||||
break
|
||||
fi
|
||||
if [[ "$grep_status" -ne 1 ]]; then
|
||||
result=2
|
||||
break
|
||||
fi
|
||||
done < "$inventory"
|
||||
|
||||
rm -f "$inventory"
|
||||
if [[ "$result" -eq 1 ]]; then
|
||||
printf '[test] FAIL: %s contained a forbidden match\n' "$label" >&2
|
||||
return 1
|
||||
fi
|
||||
if [[ "$result" -eq 2 ]]; then
|
||||
printf '[test] ERROR: %s content inspection failed\n' "$label" >&2
|
||||
return 2
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
# shellcheck source=tools/test-enumeration-assertions.sh
|
||||
source "$ROOT/tools/test-enumeration-assertions.sh"
|
||||
TMP="$(mktemp -d "${TMPDIR:-/tmp}/mosaic-fetch-contract.XXXXXX")"
|
||||
trap 'rm -rf "$TMP"' EXIT
|
||||
FAKE_BIN="$TMP/bin"; mkdir -p "$FAKE_BIN"
|
||||
@@ -41,7 +43,7 @@ empty_sha="$(printf '' | sha256sum | awk '{print $1}')"
|
||||
mkdir -p "$TMP/downloads"
|
||||
output="$(TMPDIR="$TMP/downloads" PATH="$FAKE_BIN:$PATH" bash "$ROOT/tools/verified-installer-fetch.sh" fixture://ok "$ok_sha" -- marker)"
|
||||
[[ "$output" == 'executed:marker' ]]
|
||||
[[ -z "$(find "$TMP/downloads" -mindepth 1 -print -quit)" ]]
|
||||
test_assert_find_empty 'verified-installer temporary downloads' "$TMP/downloads" -mindepth 1
|
||||
printf '[test] PASS: digest-pinned fetched artifact executes and its temporary body is removed\n'
|
||||
|
||||
for row in 'fixture://empty empty-body' 'fixture://failed failed-fetch'; do
|
||||
|
||||
Reference in New Issue
Block a user