Skip to content

Commit 0a64090

Browse files
[GuideLLM Refactor] Fixes for various failing unit tests (#394)
## Summary <!-- Include a short paragraph of the changes introduced in this PR. If this PR requires additional context or rationale, explain why the changes are necessary. --> Fixes failing unit tests. Most were failing due to changes in functionality but a couple were regressions. --- - [x] "I certify that all code in this PR is my own, except as noted below." ## Use of AI - [x] Includes AI-assisted code completion - [ ] Includes code generated by an AI application - [x] Includes AI-generated tests (NOTE: AI written tests should have a docstring that includes `## WRITTEN BY AI ##`)
2 parents 51c1681 + 1556236 commit 0a64090

19 files changed

+117
-127
lines changed

src/guidellm/benchmark/types.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
from collections.abc import Iterable
44
from pathlib import Path
5-
from typing import Any, TypeAliasType
5+
from typing import Any
66

77
from datasets import Dataset, DatasetDict, IterableDataset, IterableDatasetDict
88
from transformers import ( # type: ignore[import]
99
PreTrainedTokenizerBase,
1010
)
11+
from typing_extensions import TypeAliasType
1112

1213
from guidellm.benchmark.aggregator import (
1314
Aggregator,

src/guidellm/scheduler/objects.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
Protocol,
2121
TypeVar,
2222
Union,
23+
runtime_checkable,
2324
)
2425

2526
from pydantic import Field, computed_field
@@ -232,6 +233,7 @@ def model_copy(self, **kwargs) -> ScheduledRequestInfo: # type: ignore[override
232233
)
233234

234235

236+
@runtime_checkable
235237
class BackendInterface(Protocol, Generic[RequestT, ResponseT]):
236238
"""
237239
Abstract interface for request processing backends.

src/guidellm/utils/pydantic_utils.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,17 @@ class DatabaseConfig(BaseConfig):
275275

276276
schema_discriminator: ClassVar[str] = "model_type"
277277

278+
def __new__(cls, *args, **kwargs): # noqa: ARG004
279+
"""
280+
Prevent direct instantiation of base classes that use this mixin.
281+
282+
Only allows instantiation of concrete subclasses, not the base class.
283+
"""
284+
base_type = cls.__pydantic_schema_base_type__()
285+
if cls is base_type:
286+
raise TypeError(f"only children of '{cls.__name__}' may be instantiated")
287+
return super().__new__(cls)
288+
278289
@classmethod
279290
def register_decorator(
280291
cls, clazz: RegisterClassT, name: str | list[str] | None = None

src/guidellm/utils/statistics.py

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -275,18 +275,9 @@ def from_request_times(
275275
"""
276276
if distribution_type == "concurrency":
277277
# convert to delta changes based on when requests were running
278-
time_deltas: dict[float, int] = defaultdict(int)
279-
for start, end in requests:
280-
time_deltas[start] += 1
281-
time_deltas[end] -= 1
282-
283-
# convert to the events over time measuring concurrency changes
284-
events = []
285-
active = 0
286-
287-
for time, delta in sorted(time_deltas.items()):
288-
active += delta
289-
events.append((time, active))
278+
events = [(start, 1) for start, _ in requests] + [
279+
(end, -1) for _, end in requests
280+
]
290281
elif distribution_type == "rate":
291282
# convert to events for when requests finished
292283
global_start = min(start for start, _ in requests) if requests else 0
@@ -313,6 +304,16 @@ def from_request_times(
313304
else:
314305
flattened_events.append((time, val))
315306

307+
if distribution_type == "concurrency":
308+
# convert to the events over time measuring concurrency changes
309+
events_over_time: list[tuple[float, float]] = []
310+
active = 0
311+
for time, delta in flattened_events:
312+
active += delta # type: ignore [assignment]
313+
events_over_time.append((time, active))
314+
315+
flattened_events = events_over_time
316+
316317
# convert to value distribution function
317318
distribution: dict[float, float] = defaultdict(float)
318319

File renamed without changes.

tests/unit/backend/test_backend.py renamed to tests/unit/backends/test_backend.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ async def default_model(self) -> str | None:
8080
def test_class_signatures(self):
8181
"""Test Backend inheritance and type relationships."""
8282
assert issubclass(Backend, RegistryMixin)
83-
assert issubclass(Backend, BackendInterface)
83+
assert isinstance(Backend, BackendInterface)
8484
assert hasattr(Backend, "create")
8585
assert hasattr(Backend, "register")
8686
assert hasattr(Backend, "get_registered_object")

tests/unit/backend/test_objects.py renamed to tests/unit/backends/test_objects.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,6 @@ def valid_instances(self, request):
397397
def test_class_signatures(self):
398398
"""Test GenerationRequestTimings inheritance and type relationships."""
399399
assert issubclass(GenerationRequestTimings, MeasuredRequestTimings)
400-
assert issubclass(GenerationRequestTimings, StandardBaseModel)
401400
assert hasattr(GenerationRequestTimings, "model_dump")
402401
assert hasattr(GenerationRequestTimings, "model_validate")
403402

tests/unit/backend/test_openai_backend.py renamed to tests/unit/backends/test_openai_backend.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ async def test_info(self):
237237
target="http://test", model="test-model", timeout=30.0
238238
)
239239

240-
info = backend.info()
240+
info = backend.info
241241

242242
assert info["target"] == "http://test"
243243
assert info["model"] == "test-model"
@@ -1074,7 +1074,7 @@ def test_get_chat_message_media_item_jpeg_file(self):
10741074
mock_image = Mock(spec=Image.Image)
10751075
mock_image.tobytes.return_value = b"fake_jpeg_data"
10761076

1077-
with patch("guidellm.backend.openai.Image.open", return_value=mock_image):
1077+
with patch("guidellm.backends.openai.Image.open", return_value=mock_image):
10781078
result = backend._get_chat_message_media_item(mock_jpeg_path)
10791079

10801080
expected_data = base64.b64encode(b"fake_jpeg_data").decode("utf-8")

tests/unit/objects/__init__.py

Whitespace-only changes.

tests/unit/objects/test_pydantic.py

Lines changed: 0 additions & 43 deletions
This file was deleted.

0 commit comments

Comments
 (0)