From 380eca813bf010e6cd171823011b42482c5a2e02 Mon Sep 17 00:00:00 2001 From: AIOSAI Date: Sat, 11 Jul 2026 12:30:36 -0700 Subject: [PATCH] ai_mail: make 2 non-hermetic tests deterministic (flaked CI on PR659). test_get_pid_cwd_darwin_failure called real lsof (subprocess.run) + test_is_zombie_linux_no_proc called real open(/proc/...) for fixed PIDs 999/99999 -> on runners where that PID exists they returned non-None -> intermittent test(3.10) failures. Mocked subprocess.run + builtins.open so both assert the failure contract without touching real process/proc state. Test-only (test_wake.py). Verified 79 pass 5x deterministic. Pre-existing (not from the Windows campaign). --- CHANGELOG.md | 9 +++++++++ src/aipass/ai_mail/tests/test_wake.py | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8c67069..17f0d9d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,15 @@ PyPI version — not the changelog header. ### Fixed +- **Two more non-hermetic ai_mail tests made deterministic (PR659).** With the full + suite now running on varied CI runners, `test_get_pid_cwd_darwin_failure` and + `test_is_zombie_linux_no_proc` intermittently failed: they called the real `lsof` + (via `subprocess.run`) and real `open("/proc/…")` for a fixed PID (999 / 99999), + so on a runner where that PID happened to exist they returned a non-`None` result + instead of the expected failure. Mocked `subprocess.run` and `builtins.open` so the + tests assert the failure contract without touching real process/`/proc` state. + Test-only; deterministic across repeated runs. + - **Windows CI cross-platform fixes — `windows-setup` green (PR659).** Fixing the telegram collection errors unmasked 14 pre-existing Windows-only failures across six branches. Two root causes. **(1) pid-liveness tests** (ai_mail, flow, hooks, diff --git a/src/aipass/ai_mail/tests/test_wake.py b/src/aipass/ai_mail/tests/test_wake.py index a36c1a01..00063866 100644 --- a/src/aipass/ai_mail/tests/test_wake.py +++ b/src/aipass/ai_mail/tests/test_wake.py @@ -273,6 +273,12 @@ def test_get_pid_cwd_darwin(monkeypatch, tmp_path): def test_get_pid_cwd_darwin_failure(monkeypatch): """macOS: lsof failure returns None.""" + + class FailedResult: + returncode = 1 + stdout = "" + + monkeypatch.setattr(subprocess, "run", lambda *a, **kw: FailedResult()) assert _get_pid_cwd_darwin("999") is None @@ -309,6 +315,14 @@ def test_is_zombie_linux_zombie(monkeypatch, tmp_path): def test_is_zombie_linux_no_proc(monkeypatch): """Missing /proc entry returns False (not zombie, just gone).""" + _real_open = open + + def _fake_open(path, *a, **kw): + if "/proc/99999/" in str(path): + raise FileNotFoundError(path) + return _real_open(path, *a, **kw) + + monkeypatch.setattr("builtins.open", _fake_open) assert _is_zombie_linux(99999) is False