Skip to content
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

Rerun errored #483

Merged
merged 8 commits into from
Jun 24, 2021
Merged
Show file tree
Hide file tree
Changes from 7 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
4 changes: 2 additions & 2 deletions pydra/engine/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ def _run(self, rerun=False, **kwargs):
with SoftFileLock(lockfile):
if not (rerun or self.task_rerun):
result = self.result()
if result is not None:
if result is not None and not result.errored:
return result
# adding info file with the checksum in case the task was cancelled
# and the lockfile has to be removed
Expand Down Expand Up @@ -1017,7 +1017,7 @@ async def _run(self, submitter=None, rerun=False, **kwargs):
# retrieve cached results
if not (rerun or self.task_rerun):
result = self.result()
if result is not None:
if result is not None and not result.errored:
return result
# adding info file with the checksum in case the task was cancelled
# and the lockfile has to be removed
Expand Down
39 changes: 39 additions & 0 deletions pydra/engine/tests/test_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -1361,3 +1361,42 @@ def fun_error(x):
# the error traceback should be a list and should point to a specific line in the function
assert isinstance(error_tb, list)
assert "in fun_error" in error_tb[-2]


def test_rerun_errored(tmpdir, capfd):
"""Test rerunning a task containing errors.
Only the errored tasks should be rerun"""

@mark.task
def pass_odds(x):
if x % 2 == 0:
print(f"x%2 = {x % 2} (error)\n")
raise Exception("even error")
else:
print(f"x%2 = {x % 2}\n")
return x

task = pass_odds(name="pass_odds", x=[1, 2, 3, 4, 5], cache_dir=tmpdir).split("x")

with pytest.raises(Exception, match="even error") as exinfo:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
with pytest.raises(Exception, match="even error") as exinfo:
with pytest.raises(Exception, match="even error"):

task()
with pytest.raises(Exception, match="even error") as exinfo:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
with pytest.raises(Exception, match="even error") as exinfo:
with pytest.raises(Exception, match="even error"):

task()

out, err = capfd.readouterr()
stdout_lines = out.splitlines()

tasks_run = 0
errors_found = 0

for line in stdout_lines:
if "x%2" in line:
tasks_run += 1
if "(error)" in line:
errors_found += 1

# There should have been 5 messages of the form "x%2 = XXX" after calling task() the second time
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# There should have been 5 messages of the form "x%2 = XXX" after calling task() the second time
# There should have been 5 messages of the form "x%2 = XXX" after calling task() the first time

# There should have been 2 messages of the form "x%2 = XXX" after calling task() the second time
assert tasks_run == 7

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# There should have been 2 messages with "error" after calling task() the first time
# and 2 another messages after calling the second time

assert errors_found == 4
42 changes: 42 additions & 0 deletions pydra/engine/tests/test_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import time
import attr
from pathlib import Path
import logging

from .utils import (
add2,
Expand Down Expand Up @@ -4687,3 +4688,44 @@ def one_arg_inner(start_number):

res = test_outer.result()
assert res[0].output.res2 == 23 and res[1].output.res2 == 23


def test_rerun_errored(tmpdir, capfd):
"""Test rerunning a workflow containing errors.
Only the errored tasks and workflow should be rerun"""

@mark.task
def pass_odds(x):
if x % 2 == 0:
print(f"x%2 = {x % 2} (error)\n")
raise Exception("even error")
else:
print(f"x%2 = {x % 2}\n")
return x

wf = Workflow(name="wf", input_spec=["x"], cache_dir=tmpdir)
wf.add(pass_odds(name="pass_odds", x=[1, 2, 3, 4, 5]).split("x"))
wf.set_output([("out", wf.pass_odds.lzout.out)])

with pytest.raises(Exception) as exinfo:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
with pytest.raises(Exception) as exinfo:
with pytest.raises(Exception):

wf()
with pytest.raises(Exception) as exinfo:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
with pytest.raises(Exception) as exinfo:
with pytest.raises(Exception):

wf()

out, err = capfd.readouterr()
stdout_lines = out.splitlines()

tasks_run = 0
errors_found = 0

for line in stdout_lines:
if "x%2" in line:
tasks_run += 1
if "(error)" in line:
errors_found += 1

# There should have been 5 messages of the form "x%2 = XXX" after calling task() the second time
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# There should have been 5 messages of the form "x%2 = XXX" after calling task() the second time
# There should have been 5 messages of the form "x%2 = XXX" after calling task() the first time

# There should have been 2 messages of the form "x%2 = XXX" after calling task() the second time
assert tasks_run == 7

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
# There should have been 2 messages with "error" after calling task() the first time
# and 2 another messages after calling the second time

assert errors_found == 4