Skip to content

Commit 83b99b4

Browse files
committed
extend validation to the inputs of the top level proces
1 parent cf3e49f commit 83b99b4

File tree

5 files changed

+63
-2
lines changed

5 files changed

+63
-2
lines changed

cwltool/context.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import copy
33
import os
44
import shutil
5+
import sys
56
import tempfile
67
import threading
78
from typing import (
@@ -197,6 +198,8 @@ def __init__(self, kwargs: Optional[Dict[str, Any]] = None) -> None:
197198
self.mpi_config: MpiConfig = MpiConfig()
198199
self.default_stdout: Optional[Union[IO[bytes], TextIO]] = None
199200
self.default_stderr: Optional[Union[IO[bytes], TextIO]] = None
201+
self.validate_only: bool = False
202+
self.validate_stdout: Union[IO[bytes], TextIO, IO[str]] = sys.stdout
200203
super().__init__(kwargs)
201204
if self.tmp_outdir_prefix == "":
202205
self.tmp_outdir_prefix = self.tmpdir_prefix

cwltool/executors.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,8 @@ def check_for_abstract_op(tool: CWLObjectType) -> None:
143143
process.requirements.append(req)
144144

145145
self.run_jobs(process, job_order_object, logger, runtime_context)
146+
if runtime_context.validate_only is True:
147+
return (None, "ValidationSuccess")
146148

147149
if self.final_output and self.final_output[0] is not None and finaloutdir is not None:
148150
self.final_output[0] = relocateOutputs(
@@ -238,6 +240,16 @@ def run_jobs(
238240
process_run_id = prov_obj.record_process_start(process, job)
239241
runtime_context = runtime_context.copy()
240242
runtime_context.process_run_id = process_run_id
243+
if runtime_context.validate_only is True:
244+
if isinstance(job, WorkflowJob):
245+
name = job.tool.lc.filename
246+
else:
247+
name = getattr(job, "name", str(job))
248+
print(
249+
f"{name} is valid CWL. No errors detected in the inputs.",
250+
file=runtime_context.validate_stdout,
251+
)
252+
return
241253
job.run(runtime_context)
242254
else:
243255
logger.error("Workflow cannot make any more progress.")

cwltool/main.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1134,7 +1134,7 @@ def main(
11341134
make_template(tool, stdout)
11351135
return 0
11361136

1137-
if args.validate:
1137+
if len(args.job_order) == 0 and args.validate:
11381138
print(f"{args.workflow} is valid CWL.", file=stdout)
11391139
return 0
11401140

@@ -1294,10 +1294,14 @@ def main(
12941294
use_biocontainers=args.beta_use_biocontainers,
12951295
container_image_cache_path=args.beta_dependencies_directory,
12961296
)
1297+
runtimeContext.validate_only = args.validate
1298+
runtimeContext.validate_stdout = stdout
12971299

12981300
(out, status) = real_executor(
12991301
tool, initialized_job_order_object, runtimeContext, logger=_logger
13001302
)
1303+
if runtimeContext.validate_only is True:
1304+
return 0
13011305

13021306
if out is not None:
13031307
if runtimeContext.research_obj is not None:

tests/test_validate.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""Tests --validation."""
2-
2+
import re
33

44
from .util import get_data, get_main_output
55

@@ -14,3 +14,41 @@ def test_validate_graph_with_no_default() -> None:
1414
assert "packed_no_main.cwl#cat is valid CWL" in stdout
1515
assert "packed_no_main.cwl#collision is valid CWL" in stdout
1616
assert "tests/wf/packed_no_main.cwl is valid CWL" in stdout
17+
18+
19+
def test_validate_with_valid_input_object() -> None:
20+
"""Ensure that --validate with a valid input object."""
21+
exit_code, stdout, stderr = get_main_output(
22+
[
23+
"--validate",
24+
get_data("tests/wf/1st-workflow.cwl"),
25+
"--inp",
26+
get_data("tests/wf/1st-workflow.cwl"),
27+
"--ex",
28+
"FOO",
29+
]
30+
)
31+
assert exit_code == 0
32+
assert "tests/wf/1st-workflow.cwl is valid CWL. No errors detected in the inputs." in stdout
33+
34+
35+
def test_validate_with_invalid_input_object() -> None:
36+
"""Ensure that --validate with an invalid input object."""
37+
exit_code, stdout, stderr = get_main_output(
38+
[
39+
"--validate",
40+
get_data("tests/wf/1st-workflow.cwl"),
41+
get_data("tests/wf/1st-workflow_bad_inputs.yml"),
42+
]
43+
)
44+
assert exit_code == 1
45+
stderr = re.sub(r"\s\s+", " ", stderr)
46+
assert "Invalid job input record" in stderr
47+
assert (
48+
"tests/wf/1st-workflow_bad_inputs.yml:2:1: * the 'ex' field is not "
49+
"valid because the value is not string" in stderr
50+
)
51+
assert (
52+
"tests/wf/1st-workflow_bad_inputs.yml:1:1: * the 'inp' field is not "
53+
"valid because is not a dict. Expected a File object." in stderr
54+
)

tests/wf/1st-workflow_bad_inputs.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
inp: 42
2+
ex:
3+
class: File
4+
path: 1st-workflow.cwl

0 commit comments

Comments
 (0)