|
| 1 | +import pytest |
| 2 | + |
1 | 3 | from apsis.cond import Condition |
2 | 4 | from apsis.cond.dependency import Dependency |
3 | 5 | from apsis.cond.skip_duplicate import SkipDuplicate |
|
10 | 12 | JOBS = { |
11 | 13 | "testjob0": Job("testjob0", {"foo"}, (), None), |
12 | 14 | "testjob1": Job("testjob1", {"foo", "bar"}, (), None), |
| 15 | + "dep/us": Job("dep/us", {"date"}, (), None), |
| 16 | + "dep/eu": Job("dep/eu", {"date"}, (), None), |
13 | 17 | } |
14 | 18 |
|
15 | 19 |
|
@@ -57,6 +61,76 @@ def test_bind3(): |
57 | 61 | assert bound.states == dep.states |
58 | 62 |
|
59 | 63 |
|
| 64 | +def test_bind_parametrized_job_id(): |
| 65 | + # Dependency job_id is a template expanded from the run's args. |
| 66 | + dep = Dependency("dep/{{ region }}", {}) |
| 67 | + run = Run(Instance("testjob0", {"foo": "x", "region": "us"})) |
| 68 | + # Use a jobs dict that includes the expanded job_id. |
| 69 | + jobs = {**JOBS, "dep/us": Job("dep/us", {"foo"}, (), None)} |
| 70 | + bound = dep.bind(run, jobs) |
| 71 | + |
| 72 | + assert bound.job_id == "dep/us" |
| 73 | + assert bound.args == {"foo": "x"} |
| 74 | + |
| 75 | + |
| 76 | +def test_bind_parametrized_job_id_with_args(): |
| 77 | + # Templated job_id combined with templated args. |
| 78 | + dep = Dependency("dep/{{ region }}", {"date": "{{ date }}"}) |
| 79 | + run = Run(Instance("testjob0", {"foo": "x", "region": "eu", "date": "2024-01-01"})) |
| 80 | + bound = dep.bind(run, JOBS) |
| 81 | + |
| 82 | + assert bound.job_id == "dep/eu" |
| 83 | + assert bound.args == {"date": "2024-01-01"} |
| 84 | + |
| 85 | + |
| 86 | +def test_bind_parametrized_job_id_inherited_args(): |
| 87 | + # Templated job_id with args inherited from the run. |
| 88 | + dep = Dependency("dep/{{ region }}", {}) |
| 89 | + run = Run(Instance("testjob0", {"foo": "x", "region": "us", "date": "2024-03-15"})) |
| 90 | + jobs = {**JOBS, "dep/us": Job("dep/us", {"date"}, (), None)} |
| 91 | + bound = dep.bind(run, jobs) |
| 92 | + |
| 93 | + assert bound.job_id == "dep/us" |
| 94 | + assert bound.args == {"date": "2024-03-15"} |
| 95 | + |
| 96 | + |
| 97 | +def test_bind_parametrized_job_id_not_found(): |
| 98 | + # Templated job_id that expands to a nonexistent job. |
| 99 | + dep = Dependency("dep/{{ region }}", {}) |
| 100 | + run = Run(Instance("testjob0", {"foo": "x", "region": "xx"})) |
| 101 | + with pytest.raises(LookupError): |
| 102 | + dep.bind(run, JOBS) |
| 103 | + |
| 104 | + |
| 105 | +def test_bind_parametrized_job_id_missing_param(): |
| 106 | + # Templated job_id referencing a param not in the run's args. |
| 107 | + dep = Dependency("dep/{{ region }}", {}) |
| 108 | + run = Run(Instance("testjob0", {"foo": "x"})) |
| 109 | + with pytest.raises(NameError): |
| 110 | + dep.bind(run, JOBS) |
| 111 | + |
| 112 | + |
| 113 | +def test_bind_literal_job_id_unchanged(): |
| 114 | + # A literal job_id (no template) still works as before. |
| 115 | + dep = Dependency("testjob0", {"foo": "banana"}) |
| 116 | + run = Run(Instance("testjob1", {"foo": "apple", "bar": "celery"})) |
| 117 | + bound = dep.bind(run, JOBS) |
| 118 | + |
| 119 | + assert bound.job_id == "testjob0" |
| 120 | + assert bound.args == {"foo": "banana"} |
| 121 | + |
| 122 | + |
| 123 | +def test_bind_parametrized_job_id_jso_roundtrip(): |
| 124 | + # Verify that a dependency with a templated job_id survives JSO roundtrip |
| 125 | + # (the unbound form preserves the template). |
| 126 | + dep = Dependency("dep/{{ region }}", {"date": "2024-01-01"}) |
| 127 | + jso = dep.to_jso() |
| 128 | + restored = Condition.from_jso(jso) |
| 129 | + |
| 130 | + assert restored.job_id == "dep/{{ region }}" |
| 131 | + assert restored.args == {"date": "2024-01-01"} |
| 132 | + |
| 133 | + |
60 | 134 | def test_skip_duplicate_jso(): |
61 | 135 | cond = SkipDuplicate() |
62 | 136 | cond = Condition.from_jso(cond.to_jso()) |
|
0 commit comments