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

Fix for #895 #898

Merged
merged 11 commits into from
Nov 9, 2017
49 changes: 49 additions & 0 deletions aiida/backends/tests/workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,55 @@ def test_wf_get_state(self):
# it is a valid state
self.assertIn(wf.get_state(), wf_states)

def test_failing_calc_in_wf(self):
"""
This test checks that a workflow (but also a workflow with
sub-workflows) that has an exception at one of its steps stops
properly and it is not left as RUNNING.
"""
import logging
from aiida.daemon.workflowmanager import execute_steps
from aiida.workflows.test import (FailingWFTestSimple,
FailingWFTestSimpleWithSubWF)

try:
# First of all, I re-enable logging in case it was disabled by
# mistake by a previous test (e.g. one that disables and reenables
# again, but that failed)
logging.disable(logging.NOTSET)
# Temporarily disable logging to the stream handler (i.e. screen)
# because otherwise fix_calc_states will print warnings
handler = next((h for h in logging.getLogger('aiida').handlers if
isinstance(h, logging.StreamHandler)), None)
if handler:
original_level = handler.level
handler.setLevel(logging.ERROR)

# Testing the error propagation of a simple workflow
wf = FailingWFTestSimple()
wf.store()
step_no = 0
wf.start()
while wf.is_running():
execute_steps()
step_no += 1
self.assertLess(step_no, 5, "This workflow should have stopped "
"since it is failing")

# Testing the error propagation of a workflow with subworkflows
wf = FailingWFTestSimpleWithSubWF()
wf.store()

step_no = 0
wf.start()
while wf.is_running():
execute_steps()
step_no += 1
self.assertLess(step_no, 5, "This workflow should have stopped "
"since it is failing")
finally:
if handler:
handler.setLevel(original_level)

def tearDown(self):
"""
Expand Down
1 change: 1 addition & 0 deletions aiida/orm/implementation/sqlalchemy/workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,7 @@ def wrapper(cls, *args, **kwargs):
wrapped_method))
cls.append_to_report("full traceback: {0}".format(traceback.format_exc()))
method_step.set_state(wf_states.ERROR)
cls.set_state(wf_states.ERROR)
return None

out = wrapper
Expand Down
48 changes: 48 additions & 0 deletions aiida/workflows/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,54 @@ def second_step(self):
self.next(self.exit)


class FailingWFTestSimple(WFTestSimple):
@Workflow.step
def start(self):
# Testing calculations
self.attach_calculation(self.generate_calc())

# Test process
self.next(self.second_step)

@Workflow.step
def second_step(self):
# Testing calculations
self.attach_calculation(generate_calc())
# Raise a test exception that should make the workflow to stop
raise Exception('Test exception')

# Test process
self.next(self.third_step)

@Workflow.step
def third_step(self):
self.next(self.exit)


class FailingWFTestSimpleWithSubWF(Workflow):
def __init__(self, **kwargs):
super(FailingWFTestSimpleWithSubWF, self).__init__(**kwargs)

@Workflow.step
def start(self):
self.attach_calculation(generate_calc())

# Create two subworkflows
w = FailingWFTestSimple()
w.start()
self.attach_workflow(w)

w = FailingWFTestSimple()
w.start()
self.attach_workflow(w)

self.next(self.second)

@Workflow.step
def second(self):
self.next(self.exit)


class WFTestSimpleWithSubWF(Workflow):
def __init__(self, **kwargs):
super(WFTestSimpleWithSubWF, self).__init__(**kwargs)
Expand Down