From d2f368e89cce24230ef16efb305e30d9d102ffa7 Mon Sep 17 00:00:00 2001 From: Jake Tronge Date: Thu, 23 May 2024 08:48:17 -0600 Subject: [PATCH] Check for missing inputs and set workflow defaults --- beeflow/common/parser/parser.py | 14 +++++++++----- beeflow/tests/cf.cwl | 4 +++- beeflow/tests/test_parser.py | 14 ++++++++++++-- ci/test_workflows/missing-input/input.yml | 1 + ci/test_workflows/missing-input/workflow.cwl | 20 ++++++++++++++++++++ 5 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 ci/test_workflows/missing-input/input.yml create mode 100644 ci/test_workflows/missing-input/workflow.cwl diff --git a/beeflow/common/parser/parser.py b/beeflow/common/parser/parser.py index 7a03cddd1..fcf9b8f85 100644 --- a/beeflow/common/parser/parser.py +++ b/beeflow/common/parser/parser.py @@ -97,12 +97,13 @@ def resolve_input(input_, type_): """ # Use parsed input parameter for input value if it exists input_id = _shortname(input_.id) - if input_id not in self.params: - return None - if not isinstance(self.params[input_id], type_map[type_]): + value = self.params[input_id] if input_id in self.params else input_.default + if value is None: + raise CwlParseError(f"input {input_id} is missing from workflow job file") + if not isinstance(value, type_map[type_]): raise CwlParseError("Input/param types do not match: " - f"{input_id}/{self.params[input_id]}") - return self.params[input_id] + f"{input_id}/{value}") + return value workflow_name = os.path.basename(cwl_path).split(".")[0] workflow_inputs = {InputParameter(_shortname(input_.id), input_.type, @@ -245,6 +246,9 @@ def parse_step_outputs(cwl_out, step_outputs, stdout, stderr): :type stderr: str or None :rtype: list of StepOutput """ + if not cwl_out: + return [] + out_short = list(map(_shortname, cwl_out)) short_id = out_short[0].split("/")[0] # Inline step outputs already have short_id+"/" prepended diff --git a/beeflow/tests/cf.cwl b/beeflow/tests/cf.cwl index 144bfb31b..aa8b34116 100644 --- a/beeflow/tests/cf.cwl +++ b/beeflow/tests/cf.cwl @@ -4,7 +4,9 @@ class: Workflow cwlVersion: v1.0 inputs: - infile: File + infile: + type: File + default: 'infile' outputs: clamr_dir: diff --git a/beeflow/tests/test_parser.py b/beeflow/tests/test_parser.py index ed41b58f1..0c9514e9e 100644 --- a/beeflow/tests/test_parser.py +++ b/beeflow/tests/test_parser.py @@ -3,7 +3,7 @@ from pathlib import Path import unittest -from beeflow.common.parser import CwlParser +from beeflow.common.parser import CwlParser, CwlParseError from beeflow.common.wf_data import (generate_workflow_id, Workflow, Task, Hint, StepInput, StepOutput, InputParameter, OutputParameter) @@ -76,6 +76,16 @@ def test_parse_workflow_no_job(self): for task in tasks: self.assertEqual(task.workflow_id, workflow_id) + def test_parse_workflow_missing_input(self): + """Test parsing a workflow with a missing input value in the input file.""" + cwl_wf_file = find('ci/test_workflows/missing-input/workflow.cwl') + cwl_job_yaml = find('ci/test_workflows/missing-input/input.yml') + + workflow_id = generate_workflow_id() + + with self.assertRaises(CwlParseError): + _, _ = self.parser.parse_workflow(workflow_id, cwl_wf_file, cwl_job_yaml) + WORKFLOW_GOLD_SCRIPT = Workflow( name='clamr_wf', @@ -247,7 +257,7 @@ def test_parse_workflow_no_job(self): name='cf', hints=[], requirements=[], - inputs={InputParameter(id='infile', type='File', value=None)}, + inputs={InputParameter(id='infile', type='File', value='infile')}, outputs={OutputParameter(id='ffmpeg_movie', type='File', value=None, source='ffmpeg/outfile'), OutputParameter(id='clamr_dir', type='File', value=None, source='clamr/outfile')}, workflow_id=generate_workflow_id()) diff --git a/ci/test_workflows/missing-input/input.yml b/ci/test_workflows/missing-input/input.yml new file mode 100644 index 000000000..3589fa97a --- /dev/null +++ b/ci/test_workflows/missing-input/input.yml @@ -0,0 +1 @@ +b: 232 diff --git a/ci/test_workflows/missing-input/workflow.cwl b/ci/test_workflows/missing-input/workflow.cwl new file mode 100644 index 000000000..e2f1868ad --- /dev/null +++ b/ci/test_workflows/missing-input/workflow.cwl @@ -0,0 +1,20 @@ +class: Workflow +cwlVersion: v1.2 + +inputs: + a: int +outputs: {} + +steps: + step0: + run: + class: CommandLineTool + baseCommand: echo + inputs: + a: + type: int + inputBinding: {} + outputs: [] + in: + a: a + out: []