Skip to content

Commit 2579a22

Browse files
authored
Close #5286 by adding Cromwell-style pair test (#5476)
I synthesized this with moderate badgering and a lot of maching approve on increasingly misguided shell commands. On the plus side this also adds a way to run one misbehaving WDL unit test, and Anthropic Claude somehow got the notion that `pair_serde` should now pass and it turned out to be right.
1 parent 1bc3266 commit 2579a22

File tree

3 files changed

+72
-5
lines changed

3 files changed

+72
-5
lines changed

BOTS.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,18 @@ Tests use pytest. Example commands:
2525
# Run tests with a keyword filter
2626
./venv/bin/python -m pytest src/toil/test -k "safe" -v
2727
```
28+
29+
## Running Individual WDL Spec Unit Tests
30+
31+
The WDL spec embeds example workflows as unit tests (under the `wdl-1.1` and `wdl-1.2` branches of `https://github.com/openwdl/wdl`). `TestWDLConformance.test_single_unit_test` in `src/toil/test/wdl/wdltoil_test.py` runs one such test at a time and is controlled by environment variables:
32+
33+
- `WDL_UNIT_TEST_ID`: which test to run (default: `glob_task`)
34+
- `WDL_UNIT_TEST_VERSION`: WDL version (default: `1.1`)
35+
36+
```bash
37+
WDL_UNIT_TEST_ID=serde_pair ./venv/bin/python -m pytest \
38+
src/toil/test/wdl/wdltoil_test.py::TestWDLConformance::test_single_unit_test \
39+
--timeout=300 -v -s
40+
```
41+
42+
This test clones remote git repos and may be slow. Many WDL spec tasks run inside containers, so **Docker must be running** — if the test fails with a Docker connection error, ask the user to start Docker before retrying.
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
version 1.0
2+
3+
# Test that Cromwell-style Pair inputs ({"Left": x, "Right": y}) are accepted.
4+
5+
workflow cromwell_pair {
6+
input {
7+
Pair[Int, Int] p
8+
Pair[String, Pair[Int, Int]] nested
9+
}
10+
output {
11+
Int left_out = p.left
12+
Int right_out = p.right
13+
String nested_left_out = nested.left
14+
Int nested_inner_left_out = nested.right.left
15+
Int nested_inner_right_out = nested.right.right
16+
}
17+
}

src/toil/test/wdl/wdltoil_test.py

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@
6767
"test_transpose", # miniwdl bug, see https://github.com/chanzuckerberg/miniwdl/issues/699
6868
"test_as_map_fail", # miniwdl bug, evalerror, see https://github.com/chanzuckerberg/miniwdl/issues/700
6969
"test_collect_by_key", # same as test_as_map_
70-
"serde_pair", # miniwdl and toil bug
7170
]
7271

7372
WDL_12_UNIT_TESTS_UNSUPPORTED_BY_TOIL = WDL_11_UNIT_TESTS_UNSUPPORTED_BY_TOIL + [
@@ -227,14 +226,23 @@ def test_unit_tests_v12(self, wdl_conformance_test_repo: Path) -> None:
227226

228227
@slow
229228
def test_single_unit_test(self, wdl_conformance_test_repo: Path) -> None:
229+
"""
230+
Run a single WDL spec unit test. Defaults to ``glob_task`` on WDL
231+
1.1, but both can be overridden via environment variables:
232+
233+
- ``WDL_UNIT_TEST_ID``: id of the test to run (e.g. ``serde_pair``)
234+
- ``WDL_UNIT_TEST_VERSION``: WDL version to use (e.g. ``1.2``)
235+
"""
236+
test_id = os.environ.get("WDL_UNIT_TEST_ID", "glob_task")
237+
wdl_version = os.environ.get("WDL_UNIT_TEST_VERSION", "1.1")
230238
os.chdir(wdl_conformance_test_repo)
231239
repo_url = "https://github.com/openwdl/wdl.git"
232-
repo_branch = "wdl-1.1"
240+
repo_branch = f"wdl-{wdl_version}"
233241
commands1 = [
234242
exactPython,
235243
"setup_unit_tests.py",
236244
"-v",
237-
"1.1",
245+
wdl_version,
238246
"--extra-patch-data",
239247
"unit_tests_patch_data.yaml",
240248
"--repo",
@@ -251,10 +259,10 @@ def test_single_unit_test(self, wdl_conformance_test_repo: Path) -> None:
251259
"-r",
252260
"toil-wdl-runner",
253261
"-v",
254-
"1.1",
262+
wdl_version,
255263
"--progress",
256264
"--id",
257-
",".join("glob_task"),
265+
test_id,
258266
]
259267
p2 = subprocess.run(commands2, capture_output=True)
260268
self.check(p2)
@@ -504,6 +512,33 @@ def test_string_file_coercion(self, tmp_path: Path) -> None:
504512

505513
assert "StringFileCoercion.output_file" in result
506514

515+
def test_cromwell_pair_input(self, tmp_path: Path) -> None:
516+
"""
517+
Test that Cromwell-style Pair inputs using capitalised Left/Right keys
518+
are accepted. Cromwell allows ``{"Left": x, "Right": y}`` in input JSON.
519+
"""
520+
with get_data("test/wdl/testfiles/cromwell_pair.wdl") as wdl:
521+
inputs = json.dumps(
522+
{
523+
"cromwell_pair.p": {"Left": 1, "Right": 2},
524+
"cromwell_pair.nested": {
525+
"Left": "hello",
526+
"Right": {"Left": 3, "Right": 4},
527+
},
528+
}
529+
)
530+
result_json = subprocess.check_output(
531+
self.base_command
532+
+ [str(wdl), inputs, "-o", str(tmp_path), "--retryCount=0"]
533+
)
534+
result = json.loads(result_json)
535+
536+
assert result["cromwell_pair.left_out"] == 1
537+
assert result["cromwell_pair.right_out"] == 2
538+
assert result["cromwell_pair.nested_left_out"] == "hello"
539+
assert result["cromwell_pair.nested_inner_left_out"] == 3
540+
assert result["cromwell_pair.nested_inner_right_out"] == 4
541+
507542
@needs_docker
508543
def test_gather(self, tmp_path: Path) -> None:
509544
"""

0 commit comments

Comments
 (0)