Skip to content

Commit a596c39

Browse files
Start async benchmark
1 parent adee8a1 commit a596c39

1 file changed

Lines changed: 71 additions & 18 deletions

File tree

src/pytest_codspeed/plugin.py

Lines changed: 71 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
import json
66
import os
77
import random
8+
from collections.abc import AsyncIterator
9+
from contextlib import contextmanager
810
from dataclasses import dataclass, field
11+
from inspect import isawaitable
912
from pathlib import Path
1013
from time import time
11-
from typing import TYPE_CHECKING, cast
14+
from typing import TYPE_CHECKING, cast, overload
1215

1316
import pytest
1417
from _pytest.fixtures import FixtureManager
@@ -232,35 +235,85 @@ def pytest_collection_modifyitems(
232235
items[:] = selected
233236

234237

235-
def _measure(
236-
plugin: CodSpeedPlugin,
237-
node: pytest.Item,
238-
config: pytest.Config,
239-
pedantic_options: PedanticOptions | None,
240-
fn: Callable[..., T],
241-
args: tuple[Any, ...],
242-
kwargs: dict[str, Any],
243-
) -> T:
238+
@contextmanager
239+
def _measure_context(node: pytest.Item) -> AsyncIterator[None]
244240
marker_options = BenchmarkMarkerOptions.from_pytest_item(node)
245241
random.seed(0)
246242
is_gc_enabled = gc.isenabled()
247243
if is_gc_enabled:
248244
gc.collect()
249245
gc.disable()
250-
try:
251-
uri, name = get_git_relative_uri_and_name(node.nodeid, config.rootpath)
246+
247+
yield
248+
249+
# Ensure GC is re-enabled even if the test failed
250+
if is_gc_enabled:
251+
gc.enable()
252+
253+
254+
async def _async_measure(
255+
plugin: CodSpeedPlugin,
256+
node: pytest.Item,
257+
pedantic_options: PedanticOptions | None,
258+
fn: Awaitable[T],
259+
args: tuple[Any, ...],
260+
kwargs: dict[str, Any],
261+
) -> T:
262+
with _measure_context(node):
252263
if pedantic_options is None:
253-
return plugin.instrument.measure(
264+
return await plugin.instrument.measure_async(
254265
marker_options, name, uri, fn, *args, **kwargs
255266
)
256267
else:
257-
return plugin.instrument.measure_pedantic(
268+
return await plugin.instrument.measure_pedantic_async(
258269
marker_options, pedantic_options, name, uri
259270
)
260-
finally:
261-
# Ensure GC is re-enabled even if the test failed
262-
if is_gc_enabled:
263-
gc.enable()
271+
272+
273+
@overload
274+
def _measure(
275+
plugin: CodSpeedPlugin,
276+
node: pytest.Item,
277+
config: pytest.Config,
278+
pedantic_options: PedanticOptions | None,
279+
fn: Awaitable[T],
280+
args: tuple[Any, ...],
281+
kwargs: dict[str, Any],
282+
) -> Awaitable[T]:
283+
...
284+
@overload
285+
def _measure(
286+
plugin: CodSpeedPlugin,
287+
node: pytest.Item,
288+
config: pytest.Config,
289+
pedantic_options: PedanticOptions | None,
290+
fn: Callable[..., T],
291+
args: tuple[Any, ...],
292+
kwargs: dict[str, Any],
293+
) -> T:
294+
...
295+
def _measure(
296+
plugin: CodSpeedPlugin,
297+
node: pytest.Item,
298+
config: pytest.Config,
299+
pedantic_options: PedanticOptions | None,
300+
fn: Callable[..., T] | Awaitable[T],
301+
args: tuple[Any, ...],
302+
kwargs: dict[str, Any],
303+
) -> T | Awaitable[T]:
304+
uri, name = get_git_relative_uri_and_name(node.nodeid, config.rootpath)
305+
if isawaitable(fn):
306+
return _async_measure(plugin, node, pedantic_options, fn, args, kwargs)
307+
else:
308+
with _measure_context(node):
309+
if pedantic_options is None:
310+
return plugin.instrument.measure(
311+
marker_options, name, uri, fn, *args, **kwargs
312+
)
313+
else:
314+
return plugin.instrument.measure_pedantic(
315+
marker_options, pedantic_options, name, uri
316+
)
264317

265318

266319
def wrap_runtest(

0 commit comments

Comments
 (0)