From e19fb00276dd45a34c38660fe75867de360228c8 Mon Sep 17 00:00:00 2001 From: Gabriel Brown Date: Wed, 26 Aug 2026 23:22:26 -0400 Subject: [PATCH] Test: Harden dock fixture cleanup --- tests/quickshell/dock-position-contract | 85 ++++++++++++++++++++++--- 1 file changed, 77 insertions(+), 8 deletions(-) diff --git a/tests/quickshell/dock-position-contract b/tests/quickshell/dock-position-contract index 348d475..4fc21b6 100755 --- a/tests/quickshell/dock-position-contract +++ b/tests/quickshell/dock-position-contract @@ -76,10 +76,6 @@ assert_source_tree_unchanged() { fi } -work="$(mktemp -d)" -fixture_shell="$work/quickshell" -cp -a "$shell_dir/." "$fixture_shell/" \ - || fail 'could not copy the Quickshell fixture' fixture_pid="" stop_fixture() { [[ -n "$fixture_pid" ]] || return 0 @@ -91,24 +87,97 @@ stop_fixture() { } cleanup() { local status=$? + local fixture_cleanup='pass' + local source_probe_assertions='pass' trap - EXIT HUP INT TERM stop_fixture - rm -rf "$work" - assert_source_tree_unchanged || status=1 + if ! rm -rf -- "$work"; then + printf 'dock position contract: could not remove temporary fixture\n' >&2 + fixture_cleanup='fail' + status=1 + fi + if ! assert_source_tree_unchanged; then + source_probe_assertions='fail' + status=1 + fi + if [[ -n "${DOCK_POSITION_CONTRACT_CLEANUP_PROOF:-}" ]]; then + printf 'fixture-cleanup=%s source-and-probe-assertions=%s\n' \ + "$fixture_cleanup" "$source_probe_assertions" \ + >"$DOCK_POSITION_CONTRACT_CLEANUP_PROOF" || status=1 + fi exit "$status" } + +if ! work="$(mktemp -d)"; then + fail 'could not create a temporary fixture' +fi +[[ -d "$work" ]] || fail 'could not create a temporary fixture' trap cleanup EXIT HUP INT TERM +fixture_shell="$work/quickshell" # These checks are deliberately against this harness. A live settings read or # source-tree probe means the contract itself is unsafe before it maps a panel. probe_name='dock-position-probe.qml' source_write_marker="$(printf 'cat >\"$shell_dir/%s\"' "$probe_name")" -home_marker="$(printf '\044')HOME" +home_dollar="$(printf '\044')" +home_tilde="$(printf '\176')" +home_marker="${home_dollar}HOME" +settings_store_spellings=( + "${home_dollar}HOME/.config/panama/settings.json" + "${home_dollar}{HOME}/.config/panama/settings.json" + "${home_tilde}/.config/panama/settings.json" + "${home_dollar}{XDG_CONFIG_HOME:-${home_dollar}HOME/.config}/panama/settings.json" +) +assert_no_real_settings_reference() { + local marker + for marker in "${settings_store_spellings[@]}"; do + grep -Fq "$marker" "$1" && return 1 + done + return 0 +} +run_settings_path_probes() { + local spelling + local number=0 + for spelling in "${settings_store_spellings[@]}"; do + local fixture="$work/settings-path-$number" + printf 'settings=%s\n' "$spelling" >"$fixture" + assert_no_real_settings_reference "$fixture" \ + && fail "the real-settings guard accepted $spelling" + ((number += 1)) + done + local safe_fixture="$work/settings-path-safe" + printf 'XDG_CONFIG_HOME=%s/config\n' "$work" >"$safe_fixture" + assert_no_real_settings_reference "$safe_fixture" \ + || fail 'the real-settings guard rejected an isolated configuration' +} +run_pre_copy_cleanup_probe() { + [[ "${DOCK_POSITION_CONTRACT_SKIP_PRECOPY_PROBE:-}" == 1 ]] && return + + local proof="$work/pre-copy-cleanup-proof" + if DOCK_POSITION_CONTRACT_INJECT_PRECOPY_FAILURE=1 \ + DOCK_POSITION_CONTRACT_SKIP_PRECOPY_PROBE=1 \ + DOCK_POSITION_CONTRACT_CLEANUP_PROOF="$proof" \ + "$0" >"$work/pre-copy-output" 2>&1; then + fail 'the injected pre-copy failure did not fail' + fi + [[ -r "$proof" ]] \ + || fail 'the injected pre-copy failure did not leave cleanup proof' + grep -Fxq 'fixture-cleanup=pass source-and-probe-assertions=pass' "$proof" \ + || fail 'the injected pre-copy failure skipped cleanup or source/probe assertions' +} unsafe_harness=() grep -Fq "$source_write_marker" "$0" && unsafe_harness+=('writes its probe in the Quickshell source tree') -grep -Fq "$home_marker" "$0" && unsafe_harness+=('reads the user configuration directory') +assert_no_real_settings_reference "$0" || unsafe_harness+=('reads the user configuration directory') (( ${#unsafe_harness[@]} == 0 )) \ || fail "unsafe harness: ${unsafe_harness[*]}" +run_settings_path_probes + +[[ "${DOCK_POSITION_CONTRACT_INJECT_PRECOPY_FAILURE:-}" != 1 ]] \ + || fail 'injected pre-copy failure' +run_pre_copy_cleanup_probe + +cp -a "$shell_dir/." "$fixture_shell/" \ + || fail 'could not copy the Quickshell fixture' # ── 3, 4, 6. What can be read ───────────────────────────────────────────────