Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 1 addition & 13 deletions tests/unit/backends/test_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@

from __future__ import annotations

import asyncio
from collections.abc import AsyncIterator
from functools import wraps
from typing import Any
from unittest.mock import Mock, patch

Expand All @@ -19,17 +17,7 @@
)
from guidellm.scheduler import BackendInterface, ScheduledRequestInfo
from guidellm.utils import RegistryMixin


def async_timeout(delay):
def decorator(func):
@wraps(func)
async def new_func(*args, **kwargs):
return await asyncio.wait_for(func(*args, **kwargs), timeout=delay)

return new_func

return decorator
from tests.unit.testing_utils import async_timeout


def test_backend_type():
Expand Down
23 changes: 1 addition & 22 deletions tests/unit/backends/test_openai_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@

from __future__ import annotations

import asyncio
import base64
from functools import wraps
from pathlib import Path
from unittest.mock import AsyncMock, Mock, patch

Expand All @@ -22,17 +20,7 @@
)
from guidellm.backends.openai import OpenAIHTTPBackend, UsageStats
from guidellm.scheduler import ScheduledRequestInfo


def async_timeout(delay):
def decorator(func):
@wraps(func)
async def new_func(*args, **kwargs):
return await asyncio.wait_for(func(*args, **kwargs), timeout=delay)

return new_func

return decorator
from tests.unit.testing_utils import async_timeout


def test_usage_stats():
Expand Down Expand Up @@ -230,7 +218,6 @@ def test_header_building(self):
@pytest.mark.smoke
@pytest.mark.asyncio
@async_timeout(10.0)
@async_timeout(5.0)
async def test_info(self):
"""Test info method."""
backend = OpenAIHTTPBackend(
Expand All @@ -250,7 +237,6 @@ async def test_info(self):
@pytest.mark.smoke
@pytest.mark.asyncio
@async_timeout(10.0)
@async_timeout(5.0)
async def test_process_startup(self):
"""Test process startup."""
backend = OpenAIHTTPBackend(target="http://test")
Expand All @@ -267,7 +253,6 @@ async def test_process_startup(self):
@pytest.mark.smoke
@pytest.mark.asyncio
@async_timeout(10.0)
@async_timeout(5.0)
async def test_process_startup_already_started(self):
"""Test process startup when already started."""
backend = OpenAIHTTPBackend(target="http://test")
Expand All @@ -279,7 +264,6 @@ async def test_process_startup_already_started(self):
@pytest.mark.smoke
@pytest.mark.asyncio
@async_timeout(10.0)
@async_timeout(5.0)
async def test_process_shutdown(self):
"""Test process shutdown."""
backend = OpenAIHTTPBackend(target="http://test")
Expand All @@ -296,7 +280,6 @@ async def test_process_shutdown(self):
@pytest.mark.smoke
@pytest.mark.asyncio
@async_timeout(10.0)
@async_timeout(5.0)
async def test_process_shutdown_not_started(self):
"""Test process shutdown when not started."""
backend = OpenAIHTTPBackend(target="http://test")
Expand All @@ -307,7 +290,6 @@ async def test_process_shutdown_not_started(self):
@pytest.mark.sanity
@pytest.mark.asyncio
@async_timeout(10.0)
@async_timeout(5.0)
async def test_check_in_process(self):
"""Test _check_in_process method."""
backend = OpenAIHTTPBackend(target="http://test")
Expand All @@ -325,7 +307,6 @@ async def test_check_in_process(self):
@pytest.mark.sanity
@pytest.mark.asyncio
@async_timeout(10.0)
@async_timeout(5.0)
async def test_available_models(self):
"""Test available_models method."""
backend = OpenAIHTTPBackend(target="http://test")
Expand All @@ -346,7 +327,6 @@ async def test_available_models(self):
@pytest.mark.sanity
@pytest.mark.asyncio
@async_timeout(10.0)
@async_timeout(5.0)
async def test_default_model(self):
"""Test default_model method."""
# Test when model is already set
Expand All @@ -370,7 +350,6 @@ async def test_default_model(self):
@pytest.mark.regression
@pytest.mark.asyncio
@async_timeout(10.0)
@async_timeout(10.0)
async def test_validate_with_model(self):
"""Test validate method when model is set."""
backend = OpenAIHTTPBackend(target="http://test", model="test-model")
Expand Down
15 changes: 1 addition & 14 deletions tests/unit/scheduler/test_scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import inspect
import random
import uuid
from functools import wraps
from typing import Any, Generic

import pytest
Expand All @@ -20,19 +19,7 @@
SynchronousStrategy,
)
from guidellm.utils.singleton import ThreadSafeSingletonMixin


def async_timeout(delay: float):
"""Decorator to add timeout to async test functions."""

def decorator(func):
@wraps(func)
async def new_func(*args, **kwargs):
return await asyncio.wait_for(func(*args, **kwargs), timeout=delay)

return new_func

return decorator
from tests.unit.testing_utils import async_timeout


class MockRequest(BaseModel):
Expand Down
13 changes: 1 addition & 12 deletions tests/unit/scheduler/test_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import random
import time
from dataclasses import dataclass
from functools import wraps
from multiprocessing import Barrier, Event, Process
from multiprocessing.synchronize import Barrier as ProcessingBarrier
from multiprocessing.synchronize import Event as ProcessingEvent
Expand All @@ -27,21 +26,11 @@
WorkerProcess,
)
from guidellm.utils import InterProcessMessagingQueue
from tests.unit.testing_utils import async_timeout

STANDARD_NUM_REQUESTS: int = 200


def async_timeout(delay):
def decorator(func):
@wraps(func)
async def new_func(*args, **kwargs):
return await asyncio.wait_for(func(*args, **kwargs), timeout=delay)

return new_func

return decorator


@dataclass
class TimingsBounds:
exact: float | None = None
Expand Down
13 changes: 1 addition & 12 deletions tests/unit/scheduler/test_worker_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import asyncio
import inspect
import time
from functools import wraps
from multiprocessing.context import BaseContext
from multiprocessing.managers import BaseManager
from multiprocessing.process import BaseProcess
Expand All @@ -30,17 +29,7 @@
)
from guidellm.scheduler.worker_group import WorkerGroupState
from guidellm.utils import InterProcessMessaging


def async_timeout(delay):
def decorator(func):
@wraps(func)
async def new_func(*args, **kwargs):
return await asyncio.wait_for(func(*args, **kwargs), timeout=delay)

return new_func

return decorator
from tests.unit.testing_utils import async_timeout


class MockRequestTimings(MeasuredRequestTimings):
Expand Down
41 changes: 41 additions & 0 deletions tests/unit/testing_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""Common test utilities for async testing."""

from __future__ import annotations

import asyncio
from collections.abc import Awaitable, Callable
from functools import wraps
from typing import Any, TypeVar

import pytest

# Type variables for proper typing
F = TypeVar("F", bound=Callable[..., Awaitable[Any]])


def async_timeout(delay: float = 10.0, hard_fail: bool = False) -> Callable[[F], F]:
"""
Decorator to add timeout to async test functions.

Args:
delay: Timeout in seconds (default: 10.0)

Returns:
Decorated function with timeout applied
"""

def decorator(func: F) -> F:
@wraps(func)
async def wrapper(*args: Any, **kwargs: Any) -> Any:
try:
return await asyncio.wait_for(func(*args, **kwargs), timeout=delay)
except asyncio.TimeoutError:
msg = f"Test {func.__name__} timed out after {delay} seconds"
if hard_fail:
pytest.fail(msg)
else:
pytest.xfail(msg)

return wrapper # type: ignore[return-value]

return decorator
12 changes: 12 additions & 0 deletions tests/unit/utils/test_functions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import time
from datetime import datetime

import pytest
Expand Down Expand Up @@ -180,6 +181,17 @@ def test_single_value(self):
assert result == 3.0


@pytest.fixture(autouse=True)
def force_us_eastern_timezone(monkeypatch):
"""
Forces the timezone to US/Eastern for the duration of a test.
This ensures that timestamp formatting is consistent across all environments.

## WRITTEN BY AI ##
"""
monkeypatch.setenv("TZ", "America/New_York")
time.tzset() # Propagates the change to the underlying C library

class TestSafeFormatTimestamp:
"""Test suite for safe_format_timestamp function."""

Expand Down
15 changes: 1 addition & 14 deletions tests/unit/utils/test_messaging.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import asyncio
import multiprocessing
import threading
from functools import wraps
from typing import Any, TypeVar

import culsans
Expand All @@ -22,19 +21,7 @@
InterProcessMessagingQueue,
)
from guidellm.utils.messaging import ReceiveMessageT, SendMessageT


def async_timeout(delay: float):
"""Decorator to add timeout to async test functions."""

def decorator(func):
@wraps(func)
async def new_func(*args, **kwargs):
return await asyncio.wait_for(func(*args, **kwargs), timeout=delay)

return new_func

return decorator
from tests.unit.testing_utils import async_timeout


class MockMessage(BaseModel):
Expand Down
15 changes: 1 addition & 14 deletions tests/unit/utils/test_synchronous.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import asyncio
import multiprocessing
import threading
from functools import wraps
from multiprocessing.synchronize import Barrier as ProcessingBarrier
from multiprocessing.synchronize import Event as ProcessingEvent
from typing import get_args
Expand All @@ -16,19 +15,7 @@
wait_for_sync_event,
wait_for_sync_objects,
)


def async_timeout(delay: float):
"""Decorator to add timeout to async functions."""

def decorator(func):
@wraps(func)
async def new_func(*args, **kwargs):
return await asyncio.wait_for(func(*args, **kwargs), timeout=delay)

return new_func

return decorator
from tests.unit.testing_utils import async_timeout


def test_sync_object_types_alias():
Expand Down
Loading