diff --git a/tests/test_gcp_leoclean_service_environment.py b/tests/test_gcp_leoclean_service_environment.py index 449ed8d..57c37ae 100644 --- a/tests/test_gcp_leoclean_service_environment.py +++ b/tests/test_gcp_leoclean_service_environment.py @@ -2,6 +2,7 @@ import json import os import subprocess import sys +import time from collections.abc import Mapping from pathlib import Path @@ -14,6 +15,27 @@ def environment_block(environment: Mapping[str, str]) -> bytes: return b"\0".join(f"{key}={value}".encode() for key, value in environment.items()) + b"\0" +def wait_for_process_environment( + process: subprocess.Popen[bytes], + expected: Mapping[str, str], + *, + timeout_seconds: float = 5.0, +) -> None: + deadline = time.monotonic() + timeout_seconds + while time.monotonic() < deadline: + if process.poll() is not None: + pytest.fail("environment fixture process exited before becoming readable") + try: + observed = verifier.parse_environment(Path(f"/proc/{process.pid}/environ").read_bytes()) + except (OSError, verifier.VerificationError): + time.sleep(0.01) + continue + if observed == expected: + return + time.sleep(0.01) + pytest.fail("environment fixture process did not become readable") + + def test_all_expected_fields_pass_and_receipt_contains_no_values() -> None: environment = verifier.expected_environment() environment.update({"HOME": "/home/teleo", "LANG": "C.UTF-8"}) @@ -234,6 +256,7 @@ def test_cli_reads_real_process_environment_and_detects_effective_conflict( stderr=subprocess.DEVNULL, ) try: + wait_for_process_environment(good_process, expected) assert verifier.main(["--pid", str(good_process.pid)]) == 0 good_output = capsys.readouterr() assert good_output.err == "" @@ -253,6 +276,7 @@ def test_cli_reads_real_process_environment_and_detects_effective_conflict( stderr=subprocess.DEVNULL, ) try: + wait_for_process_environment(bad_process, conflicting) assert verifier.main(["--pid", str(bad_process.pid)]) == 1 bad_output = capsys.readouterr() receipt = json.loads(bad_output.out)