From 1aa3f745a8ca2d0b073258fd0bc2081b444df368 Mon Sep 17 00:00:00 2001 From: DriesSchaumont <5946712+DriesSchaumont@users.noreply.github.com> Date: Thu, 2 Jan 2025 08:55:58 +0000 Subject: [PATCH] Also apply to toState --- .../workflowFactory/processWorkflowArgs.nf | 4 +++ .../invalid_tostate_argument/config.vsh.yaml | 12 ++++++++ .../test_wfs/invalid_tostate_argument/main.nf | 28 +++++++++++++++++++ .../runners/nextflow/NextflowScriptTest.scala | 13 +++++++++ 4 files changed, 57 insertions(+) create mode 100644 src/test/resources/testnextflowvdsl3/src/test_wfs/invalid_tostate_argument/config.vsh.yaml create mode 100644 src/test/resources/testnextflowvdsl3/src/test_wfs/invalid_tostate_argument/main.nf diff --git a/src/main/resources/io/viash/runners/nextflow/workflowFactory/processWorkflowArgs.nf b/src/main/resources/io/viash/runners/nextflow/workflowFactory/processWorkflowArgs.nf index e23871b7e..ce3bf7af1 100644 --- a/src/main/resources/io/viash/runners/nextflow/workflowFactory/processWorkflowArgs.nf +++ b/src/main/resources/io/viash/runners/nextflow/workflowFactory/processWorkflowArgs.nf @@ -165,6 +165,7 @@ def _processToState(toState, key_, config_) { assert toState.values().every{it instanceof CharSequence} : "Error in module '$key_': toState is a Map, but not all values are Strings" assert toState.keySet().every{it instanceof CharSequence} : "Error in module '$key_': toState is a Map, but not all keys are Strings" def toStateMap = toState.clone() + def allArgumentNames = config_.allArguments.collect{it.plainName} def requiredOutputNames = config_.allArguments.findAll{it.required && it.direction == "Output"}.collect{it.plainName} // turn the map into a closure to be used later on toState = { it -> @@ -173,6 +174,9 @@ def _processToState(toState, key_, config_) { assert output instanceof Map : "Error in module '$key_': the output is not a Map" assert state instanceof Map : "Error in module '$key_': the state is not a Map" def extraEntries = toStateMap.collectMany{newkey, origkey -> + if (!allArgumentNames.contains(origkey)) { + throw new Exception("Error processing toState for '$key_': invalid argument '$origkey'") + } // check whether newkey corresponds to a required argument if (output.containsKey(origkey)) { [[newkey, output[origkey]]] diff --git a/src/test/resources/testnextflowvdsl3/src/test_wfs/invalid_tostate_argument/config.vsh.yaml b/src/test/resources/testnextflowvdsl3/src/test_wfs/invalid_tostate_argument/config.vsh.yaml new file mode 100644 index 000000000..788b6a3e8 --- /dev/null +++ b/src/test/resources/testnextflowvdsl3/src/test_wfs/invalid_tostate_argument/config.vsh.yaml @@ -0,0 +1,12 @@ +name: invalid_tostate_argument +namespace: test_wfs +resources: + - type: nextflow_script + path: main.nf + entrypoint: base + # TODO: make absolute when the ns build uses the right CWD + - path: ../../../resources +dependencies: + - name: sub_workflow +platforms: + - type: nextflow \ No newline at end of file diff --git a/src/test/resources/testnextflowvdsl3/src/test_wfs/invalid_tostate_argument/main.nf b/src/test/resources/testnextflowvdsl3/src/test_wfs/invalid_tostate_argument/main.nf new file mode 100644 index 000000000..cab143d85 --- /dev/null +++ b/src/test/resources/testnextflowvdsl3/src/test_wfs/invalid_tostate_argument/main.nf @@ -0,0 +1,28 @@ +workflow base { + take: input_ch + main: + + // generate list from 0 to 1000 + ch = Channel.fromList(0..1000) + | map { num -> + // create temporary file + def file = tempFile() + file.write("num: $num") + + ["num$num", [ file: file ], ["num": num]] + } + | sub_workflow.run( + fromState: [ + "file": "file", + ], + toState: [ + "step1_output": "output", + "file": "file", + "newkey": "thisargumentdoesnotexist" // This should raise + ] + ) + + + emit: + input_ch +} diff --git a/src/test/scala/io/viash/runners/nextflow/NextflowScriptTest.scala b/src/test/scala/io/viash/runners/nextflow/NextflowScriptTest.scala index f49394601..1d057c8b9 100644 --- a/src/test/scala/io/viash/runners/nextflow/NextflowScriptTest.scala +++ b/src/test/scala/io/viash/runners/nextflow/NextflowScriptTest.scala @@ -214,6 +214,19 @@ class NextflowScriptTest extends AnyFunSuite with BeforeAndAfterAll { assert(stdOut.contains("Error processing fromState for 'sub_workflow': invalid argument 'thisargumentdoesnotexist'")) } + test("Test invalid argument in toState map", DockerTest, NextflowTest) { + val (exitCode, stdOut, stdErr) = NextflowTestHelper.run( + mainScript = "target/nextflow/test_wfs/invalid_tostate_argument/main.nf", + args = List( + "--publish_dir", "output" + ), + cwd = tempFolFile + ) + + assert(exitCode == 1, s"\nexit code was $exitCode\nStd output:\n$stdOut\nStd error:\n$stdErr") + assert(stdOut.contains("Error processing toState for 'sub_workflow': invalid argument 'thisargumentdoesnotexist'")) + } + test("Run multiple output channels standalone", NextflowTest) { val (exitCode, stdOut, stdErr) = NextflowTestHelper.run(