Files
vllm-omni/tests/helpers/fixtures/runtime.py
T
2026-08-29 18:42:33 +08:00

155 lines
5.1 KiB
Python

# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the vLLM-Omni project
"""Runtime fixtures (OmniRunner / OmniServer). Imports are deferred to fixture time.
Loading ``tests.helpers.runtime`` at plugin import time (before session fixtures)
pulls in vLLM/vllm_omni too early and breaks initialization order vs the legacy
monolithic conftest. Defer imports until fixtures run so session fixtures in
``tests.helpers.fixtures.config`` run first. Server/runner helpers live in
``tests.helpers.runtime``; request clients live in ``tests.helpers.client``.
"""
from __future__ import annotations
import threading
from collections.abc import Generator
from typing import TYPE_CHECKING, Any
import pytest
if TYPE_CHECKING:
from tests.helpers.runtime import OmniRunner, OmniServer
omni_fixture_lock = threading.Lock()
@pytest.fixture
def _normalized_hardware_marks(request: pytest.FixtureRequest):
"""Dummy carrier for mixed-``num_cards`` ``@hardware_test`` mark normalization.
Pytest has no API to clone an item and only change marks. ``@hardware_test``
therefore parametrizes this fixture (``indirect=True``) so each collected
item gets one platform's SKU and ``cards_{n}`` without changing test
signatures. The returned platform id is unused by test bodies.
"""
return request.param
@pytest.fixture(scope="function")
def omni_server_function(
request: pytest.FixtureRequest,
run_level: str,
) -> Generator[OmniServer, Any, None]:
from tests.helpers.runtime import iter_omni_server
yield from iter_omni_server(request, run_level, omni_fixture_lock)
@pytest.fixture(scope="module")
def omni_server(request: pytest.FixtureRequest, run_level: str) -> Generator[OmniServer, Any, None]:
"""Start vLLM-Omni through the standard or stage-CLI launcher.
The fixture stays module-scoped because multi-stage initialization is costly.
The ``use_stage_cli`` flag on ``OmniServerParams`` routes the setup through the
stage-CLI harness while still reusing the same fixture grouping semantics.
"""
from tests.helpers.runtime import iter_omni_server
yield from iter_omni_server(request, run_level, omni_fixture_lock)
@pytest.fixture
def online_client(request: pytest.FixtureRequest, run_level: str):
"""Resolve ``omni_server`` lazily so parametrized server fixtures work like upstream."""
from tests.helpers.client import OnlineOmniClient
server = request.getfixturevalue("omni_server")
return OnlineOmniClient(
host=server.host,
port=server.port,
api_key="EMPTY",
run_level=run_level,
log_stats=server.log_stats,
)
@pytest.fixture
def openai_client(online_client):
"""Historical alias for :func:`online_client`."""
return online_client
@pytest.fixture
def online_client_function(request: pytest.FixtureRequest, run_level: str):
"""Resolve ``omni_server_function`` lazily for function-scoped reliability tests."""
from tests.helpers.client import OnlineOmniClient
server = request.getfixturevalue("omni_server_function")
return OnlineOmniClient(
host=server.host,
port=server.port,
api_key="EMPTY",
run_level=run_level,
log_stats=server.log_stats,
)
@pytest.fixture
def openai_client_function(online_client_function):
"""Historical alias for :func:`online_client_function`."""
return online_client_function
@pytest.fixture(scope="function")
def omni_runner_function(
request: pytest.FixtureRequest,
run_level: str,
) -> Generator[OmniRunner, Any, None]:
"""Function-scoped :class:`~tests.helpers.runtime.OmniRunner` (cf. :func:`omni_server_function`).
Tears down the runner after each test so the next test does not share engine
state with a module-scoped :func:`omni_runner`.
"""
from tests.helpers.runtime import iter_omni_runner
yield from iter_omni_runner(request, run_level, omni_fixture_lock)
@pytest.fixture(scope="module")
def omni_runner(request: pytest.FixtureRequest, run_level: str) -> Generator[OmniRunner, Any, None]:
"""Module-scoped :class:`~tests.helpers.runtime.OmniRunner` (cf. :func:`omni_server`).
Reuses one runner for the whole module to amortize multi-stage init cost.
"""
from tests.helpers.runtime import iter_omni_runner
yield from iter_omni_runner(request, run_level, omni_fixture_lock)
@pytest.fixture
def offline_client_function(omni_runner_function: OmniRunner):
"""Resolve :class:`~tests.helpers.client.OfflineOmniClient` for :func:`omni_runner_function`."""
from tests.helpers.client import OfflineOmniClient
return OfflineOmniClient(omni_runner_function)
@pytest.fixture
def omni_runner_handler_function(offline_client_function):
"""Historical alias for :func:`offline_client_function`."""
return offline_client_function
@pytest.fixture
def offline_client(omni_runner: OmniRunner):
from tests.helpers.client import OfflineOmniClient
return OfflineOmniClient(omni_runner)
@pytest.fixture
def omni_runner_handler(offline_client):
"""Historical alias for :func:`offline_client`."""
return offline_client