R-306: --preflight-only writes no state
_state_put and _state_mark are no-ops under --preflight-only as well as --dry-run, so the banner "no state written" is true and the dnsmasq ownership answer is recorded only by the real install's own preflight. The log says "would be recorded at install" on a preflight-only run. scripts/test_hostinstall.py: test_preflight_only_writes_no_state (+ its control and a no-other-writer check). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
This commit is contained in:
@@ -11,7 +11,7 @@ functions act on are variables the test points into the temp directory. Nothing
|
||||
Where behaviour cannot be isolated, a STATIC test checks the wiring (the function is CALLED, from the
|
||||
right place) — a helper defined and never called is the seam-built-never-wired shape.
|
||||
|
||||
Rows: R-275, R-276, R-881 (uninstall residue).
|
||||
Rows: R-275, R-276, R-881 (uninstall residue); R-306 (--preflight-only writes no state).
|
||||
Run: python3 scripts/test_hostinstall.py
|
||||
"""
|
||||
import os
|
||||
@@ -330,6 +330,48 @@ def test_bundle_list_is_current():
|
||||
assert not new, "the agent bundle installs file(s) this test (and maybe the uninstall) does not know: %s" % new
|
||||
|
||||
|
||||
# ── R-306: --preflight-only writes no state ──────────────────────────────────────────────────────
|
||||
def _state_run(sb, preflight_only, dry=False):
|
||||
return sb.run(prelude(dry=dry) + func("_state_mark") + func("_state_put") + func("_state_get") +
|
||||
'PREFLIGHT_ONLY=%s\nSTATE_DIR="$SB/state"; STATE_FILE="$SB/state/state.json"\n'
|
||||
'_state_put dnsmasq_preexisting yes\n_state_mark preflight\necho "GOT=$(_state_get dnsmasq_preexisting)"\n'
|
||||
% ("true" if preflight_only else "false"))
|
||||
|
||||
|
||||
def test_preflight_only_writes_no_state():
|
||||
sb = Sandbox()
|
||||
try:
|
||||
rc, out = _state_run(sb, preflight_only=True)
|
||||
assert rc == 0, out
|
||||
assert not os.path.exists(sb.path("state", "state.json")), \
|
||||
"--preflight-only wrote state.json: %s" % open(sb.path("state", "state.json")).read()
|
||||
assert "GOT=\n" in out + "\n", out
|
||||
finally:
|
||||
sb.close()
|
||||
|
||||
|
||||
def test_install_preflight_does_write_state():
|
||||
# the control: the same helpers DO write on a real install, or the test above proves nothing.
|
||||
sb = Sandbox()
|
||||
try:
|
||||
rc, out = _state_run(sb, preflight_only=False)
|
||||
assert rc == 0, out
|
||||
assert "GOT=yes" in out, out
|
||||
assert '"preflight"' in open(sb.path("state", "state.json")).read()
|
||||
finally:
|
||||
sb.close()
|
||||
|
||||
|
||||
def test_state_json_has_no_other_writer():
|
||||
# every write must go through the two guarded helpers; a direct write would bypass the guard.
|
||||
bad = [l.strip() for l in SRC.splitlines()
|
||||
if re.search(r'>\s*"?\$STATE_FILE|json\.dump\(d,open\(f', l)
|
||||
and not re.match(r"\s*STATE_FILE=\"\$STATE_FILE\" python3 -c", l)]
|
||||
assert not bad, "state.json written outside _state_mark/_state_put: %s" % bad
|
||||
body = func("step_preflight")
|
||||
assert "_state_put dnsmasq_preexisting" in body, "the ownership record no longer goes through _state_put"
|
||||
|
||||
|
||||
def main():
|
||||
tests = [(n, f) for n, f in sorted(globals().items()) if n.startswith("test_") and callable(f)]
|
||||
fails = 0
|
||||
|
||||
Reference in New Issue
Block a user