Skip to content

Fix false error in workflow output #5982

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 23, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@ class OutputDsl {

// make sure every output was assigned
for( final name : declarations.keySet() ) {
if( name !in outputs )
if( !outputs.containsKey(name) )
throw new ScriptRuntimeException("Workflow output '${name}' was declared in the output block but not assigned in the workflow")
}

for( final name : outputs.keySet() ) {
if( name !in declarations )
if( !declarations.containsKey(name) )
throw new ScriptRuntimeException("Workflow output '${name}' was assigned in the workflow but not declared in the output block")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,22 @@ import spock.lang.Specification
*/
class OutputDslTest extends Specification {

void assignOutput(Session session, String name, List values) {
def ch = new DataflowQueue()
values.each { v -> ch.bind(v) }
ch.bind(Channel.STOP)
session.outputs.put(name, ch)
}

void await(OutputDsl dsl) {
def now = System.currentTimeMillis()
while( !dsl.complete ) {
sleep 100
if( System.currentTimeMillis() - now > 5_000 )
throw new TimeoutException()
}
}

def 'should publish workflow outputs'() {
given:
def root = Files.createTempDirectory('test')
Expand All @@ -40,16 +56,9 @@ class OutputDslTest extends Specification {
}
Global.session = session
and:
def ch1 = new DataflowQueue()
ch1.bind(file1)
ch1.bind(Channel.STOP)
assignOutput(session, 'foo', [file1])
assignOutput(session, 'bar', [file2])
and:
def ch2 = new DataflowQueue()
ch2.bind(file2)
ch2.bind(Channel.STOP)
and:
session.outputs.put('foo', ch1)
session.outputs.put('bar', ch2)
def dsl = new OutputDsl()
and:
SysEnv.push(NXF_FILE_ROOT: root.toString())
Expand All @@ -65,14 +74,7 @@ class OutputDslTest extends Specification {
}
}
dsl.apply(session)

def now = System.currentTimeMillis()
while( !dsl.complete ) {
sleep 100
if( System.currentTimeMillis() - now > 5_000 )
throw new TimeoutException()
}

await(dsl)
then:
outputDir.resolve('foo/file1.txt').text == 'Hello'
outputDir.resolve('barbar/file2.txt').text == 'world'
Expand All @@ -89,6 +91,43 @@ class OutputDslTest extends Specification {
root?.deleteDir()
}

def 'should accept empty output declaration'() {
given:
def root = Files.createTempDirectory('test')
def outputDir = root.resolve('results')
def workDir = root.resolve('work')
def work1 = workDir.resolve('ab/1234'); Files.createDirectories(work1)
def file1 = work1.resolve('file1.txt'); file1.text = 'Hello'
and:
def session = Mock(Session) {
getOutputs() >> [:]
getConfig() >> [:]
getOutputDir() >> outputDir
getWorkDir() >> workDir
}
Global.session = session
and:
assignOutput(session, 'foo', [file1])
and:
def dsl = new OutputDsl()
and:
SysEnv.push(NXF_FILE_ROOT: root.toString())

when:
dsl.declare('foo') {
}
dsl.apply(session)
await(dsl)
then:
outputDir.resolve('file1.txt').text == 'Hello'
and:
1 * session.notifyFilePublish(outputDir.resolve('file1.txt'), file1)

cleanup:
SysEnv.pop()
root?.deleteDir()
}

def 'should set publish options in output declaration' () {
when:
def dsl1 = new OutputDsl.DeclareDsl()
Expand Down
Loading