Skip to content

Commit 0c35b86

Browse files
committed
WIP add stop_early arg
1 parent 014bc92 commit 0c35b86

File tree

3 files changed

+56
-8
lines changed

3 files changed

+56
-8
lines changed

bioimageio/core/_resource_tests.py

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,7 @@ def test_model(
164164
*,
165165
determinism: Literal["seed_only", "full"] = "seed_only",
166166
sha256: Optional[Sha256] = None,
167+
stop_early: bool = False,
167168
**deprecated: Unpack[DeprecatedKwargs],
168169
) -> ValidationSummary:
169170
"""Test model inference"""
@@ -174,6 +175,7 @@ def test_model(
174175
determinism=determinism,
175176
expected_type="model",
176177
sha256=sha256,
178+
stop_early=stop_early,
177179
**deprecated,
178180
)
179181

@@ -192,13 +194,15 @@ def test_description(
192194
determinism: Literal["seed_only", "full"] = "seed_only",
193195
expected_type: Optional[str] = None,
194196
sha256: Optional[Sha256] = None,
197+
stop_early: bool = False,
195198
runtime_env: Union[
196199
Literal["currently-active", "as-described"], Path, BioimageioCondaEnv
197200
] = ("currently-active"),
198201
run_command: Callable[[Sequence[str]], None] = default_run_command,
199202
**deprecated: Unpack[DeprecatedKwargs],
200203
) -> ValidationSummary:
201-
"""Test a bioimage.io resource dynamically, e.g. prediction of test tensors for models.
204+
"""Test a bioimage.io resource dynamically,
205+
for example run prediction of test tensors for models.
202206
203207
Args:
204208
source: model description source.
@@ -207,6 +211,10 @@ def test_description(
207211
devices: Devices to test with, e.g. 'cpu', 'cuda'.
208212
Default (may be weight format dependent): ['cuda'] if available, ['cpu'] otherwise.
209213
determinism: Modes to improve reproducibility of test outputs.
214+
expected_type: Assert an expected resource description `type`.
215+
sha256: Expected SHA256 value of **source**.
216+
(Ignored if **source** already is a loaded `ResourceDescr` object.)
217+
stop_early: Do not run further subtests after a failed one.
210218
runtime_env: (Experimental feature!) The Python environment to run the tests in
211219
- `"currently-active"`: Use active Python interpreter.
212220
- `"as-described"`: Use `bioimageio.spec.get_conda_env` to generate a conda
@@ -225,6 +233,7 @@ def test_description(
225233
determinism=determinism,
226234
expected_type=expected_type,
227235
sha256=sha256,
236+
stop_early=stop_early,
228237
**deprecated,
229238
)
230239
return rd.validation_summary
@@ -254,6 +263,9 @@ def test_description(
254263
conda_env=conda_env,
255264
devices=devices,
256265
determinism=determinism,
266+
expected_type=expected_type,
267+
sha256=sha256,
268+
stop_early=stop_early,
257269
run_command=run_command,
258270
**deprecated,
259271
)
@@ -268,6 +280,9 @@ def _test_in_env(
268280
devices: Optional[Sequence[str]],
269281
determinism: Literal["seed_only", "full"],
270282
run_command: Callable[[Sequence[str]], None],
283+
stop_early: bool,
284+
expected_type: Optional[str],
285+
sha256: Optional[Sha256],
271286
**deprecated: Unpack[DeprecatedKwargs],
272287
) -> ValidationSummary:
273288
descr = load_description(source)
@@ -293,6 +308,9 @@ def _test_in_env(
293308
determinism=determinism,
294309
conda_env=conda_env,
295310
run_command=run_command,
311+
expected_type=expected_type,
312+
sha256=sha256,
313+
stop_early=stop_early,
296314
**deprecated,
297315
)
298316
for wf in all_present_wfs[1:]:
@@ -304,6 +322,9 @@ def _test_in_env(
304322
determinism=determinism,
305323
conda_env=conda_env,
306324
run_command=run_command,
325+
expected_type=expected_type,
326+
sha256=sha256,
327+
stop_early=stop_early,
307328
**deprecated,
308329
)
309330
for d in additional_summary.details:
@@ -370,7 +391,10 @@ def _test_in_env(
370391
"test",
371392
str(source),
372393
f"--summary-path={summary_path}",
394+
f"--determinism={determinism}",
373395
]
396+
+ ([f"--expected-type={expected_type}"] if expected_type else [])
397+
+ (["--stop-early"] if stop_early else [])
374398
)
375399
return ValidationSummary.model_validate_json(summary_path.read_bytes())
376400

@@ -385,6 +409,7 @@ def load_description_and_test(
385409
determinism: Literal["seed_only", "full"] = "seed_only",
386410
expected_type: Optional[str] = None,
387411
sha256: Optional[Sha256] = None,
412+
stop_early: bool = False,
388413
**deprecated: Unpack[DeprecatedKwargs],
389414
) -> Union[LatestResourceDescr, InvalidDescr]: ...
390415

@@ -399,6 +424,7 @@ def load_description_and_test(
399424
determinism: Literal["seed_only", "full"] = "seed_only",
400425
expected_type: Optional[str] = None,
401426
sha256: Optional[Sha256] = None,
427+
stop_early: bool = False,
402428
**deprecated: Unpack[DeprecatedKwargs],
403429
) -> Union[ResourceDescr, InvalidDescr]: ...
404430

@@ -412,9 +438,18 @@ def load_description_and_test(
412438
determinism: Literal["seed_only", "full"] = "seed_only",
413439
expected_type: Optional[str] = None,
414440
sha256: Optional[Sha256] = None,
441+
stop_early: bool = False,
415442
**deprecated: Unpack[DeprecatedKwargs],
416443
) -> Union[ResourceDescr, InvalidDescr]:
417-
"""Test RDF dynamically, e.g. model inference of test inputs"""
444+
"""Test a bioimage.io resource dynamically,
445+
for example run prediction of test tensors for models.
446+
447+
See `test_description` for more details.
448+
449+
Returns:
450+
A (possibly invalid) resource description object
451+
with a populated `.validation_summary` attribute.
452+
"""
418453
if isinstance(source, ResourceDescrBase):
419454
root = source.root
420455
file_name = source.file_name
@@ -477,11 +512,15 @@ def load_description_and_test(
477512
enable_determinism(determinism, weight_formats=weight_formats)
478513
for w in weight_formats:
479514
_test_model_inference(rd, w, devices, **deprecated)
480-
if (
481-
not isinstance(rd, v0_4.ModelDescr)
482-
and rd.validation_summary.status == "passed"
483-
):
484-
_test_model_inference_parametrized(rd, w, devices)
515+
if stop_early and rd.validation_summary.status != "passed":
516+
break
517+
518+
if not isinstance(rd, v0_4.ModelDescr):
519+
_test_model_inference_parametrized(
520+
rd, w, devices, stop_early=stop_early
521+
)
522+
if stop_early and rd.validation_summary.status != "passed":
523+
break
485524

486525
# TODO: add execution of jupyter notebooks
487526
# TODO: add more tests
@@ -631,6 +670,8 @@ def _test_model_inference_parametrized(
631670
model: v0_5.ModelDescr,
632671
weight_format: SupportedWeightsFormat,
633672
devices: Optional[Sequence[str]],
673+
*,
674+
stop_early: bool,
634675
) -> None:
635676
if not any(
636677
isinstance(a.size, v0_5.ParameterizedSize)
@@ -772,6 +813,8 @@ def get_ns(n: int):
772813
),
773814
)
774815
)
816+
if stop_early and error is not None:
817+
break
775818
except Exception as e:
776819
if validation_context_var.get().raise_errors:
777820
raise e

bioimageio/core/cli.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,11 @@ class TestCmd(CmdBase, WithSource, WithSummaryLogging):
185185
determinism: Literal["seed_only", "full"] = "seed_only"
186186
"""Modes to improve reproducibility of test outputs."""
187187

188+
stop_early: bool = Field(
189+
False, alias="stop-early", validation_alias=AliasChoices("stop-early", "x")
190+
)
191+
"""Do not run further subtests after a failed one."""
192+
188193
def run(self):
189194
sys.exit(
190195
test(

tests/test_bioimageio_collection.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ def test_rdf(
6363

6464
from bioimageio.core import load_description_and_test
6565

66-
descr = load_description_and_test(descr_url, sha256=sha)
66+
descr = load_description_and_test(descr_url, sha256=sha, stop_early=True)
6767
assert not isinstance(descr, InvalidDescr)
6868
assert (
6969
descr.validation_summary.status == "passed"

0 commit comments

Comments
 (0)