From d4c097531dea580f729fa70c3ce23d907626d3db Mon Sep 17 00:00:00 2001 From: tzhouam Date: Fri, 18 Sep 2026 18:49:01 +0800 Subject: [PATCH] [edge-infer W8] tests/edge/local: selector event loop on Windows for the async e2e tests pytest-asyncio builds its loops from the current policy; on win32 that is the Proactor loop, which zmq.asyncio cannot use, so the engine/serving e2e hung at the first async socket (30 min, no output, GPU idle) while the accept CLI -- which installs WindowsSelectorEventLoopPolicy itself -- passed on the same venv. The conftest now installs the same policy and provides it as pytest-asyncio's event_loop_policy fixture. Co-Authored-By: Claude Fable 5.1 --- tests/edge/local/conftest.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/edge/local/conftest.py b/tests/edge/local/conftest.py index 2035c12c4..2ce6de300 100644 --- a/tests/edge/local/conftest.py +++ b/tests/edge/local/conftest.py @@ -11,7 +11,9 @@ one test module that does need real weights says so and skips. from __future__ import annotations +import asyncio import json +import sys from pathlib import Path import pytest @@ -152,3 +154,24 @@ def cpu_only_box() -> HardwareProfile: @pytest.fixture def laptop_profile() -> HardwareProfile: return blackwell_laptop() + + +# [edge-infer W8] The async tests in this directory (engine and serving e2e) +# talk to the engine over zmq.asyncio, which needs a selector event loop. +# Python on Windows defaults to the Proactor loop, and pytest-asyncio builds +# its loops from the current policy, so on win32 the e2e hung silently at the +# first async socket (measured: 30 min with no output, GPU idle) while the +# `accept` CLI -- which installs the selector policy itself -- passed on the +# same venv. Same policy here, set for the whole session. +if sys.platform == "win32": + from vllm_omni.edge.local.cli import _use_selector_event_loop_on_windows + + _use_selector_event_loop_on_windows() + + +@pytest.fixture(scope="session") +def event_loop_policy(): + """pytest-asyncio builds every loop from this policy; make it the selector one on Windows.""" + if sys.platform == "win32": + return asyncio.WindowsSelectorEventLoopPolicy() + return asyncio.get_event_loop_policy()