hpcflow-new2 0.2.0a188__py3-none-any.whl → 0.2.0a190__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hpcflow/__pyinstaller/hook-hpcflow.py +8 -6
- hpcflow/_version.py +1 -1
- hpcflow/app.py +1 -0
- hpcflow/data/scripts/main_script_test_hdf5_in_obj.py +1 -1
- hpcflow/data/scripts/main_script_test_hdf5_out_obj.py +1 -1
- hpcflow/sdk/__init__.py +21 -15
- hpcflow/sdk/app.py +2133 -770
- hpcflow/sdk/cli.py +281 -250
- hpcflow/sdk/cli_common.py +6 -2
- hpcflow/sdk/config/__init__.py +1 -1
- hpcflow/sdk/config/callbacks.py +77 -42
- hpcflow/sdk/config/cli.py +126 -103
- hpcflow/sdk/config/config.py +578 -311
- hpcflow/sdk/config/config_file.py +131 -95
- hpcflow/sdk/config/errors.py +112 -85
- hpcflow/sdk/config/types.py +145 -0
- hpcflow/sdk/core/actions.py +1054 -994
- hpcflow/sdk/core/app_aware.py +24 -0
- hpcflow/sdk/core/cache.py +81 -63
- hpcflow/sdk/core/command_files.py +275 -185
- hpcflow/sdk/core/commands.py +111 -107
- hpcflow/sdk/core/element.py +724 -503
- hpcflow/sdk/core/enums.py +192 -0
- hpcflow/sdk/core/environment.py +74 -93
- hpcflow/sdk/core/errors.py +398 -51
- hpcflow/sdk/core/json_like.py +540 -272
- hpcflow/sdk/core/loop.py +380 -334
- hpcflow/sdk/core/loop_cache.py +160 -43
- hpcflow/sdk/core/object_list.py +370 -207
- hpcflow/sdk/core/parameters.py +728 -600
- hpcflow/sdk/core/rule.py +59 -41
- hpcflow/sdk/core/run_dir_files.py +33 -22
- hpcflow/sdk/core/task.py +1546 -1325
- hpcflow/sdk/core/task_schema.py +240 -196
- hpcflow/sdk/core/test_utils.py +126 -88
- hpcflow/sdk/core/types.py +387 -0
- hpcflow/sdk/core/utils.py +410 -305
- hpcflow/sdk/core/validation.py +82 -9
- hpcflow/sdk/core/workflow.py +1192 -1028
- hpcflow/sdk/core/zarr_io.py +98 -137
- hpcflow/sdk/demo/cli.py +46 -33
- hpcflow/sdk/helper/cli.py +18 -16
- hpcflow/sdk/helper/helper.py +75 -63
- hpcflow/sdk/helper/watcher.py +61 -28
- hpcflow/sdk/log.py +83 -59
- hpcflow/sdk/persistence/__init__.py +8 -31
- hpcflow/sdk/persistence/base.py +988 -586
- hpcflow/sdk/persistence/defaults.py +6 -0
- hpcflow/sdk/persistence/discovery.py +38 -0
- hpcflow/sdk/persistence/json.py +408 -153
- hpcflow/sdk/persistence/pending.py +158 -123
- hpcflow/sdk/persistence/store_resource.py +37 -22
- hpcflow/sdk/persistence/types.py +307 -0
- hpcflow/sdk/persistence/utils.py +14 -11
- hpcflow/sdk/persistence/zarr.py +477 -420
- hpcflow/sdk/runtime.py +44 -41
- hpcflow/sdk/submission/{jobscript_info.py → enums.py} +39 -12
- hpcflow/sdk/submission/jobscript.py +444 -404
- hpcflow/sdk/submission/schedulers/__init__.py +133 -40
- hpcflow/sdk/submission/schedulers/direct.py +97 -71
- hpcflow/sdk/submission/schedulers/sge.py +132 -126
- hpcflow/sdk/submission/schedulers/slurm.py +263 -268
- hpcflow/sdk/submission/schedulers/utils.py +7 -2
- hpcflow/sdk/submission/shells/__init__.py +14 -15
- hpcflow/sdk/submission/shells/base.py +102 -29
- hpcflow/sdk/submission/shells/bash.py +72 -55
- hpcflow/sdk/submission/shells/os_version.py +31 -30
- hpcflow/sdk/submission/shells/powershell.py +37 -29
- hpcflow/sdk/submission/submission.py +203 -257
- hpcflow/sdk/submission/types.py +143 -0
- hpcflow/sdk/typing.py +163 -12
- hpcflow/tests/conftest.py +8 -6
- hpcflow/tests/schedulers/slurm/test_slurm_submission.py +5 -2
- hpcflow/tests/scripts/test_main_scripts.py +60 -30
- hpcflow/tests/shells/wsl/test_wsl_submission.py +6 -4
- hpcflow/tests/unit/test_action.py +86 -75
- hpcflow/tests/unit/test_action_rule.py +9 -4
- hpcflow/tests/unit/test_app.py +13 -6
- hpcflow/tests/unit/test_cli.py +1 -1
- hpcflow/tests/unit/test_command.py +71 -54
- hpcflow/tests/unit/test_config.py +20 -15
- hpcflow/tests/unit/test_config_file.py +21 -18
- hpcflow/tests/unit/test_element.py +58 -62
- hpcflow/tests/unit/test_element_iteration.py +3 -1
- hpcflow/tests/unit/test_element_set.py +29 -19
- hpcflow/tests/unit/test_group.py +4 -2
- hpcflow/tests/unit/test_input_source.py +116 -93
- hpcflow/tests/unit/test_input_value.py +29 -24
- hpcflow/tests/unit/test_json_like.py +44 -35
- hpcflow/tests/unit/test_loop.py +65 -58
- hpcflow/tests/unit/test_object_list.py +17 -12
- hpcflow/tests/unit/test_parameter.py +16 -7
- hpcflow/tests/unit/test_persistence.py +48 -35
- hpcflow/tests/unit/test_resources.py +20 -18
- hpcflow/tests/unit/test_run.py +8 -3
- hpcflow/tests/unit/test_runtime.py +2 -1
- hpcflow/tests/unit/test_schema_input.py +23 -15
- hpcflow/tests/unit/test_shell.py +3 -2
- hpcflow/tests/unit/test_slurm.py +8 -7
- hpcflow/tests/unit/test_submission.py +39 -19
- hpcflow/tests/unit/test_task.py +352 -247
- hpcflow/tests/unit/test_task_schema.py +33 -20
- hpcflow/tests/unit/test_utils.py +9 -11
- hpcflow/tests/unit/test_value_sequence.py +15 -12
- hpcflow/tests/unit/test_workflow.py +114 -83
- hpcflow/tests/unit/test_workflow_template.py +0 -1
- hpcflow/tests/workflows/test_jobscript.py +2 -1
- hpcflow/tests/workflows/test_workflows.py +18 -13
- {hpcflow_new2-0.2.0a188.dist-info → hpcflow_new2-0.2.0a190.dist-info}/METADATA +2 -1
- hpcflow_new2-0.2.0a190.dist-info/RECORD +165 -0
- hpcflow/sdk/core/parallel.py +0 -21
- hpcflow_new2-0.2.0a188.dist-info/RECORD +0 -158
- {hpcflow_new2-0.2.0a188.dist-info → hpcflow_new2-0.2.0a190.dist-info}/LICENSE +0 -0
- {hpcflow_new2-0.2.0a188.dist-info → hpcflow_new2-0.2.0a190.dist-info}/WHEEL +0 -0
- {hpcflow_new2-0.2.0a188.dist-info → hpcflow_new2-0.2.0a190.dist-info}/entry_points.txt +0 -0
@@ -1,4 +1,7 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from pathlib import Path
|
1
3
|
from textwrap import dedent
|
4
|
+
from typing import Any, TYPE_CHECKING
|
2
5
|
import pytest
|
3
6
|
from hpcflow.app import app as hf
|
4
7
|
from hpcflow.sdk.core.errors import UnsetParameterDataError
|
@@ -8,14 +11,15 @@ from hpcflow.sdk.core.test_utils import (
|
|
8
11
|
P1_sub_parameter_cls as P1_sub,
|
9
12
|
)
|
10
13
|
|
14
|
+
if TYPE_CHECKING:
|
15
|
+
from hpcflow.sdk.core.workflow import Workflow
|
16
|
+
|
11
17
|
|
12
18
|
@pytest.fixture
|
13
|
-
def workflow_w1(null_config, tmp_path):
|
19
|
+
def workflow_w1(null_config, tmp_path: Path) -> Workflow:
|
14
20
|
s1, s2 = make_schemas(
|
15
|
-
|
16
|
-
|
17
|
-
[{"p2": None}, (), "t2"],
|
18
|
-
]
|
21
|
+
({"p1": None}, ("p2",), "t1"),
|
22
|
+
({"p2": None}, (), "t2"),
|
19
23
|
)
|
20
24
|
|
21
25
|
t1 = hf.Task(
|
@@ -28,38 +32,30 @@ def workflow_w1(null_config, tmp_path):
|
|
28
32
|
return hf.Workflow.from_template(wkt, path=tmp_path)
|
29
33
|
|
30
34
|
|
31
|
-
def test_element_task_dependencies(workflow_w1):
|
35
|
+
def test_element_task_dependencies(workflow_w1: Workflow):
|
32
36
|
assert workflow_w1.tasks.t2.elements[0].get_task_dependencies(as_objects=True) == [
|
33
37
|
workflow_w1.tasks.t1
|
34
38
|
]
|
35
39
|
|
36
40
|
|
37
|
-
def test_element_dependent_tasks(workflow_w1):
|
41
|
+
def test_element_dependent_tasks(workflow_w1: Workflow):
|
38
42
|
assert workflow_w1.tasks.t1.elements[0].get_dependent_tasks(as_objects=True) == [
|
39
43
|
workflow_w1.tasks.t2
|
40
44
|
]
|
41
45
|
|
42
46
|
|
43
|
-
def test_element_element_dependencies(workflow_w1):
|
44
|
-
assert
|
45
|
-
|
46
|
-
workflow_w1.tasks.t2.elements[0].get_element_dependencies() == [0],
|
47
|
-
workflow_w1.tasks.t2.elements[1].get_element_dependencies() == [1],
|
48
|
-
)
|
49
|
-
)
|
47
|
+
def test_element_element_dependencies(workflow_w1: Workflow):
|
48
|
+
assert workflow_w1.tasks.t2.elements[0].get_element_dependencies() == {0}
|
49
|
+
assert workflow_w1.tasks.t2.elements[1].get_element_dependencies() == {1}
|
50
50
|
|
51
51
|
|
52
|
-
def test_element_dependent_elements(workflow_w1):
|
53
|
-
assert
|
54
|
-
|
55
|
-
workflow_w1.tasks.t1.elements[0].get_dependent_elements() == [2],
|
56
|
-
workflow_w1.tasks.t1.elements[1].get_dependent_elements() == [3],
|
57
|
-
)
|
58
|
-
)
|
52
|
+
def test_element_dependent_elements(workflow_w1: Workflow):
|
53
|
+
assert workflow_w1.tasks.t1.elements[0].get_dependent_elements() == {2}
|
54
|
+
assert workflow_w1.tasks.t1.elements[1].get_dependent_elements() == {3}
|
59
55
|
|
60
56
|
|
61
57
|
def test_equivalence_single_labelled_schema_input_element_get_label_and_non_label(
|
62
|
-
new_null_config, tmp_path
|
58
|
+
new_null_config, tmp_path: Path
|
63
59
|
):
|
64
60
|
s1 = hf.TaskSchema(
|
65
61
|
objective="t1",
|
@@ -83,7 +79,7 @@ def test_equivalence_single_labelled_schema_input_element_get_label_and_non_labe
|
|
83
79
|
)
|
84
80
|
|
85
81
|
|
86
|
-
def test_element_dependencies_inputs_only_schema(new_null_config, tmp_path):
|
82
|
+
def test_element_dependencies_inputs_only_schema(new_null_config, tmp_path: Path):
|
87
83
|
s1 = hf.TaskSchema(
|
88
84
|
objective="t1",
|
89
85
|
inputs=[hf.SchemaInput(parameter=hf.Parameter("p1"))],
|
@@ -115,12 +111,12 @@ def test_element_dependencies_inputs_only_schema(new_null_config, tmp_path):
|
|
115
111
|
path=tmp_path,
|
116
112
|
template_name="wk0",
|
117
113
|
)
|
118
|
-
assert wk.tasks.t1.elements[0].get_dependent_elements() ==
|
119
|
-
assert wk.tasks.t2.elements[0].get_element_dependencies() ==
|
120
|
-
assert wk.tasks.t2.elements[0].get_EAR_dependencies() ==
|
114
|
+
assert wk.tasks.t1.elements[0].get_dependent_elements() == {1}
|
115
|
+
assert wk.tasks.t2.elements[0].get_element_dependencies() == {0}
|
116
|
+
assert wk.tasks.t2.elements[0].get_EAR_dependencies() == {0}
|
121
117
|
|
122
118
|
|
123
|
-
def test_element_get_empty_path_single_labelled_input(null_config, tmp_path):
|
119
|
+
def test_element_get_empty_path_single_labelled_input(null_config, tmp_path: Path):
|
124
120
|
p1_val = 101
|
125
121
|
label = "my_label"
|
126
122
|
s1 = hf.TaskSchema(
|
@@ -138,7 +134,7 @@ def test_element_get_empty_path_single_labelled_input(null_config, tmp_path):
|
|
138
134
|
}
|
139
135
|
|
140
136
|
|
141
|
-
def test_element_get_labelled_non_labelled_equivalence(null_config, tmp_path):
|
137
|
+
def test_element_get_labelled_non_labelled_equivalence(null_config, tmp_path: Path):
|
142
138
|
p1_val = 101
|
143
139
|
label = "my_label"
|
144
140
|
s1 = hf.TaskSchema(
|
@@ -156,7 +152,7 @@ def test_element_get_labelled_non_labelled_equivalence(null_config, tmp_path):
|
|
156
152
|
|
157
153
|
|
158
154
|
@pytest.fixture
|
159
|
-
def element_get_wk(null_config, tmp_path):
|
155
|
+
def element_get_wk(null_config, tmp_path: Path) -> Workflow:
|
160
156
|
s1 = hf.TaskSchema(
|
161
157
|
objective="t1",
|
162
158
|
inputs=[hf.SchemaInput(parameter="p1"), hf.SchemaInput(parameter="p1c")],
|
@@ -191,62 +187,62 @@ def element_get_wk(null_config, tmp_path):
|
|
191
187
|
return wk
|
192
188
|
|
193
189
|
|
194
|
-
def test_element_get_simple(element_get_wk):
|
190
|
+
def test_element_get_simple(element_get_wk: Workflow):
|
195
191
|
assert element_get_wk.tasks.t1.elements[0].get("inputs.p1") == 100
|
196
192
|
assert element_get_wk.tasks.t1.elements[1].get("inputs.p1") == 100
|
197
193
|
|
198
194
|
|
199
|
-
def test_element_get_obj(element_get_wk):
|
195
|
+
def test_element_get_obj(element_get_wk: Workflow):
|
200
196
|
obj_0 = P1(a=20, sub_param=P1_sub(e=5))
|
201
197
|
obj_1 = P1(a=30, sub_param=P1_sub(e=5))
|
202
198
|
assert element_get_wk.tasks.t1.elements[0].get("inputs.p1c") == obj_0
|
203
199
|
assert element_get_wk.tasks.t1.elements[1].get("inputs.p1c") == obj_1
|
204
200
|
|
205
201
|
|
206
|
-
def test_element_get_sub_obj(element_get_wk):
|
202
|
+
def test_element_get_sub_obj(element_get_wk: Workflow):
|
207
203
|
sub_obj = P1_sub(e=5)
|
208
204
|
assert element_get_wk.tasks.t1.elements[0].get("inputs.p1c.sub_param") == sub_obj
|
209
205
|
assert element_get_wk.tasks.t1.elements[1].get("inputs.p1c.sub_param") == sub_obj
|
210
206
|
|
211
207
|
|
212
|
-
def test_element_get_sub_obj_attr(element_get_wk):
|
208
|
+
def test_element_get_sub_obj_attr(element_get_wk: Workflow):
|
213
209
|
assert element_get_wk.tasks.t1.elements[0].get("inputs.p1c.sub_param.e") == 5
|
214
210
|
assert element_get_wk.tasks.t1.elements[1].get("inputs.p1c.sub_param.e") == 5
|
215
211
|
|
216
212
|
|
217
|
-
def test_element_get_sub_obj_property(element_get_wk):
|
213
|
+
def test_element_get_sub_obj_property(element_get_wk: Workflow):
|
218
214
|
assert element_get_wk.tasks.t1.elements[0].get("inputs.p1c.sub_param.twice_e") == 10
|
219
215
|
assert element_get_wk.tasks.t1.elements[1].get("inputs.p1c.sub_param.twice_e") == 10
|
220
216
|
|
221
217
|
|
222
|
-
def test_element_get_obj_no_raise_missing_attr(element_get_wk):
|
218
|
+
def test_element_get_obj_no_raise_missing_attr(element_get_wk: Workflow):
|
223
219
|
assert element_get_wk.tasks.t1.elements[0].get("inputs.p1c.b") is None
|
224
220
|
|
225
221
|
|
226
|
-
def test_element_get_obj_raise_missing_attr(element_get_wk):
|
222
|
+
def test_element_get_obj_raise_missing_attr(element_get_wk: Workflow):
|
227
223
|
with pytest.raises(ValueError):
|
228
224
|
element_get_wk.tasks.t1.elements[0].get("inputs.p1c.b", raise_on_missing=True)
|
229
225
|
|
230
226
|
|
231
|
-
def test_element_get_obj_raise_missing_nested_attr(element_get_wk):
|
227
|
+
def test_element_get_obj_raise_missing_nested_attr(element_get_wk: Workflow):
|
232
228
|
with pytest.raises(ValueError):
|
233
229
|
element_get_wk.tasks.t1.elements[0].get("inputs.p1c.a.b", raise_on_missing=True)
|
234
230
|
|
235
231
|
|
236
|
-
def test_element_get_raise_missing_root(element_get_wk):
|
232
|
+
def test_element_get_raise_missing_root(element_get_wk: Workflow):
|
237
233
|
with pytest.raises(ValueError):
|
238
234
|
element_get_wk.tasks.t1.elements[0].get("blah", raise_on_missing=True)
|
239
235
|
|
240
236
|
|
241
|
-
def test_element_get_no_raise_missing_root(element_get_wk):
|
237
|
+
def test_element_get_no_raise_missing_root(element_get_wk: Workflow):
|
242
238
|
assert element_get_wk.tasks.t1.elements[0].get("blah") is None
|
243
239
|
|
244
240
|
|
245
|
-
def test_element_get_expected_default(element_get_wk):
|
241
|
+
def test_element_get_expected_default(element_get_wk: Workflow):
|
246
242
|
assert element_get_wk.tasks.t1.elements[0].get("blah", default={}) == {}
|
247
243
|
|
248
244
|
|
249
|
-
def test_element_get_part_unset(null_config, tmp_path):
|
245
|
+
def test_element_get_part_unset(null_config, tmp_path: Path):
|
250
246
|
s1 = hf.TaskSchema(
|
251
247
|
objective="t1",
|
252
248
|
inputs=[hf.SchemaInput(parameter="p1")],
|
@@ -299,7 +295,7 @@ def test_element_get_part_unset(null_config, tmp_path):
|
|
299
295
|
wk.tasks.t2.elements[0].get("inputs.p2", raise_on_unset=True)
|
300
296
|
|
301
297
|
|
302
|
-
def test_element_get_unset_object(null_config, tmp_path):
|
298
|
+
def test_element_get_unset_object(null_config, tmp_path: Path):
|
303
299
|
s1 = hf.TaskSchema(
|
304
300
|
objective="t1",
|
305
301
|
inputs=[hf.SchemaInput(parameter="p1")],
|
@@ -328,7 +324,7 @@ def test_element_get_unset_object(null_config, tmp_path):
|
|
328
324
|
assert wk.tasks.t1.elements[0].get("outputs.p1c") == None
|
329
325
|
|
330
326
|
|
331
|
-
def test_element_get_unset_sub_object(null_config, tmp_path):
|
327
|
+
def test_element_get_unset_sub_object(null_config, tmp_path: Path):
|
332
328
|
s1 = hf.TaskSchema(
|
333
329
|
objective="t1",
|
334
330
|
inputs=[hf.SchemaInput(parameter="p1")],
|
@@ -357,7 +353,7 @@ def test_element_get_unset_sub_object(null_config, tmp_path):
|
|
357
353
|
assert wk.tasks.t1.elements[0].get("outputs.p1c.sub_param") == None
|
358
354
|
|
359
355
|
|
360
|
-
def test_element_get_unset_object_group(null_config, tmp_path):
|
356
|
+
def test_element_get_unset_object_group(null_config, tmp_path: Path):
|
361
357
|
s1 = hf.TaskSchema(
|
362
358
|
objective="t1",
|
363
359
|
inputs=[hf.SchemaInput(parameter="p1c")],
|
@@ -397,7 +393,7 @@ def test_element_get_unset_object_group(null_config, tmp_path):
|
|
397
393
|
assert wk.tasks.t2.elements[0].get("inputs.p1c") == [None, None]
|
398
394
|
|
399
395
|
|
400
|
-
def test_element_get_unset_sub_object_group(null_config, tmp_path):
|
396
|
+
def test_element_get_unset_sub_object_group(null_config, tmp_path: Path):
|
401
397
|
s1 = hf.TaskSchema(
|
402
398
|
objective="t1",
|
403
399
|
inputs=[hf.SchemaInput(parameter="p1c")],
|
@@ -437,7 +433,7 @@ def test_element_get_unset_sub_object_group(null_config, tmp_path):
|
|
437
433
|
assert wk.tasks.t2.elements[0].get("inputs.p1c.sub_param") == [None, None]
|
438
434
|
|
439
435
|
|
440
|
-
def test_iter(new_null_config, tmp_path):
|
436
|
+
def test_iter(new_null_config, tmp_path: Path):
|
441
437
|
wkt = hf.WorkflowTemplate(
|
442
438
|
name="test",
|
443
439
|
tasks=[
|
@@ -452,7 +448,7 @@ def test_iter(new_null_config, tmp_path):
|
|
452
448
|
assert elem_i.index == idx
|
453
449
|
|
454
450
|
|
455
|
-
def test_slice(new_null_config, tmp_path):
|
451
|
+
def test_slice(new_null_config, tmp_path: Path):
|
456
452
|
wkt = hf.WorkflowTemplate(
|
457
453
|
name="test",
|
458
454
|
tasks=[
|
@@ -469,7 +465,7 @@ def test_slice(new_null_config, tmp_path):
|
|
469
465
|
assert elems[1].index == 2
|
470
466
|
|
471
467
|
|
472
|
-
def test_element_get_with_list_index_sequence(null_config, tmp_path):
|
468
|
+
def test_element_get_with_list_index_sequence(null_config, tmp_path: Path):
|
473
469
|
wkt_yaml = dedent(
|
474
470
|
"""\
|
475
471
|
name: test_list_idx_sequence
|
@@ -487,7 +483,7 @@ def test_element_get_with_list_index_sequence(null_config, tmp_path):
|
|
487
483
|
assert wk.tasks[0].elements[0].get("inputs.p1") == [9, 1]
|
488
484
|
|
489
485
|
|
490
|
-
def test_element_get_with_list_index_sequence_two_parts(null_config, tmp_path):
|
486
|
+
def test_element_get_with_list_index_sequence_two_parts(null_config, tmp_path: Path):
|
491
487
|
wkt_yaml = dedent(
|
492
488
|
"""\
|
493
489
|
name: test_list_idx_sequence
|
@@ -515,7 +511,7 @@ def test_element_get_with_list_index_sequence_two_parts(null_config, tmp_path):
|
|
515
511
|
]
|
516
512
|
|
517
513
|
|
518
|
-
def test_element_get_group_sequence(null_config, tmp_path):
|
514
|
+
def test_element_get_group_sequence(null_config, tmp_path: Path):
|
519
515
|
wkt_yaml = dedent(
|
520
516
|
"""\
|
521
517
|
name: test_list_idx_sequence
|
@@ -553,7 +549,7 @@ def test_element_get_group_sequence(null_config, tmp_path):
|
|
553
549
|
]
|
554
550
|
|
555
551
|
|
556
|
-
def test_element_get_group_sequence_obj(new_null_config, tmp_path):
|
552
|
+
def test_element_get_group_sequence_obj(new_null_config, tmp_path: Path):
|
557
553
|
wkt_yaml = dedent(
|
558
554
|
"""\
|
559
555
|
name: test_list_idx_sequence
|
@@ -607,29 +603,28 @@ def test_element_get_group_sequence_obj(new_null_config, tmp_path):
|
|
607
603
|
]
|
608
604
|
|
609
605
|
|
610
|
-
def test_element_resources_get_jobscript_hash_equal_empty():
|
606
|
+
def test_element_resources_get_jobscript_hash_equal_empty() -> None:
|
611
607
|
assert (
|
612
608
|
hf.ElementResources().get_jobscript_hash()
|
613
609
|
== hf.ElementResources().get_jobscript_hash()
|
614
610
|
)
|
615
611
|
|
616
612
|
|
617
|
-
def test_element_resources_get_jobscript_hash_unequal_num_cores():
|
613
|
+
def test_element_resources_get_jobscript_hash_unequal_num_cores() -> None:
|
618
614
|
assert (
|
619
615
|
hf.ElementResources(num_cores=1).get_jobscript_hash()
|
620
616
|
!= hf.ElementResources(num_cores=2).get_jobscript_hash()
|
621
617
|
)
|
622
618
|
|
623
619
|
|
624
|
-
def test_element_resources_get_jobscript_hash_equal_num_cores():
|
620
|
+
def test_element_resources_get_jobscript_hash_equal_num_cores() -> None:
|
625
621
|
assert (
|
626
622
|
hf.ElementResources(num_cores=1).get_jobscript_hash()
|
627
623
|
== hf.ElementResources(num_cores=1).get_jobscript_hash()
|
628
624
|
)
|
629
625
|
|
630
626
|
|
631
|
-
def test_element_resources_get_jobscript_hash_unequal_scheduler_args_empty():
|
632
|
-
|
627
|
+
def test_element_resources_get_jobscript_hash_unequal_scheduler_args_empty() -> None:
|
633
628
|
assert (
|
634
629
|
hf.ElementResources().get_jobscript_hash()
|
635
630
|
!= hf.ElementResources(
|
@@ -638,16 +633,16 @@ def test_element_resources_get_jobscript_hash_unequal_scheduler_args_empty():
|
|
638
633
|
)
|
639
634
|
|
640
635
|
|
641
|
-
def test_element_resources_get_jobscript_hash_equal_non_truthy_scheduler_args():
|
642
|
-
|
636
|
+
def test_element_resources_get_jobscript_hash_equal_non_truthy_scheduler_args() -> None:
|
643
637
|
assert (
|
644
638
|
hf.ElementResources().get_jobscript_hash()
|
645
639
|
== hf.ElementResources(scheduler_args={}).get_jobscript_hash()
|
646
640
|
)
|
647
641
|
|
648
642
|
|
649
|
-
def test_element_resources_get_jobscript_hash_unequal_scheduler_args_diff_options()
|
650
|
-
|
643
|
+
def test_element_resources_get_jobscript_hash_unequal_scheduler_args_diff_options() -> (
|
644
|
+
None
|
645
|
+
):
|
651
646
|
assert (
|
652
647
|
hf.ElementResources(
|
653
648
|
scheduler_args={"options": {"--time": "02:00:00"}}
|
@@ -658,8 +653,9 @@ def test_element_resources_get_jobscript_hash_unequal_scheduler_args_diff_option
|
|
658
653
|
)
|
659
654
|
|
660
655
|
|
661
|
-
def test_element_resources_get_jobscript_hash_unequal_scheduler_args_same_options()
|
662
|
-
|
656
|
+
def test_element_resources_get_jobscript_hash_unequal_scheduler_args_same_options() -> (
|
657
|
+
None
|
658
|
+
):
|
663
659
|
assert (
|
664
660
|
hf.ElementResources(
|
665
661
|
scheduler_args={"options": {"--time": "02:00:00"}}
|
@@ -1,9 +1,11 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from pathlib import Path
|
1
3
|
import pytest
|
2
4
|
from hpcflow.app import app as hf
|
3
5
|
|
4
6
|
|
5
7
|
@pytest.mark.parametrize("store", ["json", "zarr"])
|
6
|
-
def test_decode(null_config, tmp_path, store):
|
8
|
+
def test_decode(null_config, tmp_path: Path, store: str):
|
7
9
|
s1 = hf.TaskSchema(
|
8
10
|
objective="t1",
|
9
11
|
inputs=[hf.SchemaInput(parameter=hf.Parameter("p1"))],
|
@@ -1,31 +1,41 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import TYPE_CHECKING
|
1
3
|
import pytest
|
2
4
|
from hpcflow.app import app as hf
|
3
5
|
from hpcflow.sdk.core.errors import MalformedNestingOrderPath
|
4
6
|
|
7
|
+
if TYPE_CHECKING:
|
8
|
+
from pathlib import Path
|
9
|
+
from hpcflow.sdk.core.parameters import Parameter
|
10
|
+
from hpcflow.sdk.core.types import ResourceSpecArgs
|
11
|
+
from hpcflow.sdk.core.workflow import Workflow
|
12
|
+
|
5
13
|
|
6
14
|
@pytest.fixture
|
7
|
-
def null_config(tmp_path):
|
15
|
+
def null_config(tmp_path: Path):
|
8
16
|
if not hf.is_config_loaded:
|
9
17
|
hf.load_config(config_dir=tmp_path)
|
10
18
|
|
11
19
|
|
12
20
|
@pytest.fixture
|
13
|
-
def param_p1():
|
21
|
+
def param_p1() -> Parameter:
|
14
22
|
return hf.Parameter("p1")
|
15
23
|
|
16
24
|
|
17
25
|
@pytest.fixture
|
18
|
-
def param_p2():
|
26
|
+
def param_p2() -> Parameter:
|
19
27
|
return hf.Parameter("p2")
|
20
28
|
|
21
29
|
|
22
30
|
@pytest.fixture
|
23
|
-
def param_p3():
|
31
|
+
def param_p3() -> Parameter:
|
24
32
|
return hf.Parameter("p3")
|
25
33
|
|
26
34
|
|
27
35
|
@pytest.fixture
|
28
|
-
def workflow_w1(
|
36
|
+
def workflow_w1(
|
37
|
+
null_config, tmp_path: Path, param_p1: Parameter, param_p2: Parameter
|
38
|
+
) -> Workflow:
|
29
39
|
s1 = hf.TaskSchema("t1", actions=[], inputs=[param_p1], outputs=[param_p2])
|
30
40
|
s2 = hf.TaskSchema("t2", actions=[], inputs=[param_p2])
|
31
41
|
|
@@ -40,45 +50,45 @@ def workflow_w1(null_config, tmp_path, param_p1, param_p2):
|
|
40
50
|
|
41
51
|
|
42
52
|
@pytest.fixture
|
43
|
-
def workflow_w2(workflow_w1):
|
53
|
+
def workflow_w2(workflow_w1: Workflow) -> Workflow:
|
44
54
|
"""Add another element set to the second task."""
|
45
55
|
workflow_w1.tasks.t2.add_elements(nesting_order={"inputs.p2": 1})
|
46
56
|
return workflow_w1
|
47
57
|
|
48
58
|
|
49
|
-
def test_resources_init_equivalence_dict_list_of_obj():
|
59
|
+
def test_resources_init_equivalence_dict_list_of_obj() -> None:
|
50
60
|
es1 = hf.ElementSet(resources={"any": {"num_cores": 1}})
|
51
61
|
es2 = hf.ElementSet(resources=[hf.ResourceSpec(scope="any", num_cores=1)])
|
52
62
|
assert es1 == es2
|
53
63
|
|
54
64
|
|
55
|
-
def test_resources_init_equivalence_list_list_of_obj():
|
56
|
-
res_1_kwargs = {"scope": "any", "num_cores": 1}
|
65
|
+
def test_resources_init_equivalence_list_list_of_obj() -> None:
|
66
|
+
res_1_kwargs: ResourceSpecArgs = {"scope": "any", "num_cores": 1}
|
57
67
|
es1 = hf.ElementSet(resources=[res_1_kwargs])
|
58
68
|
es2 = hf.ElementSet(resources=[hf.ResourceSpec(**res_1_kwargs)])
|
59
69
|
assert es1 == es2
|
60
70
|
|
61
71
|
|
62
|
-
def test_resources_init_equivalence_list_of_obj_resource_list_obj():
|
63
|
-
res_1_kwargs = {"scope": "any", "num_cores": 1}
|
72
|
+
def test_resources_init_equivalence_list_of_obj_resource_list_obj() -> None:
|
73
|
+
res_1_kwargs: ResourceSpecArgs = {"scope": "any", "num_cores": 1}
|
64
74
|
es1 = hf.ElementSet(resources=[hf.ResourceSpec(**res_1_kwargs)])
|
65
75
|
es2 = hf.ElementSet(resources=hf.ResourceList([hf.ResourceSpec(**res_1_kwargs)]))
|
66
76
|
assert es1 == es2
|
67
77
|
|
68
78
|
|
69
|
-
def test_repeats_single_int_equivalence(null_config):
|
79
|
+
def test_repeats_single_int_equivalence(null_config) -> None:
|
70
80
|
es1 = hf.ElementSet(repeats=2)
|
71
81
|
es2 = hf.ElementSet(repeats=[{"name": "", "number": 2, "nesting_order": 0}])
|
72
82
|
assert es1 == es2
|
73
83
|
|
74
84
|
|
75
|
-
def test_merge_envs(null_config):
|
85
|
+
def test_merge_envs(null_config) -> None:
|
76
86
|
envs = {"my_env": {"version": "1.0"}}
|
77
87
|
es = hf.ElementSet(environments=envs)
|
78
88
|
assert es.resources.get(scope=hf.ActionScope.any()).environments == envs
|
79
89
|
|
80
90
|
|
81
|
-
def test_merge_envs_existing_any_resources(null_config):
|
91
|
+
def test_merge_envs_existing_any_resources(null_config) -> None:
|
82
92
|
envs = {"my_env": {"version": "1.0"}}
|
83
93
|
num_cores = 2
|
84
94
|
es = hf.ElementSet(resources={"any": {"num_cores": num_cores}}, environments=envs)
|
@@ -86,28 +96,28 @@ def test_merge_envs_existing_any_resources(null_config):
|
|
86
96
|
assert es.resources.get(scope=hf.ActionScope.any()).num_cores == num_cores
|
87
97
|
|
88
98
|
|
89
|
-
def test_merge_envs_resource_envs_precedence(null_config):
|
99
|
+
def test_merge_envs_resource_envs_precedence(null_config) -> None:
|
90
100
|
envs = {"my_env": {"version": "1.0"}}
|
91
101
|
res_envs = {"other_env": {"version": "2.0"}}
|
92
102
|
es = hf.ElementSet(resources={"any": {"environments": res_envs}}, environments=envs)
|
93
103
|
assert es.resources.get(scope=hf.ActionScope.any()).environments == res_envs
|
94
104
|
|
95
105
|
|
96
|
-
def test_merge_envs_no_envs_with_resource_envs(null_config):
|
106
|
+
def test_merge_envs_no_envs_with_resource_envs(null_config) -> None:
|
97
107
|
envs = {"my_env": {"version": "1.0"}}
|
98
108
|
es = hf.ElementSet(resources={"any": {"environments": envs}})
|
99
109
|
assert es.resources.get(scope=hf.ActionScope.any()).environments == envs
|
100
110
|
|
101
111
|
|
102
|
-
def test_raise_env_and_envs_specified(null_config):
|
112
|
+
def test_raise_env_and_envs_specified(null_config) -> None:
|
103
113
|
with pytest.raises(ValueError):
|
104
114
|
hf.ElementSet(env_preset="my_preset", environments={"my_env": {"version": 1}})
|
105
115
|
|
106
116
|
|
107
|
-
def test_nesting_order_paths_raise(null_config):
|
117
|
+
def test_nesting_order_paths_raise(null_config) -> None:
|
108
118
|
with pytest.raises(MalformedNestingOrderPath):
|
109
119
|
hf.ElementSet(nesting_order={"bad_path.p1": 1})
|
110
120
|
|
111
121
|
|
112
|
-
def test_nesting_order_paths_no_raise(null_config):
|
122
|
+
def test_nesting_order_paths_no_raise(null_config) -> None:
|
113
123
|
hf.ElementSet(nesting_order={"inputs.p1": 1, "resources.any": 2, "repeats": 3})
|
hpcflow/tests/unit/test_group.py
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from pathlib import Path
|
1
3
|
import pytest
|
2
4
|
from hpcflow.app import app as hf
|
3
5
|
from hpcflow.sdk.core.errors import MissingElementGroup
|
4
6
|
|
5
7
|
|
6
|
-
def test_group_simple(null_config, tmp_path):
|
8
|
+
def test_group_simple(null_config, tmp_path: Path):
|
7
9
|
s1 = hf.TaskSchema(
|
8
10
|
objective="t1",
|
9
11
|
inputs=[hf.SchemaInput("p1")],
|
@@ -48,7 +50,7 @@ def test_group_simple(null_config, tmp_path):
|
|
48
50
|
assert len(wk.tasks.t2.elements[0].get_data_idx("inputs.p2")["inputs.p2"]) == 3
|
49
51
|
|
50
52
|
|
51
|
-
def test_group_raise_no_elements(null_config, tmp_path):
|
53
|
+
def test_group_raise_no_elements(null_config, tmp_path: Path):
|
52
54
|
s1 = hf.TaskSchema(
|
53
55
|
objective="t1",
|
54
56
|
inputs=[hf.SchemaInput("p1")],
|