-
Notifications
You must be signed in to change notification settings - Fork 8
Add option to exit with error status if workflow is incomplete #108
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
4842c99
997ea2f
5b4fea5
dffff3d
c337b7f
d6f4bef
c21a8a0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -48,5 +48,5 @@ | |
| "zarr ==3.1.*" | ||
| ] | ||
| }, | ||
| "version": "0.6.0" | ||
| "version": "0.7.0" | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,13 +30,15 @@ def main() -> None: | |
| c = validated_config(yc) | ||
| if args.check: | ||
| sys.exit(0) | ||
| logging.info("Preparing task graph for %s", args.task) | ||
| logging.info("Preparing task graph for '%s'", args.task) | ||
| task = getattr(workflow, args.task) | ||
| if args.threads > 1: | ||
| logging.info("Using %s threads", args.threads) | ||
| initialize_pool(args.threads) | ||
| initialize_session(args.threads) | ||
| task(c, threads=args.threads) | ||
| node = task(c, threads=args.threads) | ||
| if args.fail and not node.ready: | ||
| fail(f"Task '{args.task}' is incomplete") | ||
|
Comment on lines
+39
to
+41
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Main logic for the new feature. |
||
| except WXVXError as e: | ||
| for line in traceback.format_exc().strip().split("\n"): | ||
| logging.debug(line) | ||
|
|
@@ -85,6 +87,12 @@ def _parse_args(argv: list[str]) -> Namespace: | |
| action="store_true", | ||
| help="Log all messages", | ||
| ) | ||
| optional.add_argument( | ||
| "-f", | ||
| "--fail", | ||
| action="store_true", | ||
| help="Exit with error status if task is incomplete", | ||
| ) | ||
|
Comment on lines
+90
to
+95
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add the new feature to the CLI. |
||
| optional.add_argument( | ||
| "-h", | ||
| "--help", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| { | ||
| "buildnum": "0", | ||
| "version": "0.6.0" | ||
| "version": "0.7.0" | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,16 +2,16 @@ | |
| Tests for wxvx.cli. | ||
| """ | ||
|
|
||
| import logging | ||
| import re | ||
| from argparse import ArgumentTypeError, Namespace | ||
| from pathlib import Path | ||
| from unittest.mock import patch | ||
|
|
||
| import yaml | ||
| from iotaa import Asset, external | ||
| from pytest import mark, raises | ||
|
|
||
| from wxvx import cli | ||
| from wxvx import cli, workflow | ||
| from wxvx.strings import S | ||
| from wxvx.types import Config | ||
| from wxvx.util import WXVXError, pkgname, resource_path | ||
|
|
@@ -25,8 +25,7 @@ | |
| @mark.parametrize("threads", [1, 2]) | ||
| def test_cli_main(config_data, logged, switch_c, switch_n, switch_t, threads, tmp_path): | ||
| cfgfile = tmp_path / "config.yaml" | ||
| with cfgfile.open("w") as f: | ||
| yaml.safe_dump(config_data, f) | ||
| cfgfile.write_text(yaml.safe_dump(config_data)) | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In a few places, I simplified code slightly by using |
||
| argv = [pkgname, switch_c, str(cfgfile), switch_n, str(threads), switch_t, S.plots] | ||
| with ( | ||
| patch.object(cli, "_parse_args", wraps=cli._parse_args) as _parse_args, | ||
|
|
@@ -85,9 +84,30 @@ def test_cli_main__exception(logged): | |
| assert e.value.code == 1 | ||
|
|
||
|
|
||
| @mark.parametrize("switch", ["-f", "--fail", None]) | ||
| def test_cli_main__fail(config_data, switch, tmp_path): | ||
| @external | ||
| def bad(_): | ||
| yield "bad" | ||
| yield Asset(None, lambda: False) | ||
|
|
||
| cfgfile = tmp_path / "config.yaml" | ||
| cfgfile.write_text(yaml.safe_dump(config_data)) | ||
| argv = [pkgname, "-c", str(cfgfile), "-t", "bad", switch] | ||
| with ( | ||
| patch.object(cli.sys, "argv", list(filter(None, argv))), | ||
| patch.object(workflow, "bad", create=True, new=bad), | ||
| ): | ||
| if switch: | ||
| with raises(SystemExit) as e: | ||
| cli.main() | ||
| assert e.value.code == 1 | ||
| else: | ||
| cli.main() | ||
|
Comment on lines
+87
to
+106
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Test for the new feature. I also verified manually with a real config and vx use case. |
||
|
|
||
|
|
||
| @mark.parametrize("switch", ["-l", "--list"]) | ||
| def test_cli_main__task_list(caplog, switch, tidy): | ||
| caplog.set_level(logging.INFO) | ||
| with ( | ||
| patch.object( | ||
| cli.sys, "argv", [pkgname, "-c", str(resource_path("config-grid.yaml")), switch] | ||
|
|
@@ -126,14 +146,13 @@ def test_cli_main__show_config(capsys, check, fs, switch): | |
| assert isinstance(yaml.safe_load(capsys.readouterr().out), dict) | ||
|
|
||
|
|
||
| def test_cli_main__task_missing(caplog): | ||
| caplog.set_level(logging.INFO) | ||
| def test_cli_main__task_missing(logged): | ||
| argv = [pkgname, "-c", str(resource_path("config-grid.yaml")), "-t", "foo"] | ||
| with patch.object(cli.sys, "argv", argv), patch.object(cli, "use_uwtools_logger"): | ||
| with raises(SystemExit) as e: | ||
| cli.main() | ||
| assert e.value.code == 1 | ||
| assert "No such task: foo" in caplog.messages | ||
| assert logged("No such task: foo") | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I simplified a few tests by using the |
||
|
|
||
|
|
||
| def test_cli__arg_type_int_greater_than_zero__pass(): | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.