96 lines
3.7 KiB
Python
96 lines
3.7 KiB
Python
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow
|
|
from SpiffWorkflow.task import TaskState
|
|
from .BpmnWorkflowTestCase import BpmnWorkflowTestCase
|
|
|
|
|
|
class ResetTokenOnBoundaryEventTest(BpmnWorkflowTestCase):
|
|
"""Assure that when we reset a token to a previous task, and that
|
|
task has a boundary event, that the boundary event is reset to the
|
|
correct state."""
|
|
|
|
def setUp(self):
|
|
spec, subprocesses = self.load_workflow_spec('reset_with_boundary_event.bpmn', 'token')
|
|
self.workflow = BpmnWorkflow(spec, subprocesses)
|
|
|
|
def testResetToOuterWorkflow(self):
|
|
self.reset_to_outer_workflow(save_restore=False)
|
|
|
|
def testResetToSubprocess(self):
|
|
self.reset_to_subprocess(save_restore=False)
|
|
|
|
def testSaveRestore(self):
|
|
self.reset_to_outer_workflow(save_restore=True)
|
|
|
|
def reset_to_outer_workflow(self, save_restore=False):
|
|
|
|
# Advance insie the subworkflow
|
|
self.advance_to_task('Last')
|
|
sub = self.workflow.get_tasks_from_spec_name('subprocess')[0]
|
|
timer_event = self.workflow.get_tasks_from_spec_name('Event_My_Timer')[0]
|
|
self.assertEqual(TaskState.CANCELLED, timer_event.state)
|
|
|
|
if save_restore:
|
|
self.save_restore()
|
|
|
|
# Here we reset back to the first task
|
|
first = self.workflow.get_tasks_from_spec_name('First')[0]
|
|
self.workflow.reset_from_task_id(first.id)
|
|
|
|
if save_restore:
|
|
self.save_restore()
|
|
|
|
# At which point, the timer event should return to a waiting state, the subprocess shoud have been removed
|
|
task = self.workflow.get_tasks_from_spec_name('First')[0]
|
|
self.assertEqual(task.state, TaskState.READY)
|
|
timer_event = self.workflow.get_tasks_from_spec_name('Event_My_Timer')[0]
|
|
self.assertEqual(timer_event.state, TaskState.WAITING)
|
|
self.assertNotIn(sub.id, self.workflow.subprocesses)
|
|
|
|
# Ensure the workflow can be completed without being stuck on stranded tasks
|
|
self.complete_workflow()
|
|
self.assertTrue(self.workflow.is_completed())
|
|
|
|
def reset_to_subprocess(self, save_restore=False):
|
|
|
|
# Advance past the subworkflow
|
|
self.advance_to_task('Final')
|
|
if save_restore:
|
|
self.save_restore()
|
|
|
|
# Reset to a task inside the subworkflow
|
|
task = self.workflow.get_tasks_from_spec_name('Last')[0]
|
|
self.workflow.reset_from_task_id(task.id)
|
|
|
|
if save_restore:
|
|
self.save_restore()
|
|
|
|
# The task we returned to should be ready, the subprocess should be waiting, the final task should be future
|
|
sub = self.workflow.get_tasks_from_spec_name('subprocess')[0]
|
|
self.assertEqual(sub.state, TaskState.WAITING)
|
|
self.assertEqual(task.state, TaskState.READY)
|
|
final = self.workflow.get_tasks_from_spec_name('Final')[0]
|
|
self.assertEqual(final.state, TaskState.FUTURE)
|
|
|
|
# Ensure the workflow can be completed without being stuck on stranded tasks
|
|
self.complete_workflow()
|
|
self.assertTrue(self.workflow.is_completed())
|
|
|
|
def advance_to_task(self, name):
|
|
|
|
self.workflow.do_engine_steps()
|
|
ready_tasks = self.workflow.get_tasks(TaskState.READY)
|
|
while ready_tasks[0].task_spec.name != name:
|
|
ready_tasks[0].run()
|
|
self.workflow.do_engine_steps()
|
|
self.workflow.refresh_waiting_tasks()
|
|
ready_tasks = self.workflow.get_tasks(TaskState.READY)
|
|
|
|
def complete_workflow(self):
|
|
|
|
ready_tasks = self.workflow.get_tasks(TaskState.READY)
|
|
while len(ready_tasks) > 0:
|
|
ready_tasks[0].run()
|
|
self.workflow.do_engine_steps()
|
|
self.workflow.refresh_waiting_tasks()
|
|
ready_tasks = self.workflow.get_tasks(TaskState.READY)
|