Skip to content

Commit

Permalink
Fix issue when retrying with stub (#5359)
Browse files Browse the repository at this point in the history

Signed-off-by: jorgee <[email protected]>
Signed-off-by: Paolo Di Tommaso <[email protected]>
Co-authored-by: Paolo Di Tommaso <[email protected]>
  • Loading branch information
jorgee and pditommaso authored Oct 11, 2024
1 parent fb1c8b2 commit 324b611
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ class TaskConfig extends LazyMap implements Cloneable {
return eval0(this, path.tokenize('.'), path)
}

private Object eval0(Object object, List<String> path, String key ) {
private Object eval0(Object object, List<String> path, String key) {
assert path, "Missing task attribute name"
def result = null
if( object instanceof LazyMap ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ import nextflow.script.BodyDef
import nextflow.script.ProcessConfig
import nextflow.script.ScriptMeta
import nextflow.script.ScriptType
import nextflow.script.TaskClosure
import nextflow.script.bundle.ResourcesBundle
import nextflow.script.params.BaseOutParam
import nextflow.script.params.CmdEvalParam
Expand Down Expand Up @@ -642,14 +641,8 @@ class TaskProcessor {
if( !checkWhenGuard(task) )
return

TaskClosure block
if( session.stubRun && (block=task.config.getStubBlock()) ) {
task.resolve(block)
}
else {
// -- resolve the task command script
task.resolve(taskBody)
}
// -- resolve the task command script
task.resolve(taskBody)

// -- verify if exists a stored result for this case,
// if true skip the execution and return the stored data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import java.util.function.Function

import com.google.common.hash.HashCode
import groovy.transform.Memoized
import groovy.transform.PackageScope
import groovy.util.logging.Slf4j
import nextflow.Session
import nextflow.conda.CondaCache
Expand Down Expand Up @@ -787,7 +786,13 @@ class TaskRun implements Cloneable {
*
* @param body A {@code BodyDef} object instance
*/
@PackageScope void resolve(BodyDef body) {
void resolve(BodyDef body) {
processor.session.stubRun
? resolveStub(config.getStubBlock())
: resolveBody(body)
}

protected void resolveBody(BodyDef body) {

// -- initialize the task code to be executed
this.code = body.closure.clone() as Closure
Expand Down Expand Up @@ -829,7 +834,7 @@ class TaskRun implements Cloneable {
throw new ProcessUnrecoverableException("Process `${getName()}` script is empty")
}

@PackageScope void resolve(TaskClosure block) {
protected void resolveStub(TaskClosure block) {
this.code = block.clone() as Closure
this.code.delegate = this.context
this.code.setResolveStrategy(Closure.DELEGATE_ONLY)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,6 @@ class TaskRunTest extends Specification {
}

def 'should resolve the task body script' () {

given:
def task = new TaskRun()
task.processor = [:] as TaskProcessor
Expand All @@ -412,7 +411,7 @@ class TaskRunTest extends Specification {
* plain task script
*/
when:
task.resolve(new BodyDef({-> 'Hello'}, 'Hello', 'script'))
task.resolveBody(new BodyDef({-> 'Hello'}, 'Hello', 'script'))
then:
task.script == 'Hello'
task.source == 'Hello'
Expand All @@ -422,7 +421,7 @@ class TaskRunTest extends Specification {
*/
when:
task.context = new TaskContext(Mock(Script),[x: 'world'],'foo')
task.resolve(new BodyDef({-> "Hello ${x}"}, 'Hello ${x}', 'script'))
task.resolveBody(new BodyDef({-> "Hello ${x}"}, 'Hello ${x}', 'script'))
then:
task.script == 'Hello world'
task.source == 'Hello ${x}'
Expand All @@ -448,7 +447,7 @@ class TaskRunTest extends Specification {
*/
when:
task.context = new TaskContext(Mock(Script),VARS,'foo')
task.resolve(new BodyDef(body, 'cat ${one}\nhead ${many}', 'script'))
task.resolveBody(new BodyDef(body, 'cat ${one}\nhead ${many}', 'script'))
then:
task.script == '''
cat a\\ b.txt
Expand Down Expand Up @@ -481,7 +480,7 @@ class TaskRunTest extends Specification {
when:
task.context = new TaskContext(script,local,'foo')
task.config = new TaskConfig().setContext(task.context)
task.resolve(new BodyDef({-> '$BASH_VAR !{nxf_var} - !{params.var_no}'}, '<the source script>', 'shell')) // <-- note: 'shell' type
task.resolveBody(new BodyDef({-> '$BASH_VAR !{nxf_var} - !{params.var_no}'}, '<the source script>', 'shell')) // <-- note: 'shell' type
then:
task.script == '$BASH_VAR YES - NO'
task.source == '<the source script>'
Expand All @@ -493,7 +492,7 @@ class TaskRunTest extends Specification {
task.context = new TaskContext(Mock(Script),[nxf_var: '>interpolated value<'],'foo')
task.config = new TaskConfig().setContext(task.context)
task.config.placeholder = '#' as char
task.resolve(new BodyDef({-> '$BASH_VAR #{nxf_var}'}, '$BASH_VAR #{nxf_var}', 'shell')) // <-- note: 'shell' type
task.resolveBody(new BodyDef({-> '$BASH_VAR #{nxf_var}'}, '$BASH_VAR #{nxf_var}', 'shell')) // <-- note: 'shell' type
then:
task.script == '$BASH_VAR >interpolated value<'
task.source == '$BASH_VAR #{nxf_var}'
Expand All @@ -517,7 +516,7 @@ class TaskRunTest extends Specification {
task.config = new TaskConfig().setContext(task.context)

when:
task.resolve( new BodyDef({-> template(my_file)}, 'template($file)', 'script'))
task.resolveBody( new BodyDef({-> template(my_file)}, 'template($file)', 'script'))
then:
task.script == 'echo Ciao mondo'
task.source == 'echo ${say_hello}'
Expand All @@ -542,7 +541,7 @@ class TaskRunTest extends Specification {
task.config = new TaskConfig().setContext(task.context)

when:
task.resolve( new BodyDef({-> template(my_file)}, 'template($file)', 'shell'))
task.resolveBody( new BodyDef({-> template(my_file)}, 'template($file)', 'shell'))
then:
task.script == 'echo $HOME ~ Foo bar'
task.source == 'echo $HOME ~ !{user_name}'
Expand All @@ -568,7 +567,7 @@ class TaskRunTest extends Specification {
task.config.placeholder = '#' as char

when:
task.resolve( new BodyDef({-> template(my_file)}, 'template($file)', 'shell'))
task.resolveBody( new BodyDef({-> template(my_file)}, 'template($file)', 'shell'))
then:
task.script == 'echo $HOME ~ Foo bar'
task.source == 'echo $HOME ~ #{user_name}'
Expand Down Expand Up @@ -750,7 +749,7 @@ class TaskRunTest extends Specification {
task.context = GroovyMock(TaskContext)

when:
task.resolve(new BodyDef({-> "Hello ${x}"}, 'Hello ${x}', 'script'))
task.resolveBody(new BodyDef({-> "Hello ${x}"}, 'Hello ${x}', 'script'))
and:
def vars = task.getVariableNames()
then:
Expand All @@ -769,7 +768,7 @@ class TaskRunTest extends Specification {
task.config = new TaskConfig()

when:
task.resolve(new BodyDef({-> 'Hello !{foo} !{bar} !{input_x}'}, 'Hello..', 'shell'))
task.resolveBody(new BodyDef({-> 'Hello !{foo} !{bar} !{input_x}'}, 'Hello..', 'shell'))
and:
def vars = task.getVariableNames()
then:
Expand All @@ -793,7 +792,7 @@ class TaskRunTest extends Specification {
task.config = new TaskConfig()

when:
task.resolve(new BodyDef({-> template }, 'Hello..', 'script'))
task.resolveBody(new BodyDef({-> template }, 'Hello..', 'script'))
and:
def vars = task.getVariableNames()
then:
Expand Down Expand Up @@ -822,7 +821,7 @@ class TaskRunTest extends Specification {
* plain task script
*/
when:
task.resolve(dryRun)
task.resolveStub(dryRun)
then:
task.script == 'echo Hello world'
task.source == 'command source'
Expand Down Expand Up @@ -891,4 +890,38 @@ class TaskRunTest extends Specification {
expect:
!task.isArray()
}

def 'should resolve task body' () {
given:
def task = Spy(TaskRun)
task.processor = Mock(TaskProcessor) {
getSession()>>Mock(Session) { getStubRun() >> false}
}
and:
def body = Mock(BodyDef)

when:
task.resolve(body)
then:
1 * task.resolveBody(body) >> null
0 * task.resolveStub(_) >> null
}

def 'should resolve task stub' () {
given:
def body = Mock(BodyDef)
def stub = Mock(TaskClosure)
and:
def task = Spy(TaskRun)
task.config = Mock(TaskConfig) { getStubBlock()>>stub }
task.processor = Mock(TaskProcessor) {
getSession()>>Mock(Session) { getStubRun() >> true}
}

when:
task.resolve(body)
then:
1 * task.resolveStub(stub) >> null
0 * task.resolveBody(_) >> null
}
}
11 changes: 11 additions & 0 deletions tests/checks/stub-retry.nf/.checks
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
set -e

echo ''
$NXF_RUN -stub | tee stdout

[[ `grep 'INFO' .nextflow.log | grep -c 'Submitted process > stubtest'` == 1 ]] || false
[[ `grep 'INFO' .nextflow.log | grep -c 'Re-submitted process > stubtest'` == 1 ]] || false

[[ `grep -c 'Stubbing. Creating file' stdout` == 1 ]] || false


30 changes: 30 additions & 0 deletions tests/stub-retry.nf
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
process stubtest {
debug true
errorStrategy 'retry'

output:
path("*.txt")

script:
"""
echo "Not stubbing"
touch script.txt
"""

stub:
if( task.attempt < 2 ) {
"""
echo "Stubbing. Not creating file"
"""
} else {
"""
echo "Stubbing. Creating file"
touch script.txt
"""
}
}

workflow {
main:
stubtest()
}

0 comments on commit 324b611

Please sign in to comment.