From f5125f3c0742c0f4e36ee12bb3555e5b7b9d0f66 Mon Sep 17 00:00:00 2001 From: Xubin Ren <52506698+Re-bin@users.noreply.github.com> Date: Mon, 17 Aug 2026 03:32:07 +0800 Subject: [PATCH] test(gateway): isolate lifecycle lock behavior --- .github/workflows/ci.yml | 9 ++++----- tests/gateway/test_runtime.py | 5 +++++ 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a37495eef..758a73008 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -96,9 +96,9 @@ jobs: os: windows-latest python-version: "3.14" coverage: false - # Process lifecycle tests run serially below. Keep them out of - # xdist so workers never share Windows console or process state. - pytest_args: "-n 2 --dist loadfile --ignore=tests/gateway/test_runtime.py --ignore=tests/tools/test_exec_platform.py" + # Real PowerShell/process-tree tests run serially below. Keep + # them out of xdist so workers never share a Windows console. + pytest_args: "-n 2 --dist loadfile --ignore=tests/tools/test_exec_platform.py" steps: - uses: actions/checkout@v4 @@ -148,11 +148,10 @@ jobs: ${{ matrix.pytest_args }} --durations=25 --durations-min=1.0 - - name: Run Windows lifecycle compatibility tests + - name: Run Windows process compatibility tests if: runner.os == 'Windows' run: >- uv run --no-sync python -m pytest - tests/gateway/test_runtime.py tests/tools/test_exec_platform.py --durations=25 --durations-min=1.0 diff --git a/tests/gateway/test_runtime.py b/tests/gateway/test_runtime.py index 7b6306d34..b827a7ee1 100644 --- a/tests/gateway/test_runtime.py +++ b/tests/gateway/test_runtime.py @@ -206,6 +206,7 @@ def test_stop_reaps_an_owned_child_without_consuming_the_shutdown_timeout( def test_concurrent_background_starts_create_only_one_process(tmp_path, monkeypatch): first_spawned = threading.Event() release_first = threading.Event() + lifecycle_lock = threading.Lock() calls: list[list[str]] = [] def fake_popen(command, **_kwargs): @@ -231,6 +232,10 @@ def test_concurrent_background_starts_create_only_one_process(tmp_path, monkeypa for runtime in (first, second): monkeypatch.setattr(runtime, "_is_pid_running", lambda _pid: True) monkeypatch.setattr(runtime, "_process_identity", lambda _pid: 12345) + # Exercise the runtime's critical section without mixing an OS-level + # file lock into a same-process thread scheduling test. FileLock is + # independently responsible for cross-process portability. + monkeypatch.setattr(runtime, "_lifecycle_lock", lambda: lifecycle_lock) results = [] first_thread = threading.Thread(