@@ -58,7 +58,7 @@ def add_run_time(self, test_name: str, runtime: int, out: SummaryTree):
5858
5959
6060class TestPicker :
61- def __init__ (self , test_dir : Path ):
61+ def __init__ (self , test_dir : Path , binaries : OrderedDict [ Version , Path ] ):
6262 if not test_dir .exists ():
6363 raise RuntimeError ("{} is neither a directory nor a file" .format (test_dir ))
6464 self .include_files_regex = re .compile (config .include_test_files )
@@ -69,6 +69,7 @@ def __init__(self, test_dir: Path):
6969 self .tests : OrderedDict [str , TestDescription ] = collections .OrderedDict ()
7070 self .restart_test : Pattern = re .compile (r".*-\d+\.(txt|toml)" )
7171 self .follow_test : Pattern = re .compile (r".*-[2-9]\d*\.(txt|toml)" )
72+ self .old_binaries : OrderedDict [Version , Path ] = binaries
7273
7374 for subdir in self .test_dir .iterdir ():
7475 if subdir .is_dir () and subdir .name in config .test_dirs :
@@ -85,6 +86,10 @@ def __init__(self, test_dir: Path):
8586 else :
8687 self .fetch_stats ()
8788
89+ if not self .tests :
90+ raise Exception (
91+ "No tests to run! Please check if tests are included/excluded incorrectly or old binaries are missing for restarting tests" )
92+
8893 def add_time (self , test_file : Path , run_time : int , out : SummaryTree ) -> None :
8994 # getting the test name is fairly inefficient. But since we only have 100s of tests, I won't bother
9095 test_name : str | None = None
@@ -132,6 +137,23 @@ def parse_txt(self, path: Path):
132137 or self .exclude_files_regex .search (str (path )) is not None
133138 ):
134139 return
140+ # Skip restarting tests that do not have old binaries in the given version range
141+ # In particular, this is only for restarting tests with the "until" keyword,
142+ # since without "until", it will at least run with the current binary.
143+ if is_restarting_test (path ):
144+ candidates : List [Path ] = []
145+ dirs = path .parent .parts
146+ version_expr = dirs [- 1 ].split ("_" )
147+ if (version_expr [0 ] == "from" or version_expr [0 ] == "to" ) and len (version_expr ) == 4 and version_expr [2 ] == "until" :
148+ max_version = Version .parse (version_expr [3 ])
149+ min_version = Version .parse (version_expr [1 ])
150+ for ver , binary in self .old_binaries .items ():
151+ if min_version <= ver < max_version :
152+ candidates .append (binary )
153+ if not len (candidates ):
154+ # No valid old binary found
155+ return
156+
135157 with path .open ("r" ) as f :
136158 test_name : str | None = None
137159 test_class : str | None = None
@@ -263,7 +285,7 @@ def choose_binary(self, test_file: Path) -> Path:
263285 max_version = Version .parse (version_expr [3 ])
264286 candidates : List [Path ] = []
265287 for ver , binary in self .binaries .items ():
266- if min_version <= ver <= max_version :
288+ if min_version <= ver < max_version :
267289 candidates .append (binary )
268290 if len (candidates ) == 0 :
269291 return config .binary
@@ -474,7 +496,7 @@ def __init__(self):
474496 self .cluster_file : str | None = None
475497 self .fdb_app_dir : str | None = None
476498 self .binary_chooser = OldBinaries ()
477- self .test_picker = TestPicker (self .test_path )
499+ self .test_picker = TestPicker (self .test_path , self . binary_chooser . binaries )
478500
479501 def backup_sim_dir (self , seed : int ):
480502 temp_dir = config .run_dir / str (self .uid )
0 commit comments