@@ -58,8 +58,7 @@ def pytest_addoption(parser: pytest.Parser):
5858 action = "store" ,
5959 type = float ,
6060 help = (
61- "The time to warm up the benchmark for (in seconds), "
62- "only for walltime mode"
61+ "The time to warm up the benchmark for (in seconds), only for walltime mode"
6362 ),
6463 )
6564 group .addoption (
@@ -223,6 +222,43 @@ def has_benchmark_fixture(item: pytest.Item) -> bool:
223222 return "benchmark" in item_fixtures or "codspeed_benchmark" in item_fixtures
224223
225224
225+ @dataclass (frozen = True )
226+ class BenchmarkMarkerOptions :
227+ group : str | None = None
228+ """The group name to use for the benchmark"""
229+ min_time : int | None = None
230+ """The minimum time of a round (in seconds)"""
231+ max_time : int | None = None
232+ """The maximum time to run the benchmark for (in seconds)"""
233+ max_rounds : int | None = None
234+ """The maximum number of rounds to run the benchmark for. Takes precedence over
235+ max_time."""
236+
237+
238+ def get_benchmark_marker_options (item : pytest .Item ) -> BenchmarkMarkerOptions :
239+ marker = item .get_closest_marker ("codspeed_benchmark" ) or item .get_closest_marker (
240+ "benchmark"
241+ )
242+ if marker is None :
243+ return BenchmarkMarkerOptions ()
244+ if len (marker .args ) > 0 :
245+ raise ValueError ("Positional arguments are not allowed in the benchmark marker" )
246+
247+ options = BenchmarkMarkerOptions (
248+ group = marker .kwargs .pop ("group" , None ),
249+ max_time = marker .kwargs .pop ("max_time" , None ),
250+ min_time = marker .kwargs .pop ("min_time" , None ),
251+ max_rounds = marker .kwargs .pop ("max_rounds" , None ),
252+ )
253+
254+ if len (marker .kwargs ) > 0 :
255+ raise ValueError (
256+ "Unknown kwargs passed to benchmark marker: "
257+ + ", " .join (marker .kwargs .keys ())
258+ )
259+ return options
260+
261+
226262def has_benchmark_marker (item : pytest .Item ) -> bool :
227263 return (
228264 item .get_closest_marker ("codspeed_benchmark" ) is not None
@@ -254,7 +290,7 @@ def pytest_collection_modifyitems(
254290
255291def _measure (
256292 plugin : CodSpeedPlugin ,
257- nodeid : str ,
293+ node : pytest . Item ,
258294 config : pytest .Config ,
259295 fn : Callable [P , T ],
260296 * args : P .args ,
@@ -266,8 +302,9 @@ def _measure(
266302 gc .collect ()
267303 gc .disable ()
268304 try :
269- uri , name = get_git_relative_uri_and_name (nodeid , config .rootpath )
270- return plugin .instrument .measure (name , uri , fn , * args , ** kwargs )
305+ uri , name = get_git_relative_uri_and_name (node .nodeid , config .rootpath )
306+ marker_options = get_benchmark_marker_options (node )
307+ return plugin .instrument .measure (marker_options , name , uri , fn , * args , ** kwargs )
271308 finally :
272309 # Ensure GC is re-enabled even if the test failed
273310 if is_gc_enabled :
@@ -276,13 +313,13 @@ def _measure(
276313
277314def wrap_runtest (
278315 plugin : CodSpeedPlugin ,
279- nodeid : str ,
316+ node : pytest . Item ,
280317 config : pytest .Config ,
281318 fn : Callable [P , T ],
282319) -> Callable [P , T ]:
283320 @functools .wraps (fn )
284321 def wrapped (* args : P .args , ** kwargs : P .kwargs ) -> T :
285- return _measure (plugin , nodeid , config , fn , * args , ** kwargs )
322+ return _measure (plugin , node , config , fn , * args , ** kwargs )
286323
287324 return wrapped
288325
@@ -299,7 +336,7 @@ def pytest_runtest_protocol(item: pytest.Item, nextitem: pytest.Item | None):
299336 return None
300337
301338 # Wrap runtest and defer to default protocol
302- item .runtest = wrap_runtest (plugin , item . nodeid , item .config , item .runtest )
339+ item .runtest = wrap_runtest (plugin , item , item .config , item .runtest )
303340 return None
304341
305342
@@ -343,9 +380,7 @@ def __call__(self, func: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T
343380 config = self ._request .config
344381 plugin = get_plugin (config )
345382 if plugin .is_codspeed_enabled :
346- return _measure (
347- plugin , self ._request .node .nodeid , config , func , * args , ** kwargs
348- )
383+ return _measure (plugin , self ._request .node , config , func , * args , ** kwargs )
349384 else :
350385 return func (* args , ** kwargs )
351386
0 commit comments