@@ -18,7 +18,8 @@ from typing import Any
1818
1919ROOT = Path (__file__ ).resolve ().parents [2 ]
2020CONFIG = ROOT / ".github" / "ci-config.json"
21- SHARDED_SUITES = ("domain" , "composition" )
21+ CI_SHARDED_SUITES = ("domain" , "composition" )
22+ TIMING_SUITES = (* CI_SHARDED_SUITES , "benchmark" )
2223MAX_BYTES = 5 * 1024 * 1024
2324MAX_ENTRIES = 10_000
2425MAX_CANDIDATES = 5
@@ -58,8 +59,10 @@ class CrossOriginRedirectHandler(urllib.request.HTTPRedirectHandler):
5859
5960
6061def shard_count (suite : str ) -> int :
61- if suite not in SHARDED_SUITES :
62+ if suite not in TIMING_SUITES :
6263 raise ValueError (f"unsupported timing suite: { suite } " )
64+ if suite == "benchmark" :
65+ return 4
6366 return int (ci_config ()[f"{ suite } _shard_count" ])
6467
6568
@@ -75,7 +78,7 @@ def ci_config() -> dict[str, Any]:
7578 payload = json .loads (CONFIG .read_text (encoding = "utf-8" ))
7679 if not isinstance (payload , dict ):
7780 raise ValueError ("ci-config.json must contain a JSON object" )
78- for suite in SHARDED_SUITES :
81+ for suite in CI_SHARDED_SUITES :
7982 count = payload .get (f"{ suite } _shard_count" )
8083 if not isinstance (count , int ) or isinstance (count , bool ) or count < 1 :
8184 raise ValueError (f"{ suite } _shard_count must be a positive integer" )
@@ -111,7 +114,7 @@ def emit_plan_outputs() -> None:
111114 """Print GitHub Actions outputs for shard, Node, and pytest-split pins."""
112115
113116 config = ci_config ()
114- for suite in SHARDED_SUITES :
117+ for suite in CI_SHARDED_SUITES :
115118 count = int (config [f"{ suite } _shard_count" ])
116119 print (f"{ suite } -shard-count={ count } " )
117120 print (f"{ suite } -shards={ json .dumps (list (range (1 , count + 1 )))} " )
@@ -138,8 +141,9 @@ def validate_durations(value: Any, source: str, suite: str) -> dict[str, float]:
138141 raise ValueError (f"{ source } exceeds { MAX_ENTRIES } timing entries" )
139142
140143 durations : dict [str , float ] = {}
144+ prefix = "benchmarks/validation/" if suite == "benchmark" else f"tests/{ suite } /"
141145 for nodeid , duration in value .items ():
142- if not isinstance (nodeid , str ) or not nodeid .startswith (f"tests/ { suite } /" ):
146+ if not isinstance (nodeid , str ) or not nodeid .startswith (prefix ):
143147 raise ValueError (f"{ source } contains an invalid test node id: { nodeid !r} " )
144148 if isinstance (duration , bool ) or not isinstance (duration , (int , float )):
145149 raise ValueError (f"{ source } contains a non-numeric duration for { nodeid } " )
@@ -321,14 +325,14 @@ def main() -> None:
321325
322326 prepare_parser = subparsers .add_parser ("prepare" )
323327 prepare_parser .add_argument ("--output" , type = Path , required = True )
324- prepare_parser .add_argument ("--suite" , choices = SHARDED_SUITES , required = True )
328+ prepare_parser .add_argument ("--suite" , choices = TIMING_SUITES , required = True )
325329
326330 merge_parser = subparsers .add_parser ("merge" )
327331 merge_parser .add_argument ("--input" , action = "append" , type = Path , required = True )
328332 merge_parser .add_argument ("--output" , type = Path , required = True )
329333 merge_parser .add_argument ("--source-sha" , required = True )
330334 merge_parser .add_argument ("--python-version" , required = True )
331- merge_parser .add_argument ("--suite" , choices = SHARDED_SUITES , required = True )
335+ merge_parser .add_argument ("--suite" , choices = TIMING_SUITES , required = True )
332336 merge_parser .add_argument (
333337 "--pytest-split-version" ,
334338 default = None ,
0 commit comments