Files
SeedPass/src/tests/test_atomic_write.py
T
thePR0M3TH3ANandClaude Opus 5 527d7be5c5 Make the Tests workflow able to fail on Windows, and skip two POSIX-only tests
The Tests workflow reported SUCCESS on Windows while its own log read
"2 failed, 1114 passed". On Windows a multi-line `run:` block executes under
pwsh, where only the last command decides the step's result -- so
`coverage xml` succeeding hid `pytest` failing. Linux and macOS use bash -e
and did catch it, which is why this was invisible. `shell: bash` on that step
fixes it, and the same hazard is fixed in python-ci.yml's install step. An
audit of every Windows-capable multi-line step found no others; the installer
smoke steps are Unix-guarded and already set -euo pipefail.

A check that cannot go red is worse than no check, because it is trusted --
and this one has been trusted while six Windows tests failed underneath it.

Two of those six are now skipped on Windows: they assert POSIX mode 0o600,
which cannot hold where os.chmod only toggles a read-only flag and st_mode
reads back 0o666. Skipped rather than relaxed, because the property is real
and a weakened assertion would answer it falsely. Whether these files -- the
semantic index among them, which holds stored secrets -- are actually
protected from other users on Windows is an ACL question, now recorded.

The remaining four are TUI tests that assume POSIX paths. They are recorded
rather than patched: reproducing them needs a Windows host, and guessing at
path normalization and palette-argument parsing would mean changing tests to
match an assumption rather than a behaviour. They also interact with the
undeclared-textual finding -- those tests SKIP everywhere except Windows, the
one platform they were not written for.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01Vtx94nXDmNgXEeThUZP4QN
2026-08-20 10:37:35 -04:00

106 lines
3.2 KiB
Python

import json
import pytest
from multiprocessing import Process
import sys
from pathlib import Path
from utils.atomic_write import atomic_write
def _writer(path: Path, content: dict, loops: int) -> None:
for _ in range(loops):
atomic_write(path, lambda f: json.dump(content, f), mode="w")
def test_atomic_write_concurrent(tmp_path: Path) -> None:
"""Concurrent writers should not leave partial files."""
file_path = tmp_path / "data.json"
contents = [{"proc": i} for i in range(5)]
procs = [
Process(target=_writer, args=(file_path, content, 50)) for content in contents
]
for p in procs:
p.start()
for p in procs:
p.join()
final_text = file_path.read_text()
final_obj = json.loads(final_text)
assert final_obj in contents
def test_atomic_write_cleanup_on_failure(tmp_path: Path) -> None:
"""Temporary file should be cleaned up if write fails."""
dest_path = tmp_path / "dest.txt"
# Ensure directory is empty initially
assert list(tmp_path.iterdir()) == []
def failing_writer(f) -> None:
# Verify temp file exists while writing
# There should be exactly one file in the dir now
files = list(tmp_path.iterdir())
assert len(files) == 1
f.write("partial data")
raise RuntimeError("Write failed")
with pytest.raises(RuntimeError, match="Write failed"):
atomic_write(dest_path, failing_writer)
# Verify directory is empty again (temp file deleted)
assert list(tmp_path.iterdir()) == []
# Verify destination file was NOT created
assert not dest_path.exists()
def test_atomic_write_preserves_existing_on_failure(tmp_path: Path) -> None:
"""Existing file should not be overwritten if write fails."""
dest_path = tmp_path / "existing.txt"
dest_path.write_text("original content")
# There should be 1 file initially
assert len(list(tmp_path.iterdir())) == 1
def failing_writer(f) -> None:
# There should be 2 files now (original + temp)
assert len(list(tmp_path.iterdir())) == 2
raise RuntimeError("Write failed")
with pytest.raises(RuntimeError):
atomic_write(dest_path, failing_writer)
# Should revert to 1 file
assert len(list(tmp_path.iterdir())) == 1
assert dest_path.read_text() == "original content"
@pytest.mark.skipif(
sys.platform == "win32",
reason=(
"POSIX mode bits do not exist on Windows: os.chmod only toggles the "
"read-only flag and st_mode reads back 0o666, so this assertion cannot "
"hold there. It is SKIPPED rather than relaxed because the property it "
"checks is real -- whether these files are protected from other users "
"on Windows is an open question about ACLs, recorded in TODO.md, and "
"a weakened assertion would answer it falsely."
),
)
def test_atomic_write_permissions(tmp_path: Path) -> None:
"""File permissions should be set to 0o600 (owner read/write only)."""
import stat
test_file = tmp_path / "permissions.txt"
def write_op(f):
f.write("content")
atomic_write(test_file, write_op)
st = test_file.stat()
mode = stat.S_IMODE(st.st_mode)
assert mode == 0o600