def run_master_spec(spec_model, study): """Executes a BPMN specification for the given study, without recording any information to the database Useful for running the master specification, which should not persist. """ lasttime = firsttime() spec_files = SpecFileService().get_spec_files(spec_model.id, include_libraries=True) lasttime = sincetime('load Files', lasttime) spec = WorkflowProcessor.get_spec(spec_files, spec_model.id) lasttime = sincetime('get spec', lasttime) try: bpmn_workflow = BpmnWorkflow( spec, script_engine=WorkflowProcessor._script_engine) bpmn_workflow.data[WorkflowProcessor.STUDY_ID_KEY] = study.id bpmn_workflow.data[ WorkflowProcessor.VALIDATION_PROCESS_KEY] = False lasttime = sincetime('get_workflow', lasttime) bpmn_workflow.do_engine_steps() lasttime = sincetime('run steps', lasttime) except WorkflowException as we: raise ApiError.from_task_spec("error_running_master_spec", str(we), we.sender) if not bpmn_workflow.is_completed(): raise ApiError( "master_spec_not_automatic", "The master spec should only contain fully automated tasks, it failed to complete." ) return bpmn_workflow.last_task.data
class TimerIntermediateTest(BpmnWorkflowTestCase): def setUp(self): self.spec = self.load_spec() def load_spec(self): return self.load_workflow_spec('Test-Workflows/*.bpmn20.xml', 'Timer Intermediate') def testRunThroughHappy(self): self.workflow = BpmnWorkflow(self.spec) due_time = datetime.datetime.now() + datetime.timedelta(seconds=0.5) self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.workflow.get_tasks(Task.READY)[0].set_data(due_time=due_time) self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) time.sleep(0.6) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.refresh_waiting_tasks() self.assertEqual(0, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
def hard_reset(self): """Recreate this workflow. This will be useful when a workflow specification changes. """ self.spec_data_files = FileService.get_spec_data_files( workflow_spec_id=self.workflow_spec_id) new_spec = WorkflowProcessor.get_spec(self.spec_data_files, self.workflow_spec_id) new_bpmn_workflow = BpmnWorkflow(new_spec, script_engine=self._script_engine) new_bpmn_workflow.data = self.bpmn_workflow.data try: new_bpmn_workflow.do_engine_steps() except WorkflowException as we: raise ApiError.from_task_spec("hard_reset_engine_steps_error", str(we), we.sender) self.bpmn_workflow = new_bpmn_workflow
def __get_bpmn_workflow(self, workflow_model: WorkflowModel, spec: WorkflowSpec, validate_only=False): if workflow_model.bpmn_workflow_json: bpmn_workflow = self._serializer.deserialize_workflow( workflow_model.bpmn_workflow_json, workflow_spec=spec) else: bpmn_workflow = BpmnWorkflow(spec, script_engine=self._script_engine) bpmn_workflow.data[ WorkflowProcessor.STUDY_ID_KEY] = workflow_model.study_id bpmn_workflow.data[ WorkflowProcessor.VALIDATION_PROCESS_KEY] = validate_only try: bpmn_workflow.do_engine_steps() except WorkflowException as we: raise ApiError.from_task_spec("error_loading_workflow", str(we), we.sender) return bpmn_workflow
class AbstractParallelTest(BpmnWorkflowTestCase): def _do_test(self, order, only_one_instance=True, save_restore=False): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() for s in order: choice = None if isinstance(s, tuple): s, choice = s if s.startswith('!'): logging.info("Checking that we cannot do '%s'", s[1:]) self.assertRaises( AssertionError, self.do_next_named_step, s[1:], choice=choice) else: if choice is not None: logging.info( "Doing step '%s' (with choice='%s')", s, choice) else: logging.info("Doing step '%s'", s) # logging.debug(self.workflow.get_dump()) self.do_next_named_step( s, choice=choice, only_one_instance=only_one_instance) self.workflow.do_engine_steps() if save_restore: # logging.debug("Before SaveRestore: \n%s" % # self.workflow.get_dump()) self.save_restore() self.workflow.do_engine_steps() unfinished = self.workflow.get_tasks(Task.READY | Task.WAITING) if unfinished: logging.debug("Unfinished tasks: %s", unfinished) logging.debug(self.workflow.get_dump()) self.assertEqual(0, len(unfinished))
def main(): print("Loading BPMN Specification.") spec = bpmn_diagram_to_spec('app/static/bpmn/random_fact') print("Creating a new workflow based on the specification.") script_engine = CustomBpmnScriptEngine() workflow = BpmnWorkflow(spec, script_engine=script_engine) workflow.debug = False print("Running automated tasks.") workflow.do_engine_steps() while not workflow.is_completed(): workflow.do_engine_steps() ready_tasks = workflow.get_ready_user_tasks() while len(ready_tasks) > 0: for task in ready_tasks: if isinstance(task.task_spec, UserTask): show_form(task) workflow.complete_next() else: raise ("Unown Ready Task.") workflow.do_engine_steps() ready_tasks = workflow.get_ready_user_tasks() print("All tasks in the workflow are now complete.") print("The following data was collected:") pprint.pprint(workflow.last_task.data)
class MessagesTest(BpmnWorkflowTestCase): def setUp(self): self.spec = self.load_spec() def load_spec(self): return self.load_workflow_spec('Test-Workflows/*.bpmn20.xml', 'Test Workflows') def testRunThroughHappy(self): self.workflow = BpmnWorkflow(self.spec) self.do_next_exclusive_step('Select Test', choice='Messages') self.workflow.do_engine_steps() self.assertEqual([], self.workflow.get_tasks(Task.READY)) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.accept_message('Wrong Message') self.assertEqual([], self.workflow.get_tasks(Task.READY)) self.workflow.accept_message('Test Message') self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual( 'Test Message', self.workflow.get_tasks(Task.READY)[0].task_spec.description) self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughSaveAndRestore(self): self.workflow = BpmnWorkflow(self.spec) self.do_next_exclusive_step('Select Test', choice='Messages') self.workflow.do_engine_steps() self.save_restore() self.assertEqual([], self.workflow.get_tasks(Task.READY)) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.accept_message('Wrong Message') self.assertEqual([], self.workflow.get_tasks(Task.READY)) self.workflow.accept_message('Test Message') self.save_restore() self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
class AbstractParallelTest(BpmnWorkflowTestCase): def _do_test(self, order, only_one_instance=True, save_restore=False): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() for s in order: choice = None if isinstance(s, tuple): s, choice = s if s.startswith('!'): logging.info("Checking that we cannot do '%s'", s[1:]) self.assertRaises(AssertionError, self.do_next_named_step, s[1:], choice=choice) else: if choice is not None: logging.info("Doing step '%s' (with choice='%s')", s, choice) else: logging.info("Doing step '%s'", s) # logging.debug(self.workflow.get_dump()) self.do_next_named_step(s, choice=choice, only_one_instance=only_one_instance) self.workflow.do_engine_steps() if save_restore: # logging.debug("Before SaveRestore: \n%s" % # self.workflow.get_dump()) self.save_restore() self.workflow.do_engine_steps() unfinished = self.workflow.get_tasks(Task.READY | Task.WAITING) if unfinished: logging.debug("Unfinished tasks: %s", unfinished) logging.debug(self.workflow.get_dump()) self.assertEqual(0, len(unfinished))
class NestedProcessesTest(BpmnWorkflowTestCase): def setUp(self): self.spec = self.load_spec() def load_spec(self): return self.load_workflow_spec('Test-Workflows/*.bpmn20.xml', 'Nested Subprocesses') def testRunThroughHappy(self): self.workflow = BpmnWorkflow(self.spec) self.do_next_named_step('Action1') self.workflow.do_engine_steps() self.save_restore() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Action2') self.workflow.do_engine_steps() self.save_restore() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Action3') self.workflow.do_engine_steps() self.save_restore() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
class MessageInterruptsTest(BpmnWorkflowTestCase): def setUp(self): self.spec = self.load_spec() # self.spec.dump() def load_spec(self): return self.load_workflow_spec('Test-Workflows/*.bpmn20.xml', 'Test Workflows') def testRunThroughHappySaveAndRestore(self): self.workflow = BpmnWorkflow(self.spec) self.save_restore() self.do_next_exclusive_step('Select Test', choice='Message Interrupts') self.workflow.do_engine_steps() self.save_restore() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.do_next_exclusive_step('Do Something That Takes A Long Time') self.save_restore() self.workflow.do_engine_steps() self.assertEqual(0, len(self.workflow.get_tasks(Task.WAITING))) self.save_restore() self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughMessageInterruptSaveAndRestore(self): self.workflow = BpmnWorkflow(self.spec) self.save_restore() self.do_next_exclusive_step('Select Test', choice='Message Interrupts') self.workflow.do_engine_steps() self.save_restore() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.accept_message('Test Message') self.save_restore() self.workflow.do_engine_steps() self.save_restore() self.assertEqual(0, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.do_next_exclusive_step('Acknowledge Interrupt Message') self.save_restore() self.workflow.do_engine_steps() self.save_restore() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughHappy(self): self.workflow = BpmnWorkflow(self.spec) self.do_next_exclusive_step('Select Test', choice='Message Interrupts') self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.do_next_exclusive_step('Do Something That Takes A Long Time') self.workflow.do_engine_steps() self.assertEqual(0, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughMessageInterrupt(self): self.workflow = BpmnWorkflow(self.spec) self.do_next_exclusive_step('Select Test', choice='Message Interrupts') self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.accept_message('Test Message') self.workflow.do_engine_steps() self.assertEqual(0, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.do_next_exclusive_step('Acknowledge Interrupt Message') self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
class ActionManagementTest(BpmnWorkflowTestCase): def setUp(self): self.spec = self.load_spec() self.workflow = BpmnWorkflow(self.spec) start_time = datetime.datetime.now() + datetime.timedelta(seconds=0.5) finish_time = datetime.datetime.now() + datetime.timedelta(seconds=1.5) self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.workflow.get_tasks(Task.READY)[0].set_data( start_time=start_time, finish_time=finish_time) def load_spec(self): return self.load_workflow_spec('Test-Workflows/*.bpmn20.xml', 'Action Management') def testRunThroughHappy(self): self.do_next_exclusive_step("Review Action", choice='Approve') self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual('NEW ACTION', self.workflow.get_tasks( Task.READY)[0].get_data('script_output')) self.assertEqual('Cancel Action (if necessary)', self.workflow.get_tasks(Task.READY)[0].task_spec.description) time.sleep(0.6) self.workflow.refresh_waiting_tasks() self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step("Start Work") self.workflow.do_engine_steps() self.do_next_named_step("Complete Work", choice="Done") self.workflow.do_engine_steps() self.assertTrue(self.workflow.is_completed()) def testRunThroughOverdue(self): self.do_next_exclusive_step("Review Action", choice='Approve') self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual('Cancel Action (if necessary)', self.workflow.get_tasks(Task.READY)[0].task_spec.description) time.sleep(0.6) self.workflow.refresh_waiting_tasks() self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step("Start Work") self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual('Finish Time', self.workflow.get_tasks( Task.WAITING)[0].task_spec.description) time.sleep(1.1) self.workflow.refresh_waiting_tasks() self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.assertNotEqual( 'Finish Time', self.workflow.get_tasks(Task.WAITING)[0].task_spec.description) overdue_escalation_task = [ t for t in self.workflow.get_tasks() if t.task_spec.description == 'Overdue Escalation'] self.assertEqual(1, len(overdue_escalation_task)) overdue_escalation_task = overdue_escalation_task[0] self.assertEqual(Task.COMPLETED, overdue_escalation_task.state) self.assertEqual( 'ACTION OVERDUE', overdue_escalation_task.get_data('script_output')) self.do_next_named_step("Complete Work", choice="Done") self.workflow.do_engine_steps() self.assertTrue(self.workflow.is_completed()) def testRunThroughCancel(self): self.do_next_exclusive_step("Review Action", choice='Cancel') self.workflow.do_engine_steps() self.assertTrue(self.workflow.is_completed()) def testRunThroughCancelAfterApproved(self): self.do_next_exclusive_step("Review Action", choice='Approve') self.workflow.do_engine_steps() self.do_next_named_step("Cancel Action (if necessary)") self.workflow.do_engine_steps() self.assertTrue(self.workflow.is_completed()) self.assertEqual( 'ACTION CANCELLED', self.workflow.get_data('script_output')) def testRunThroughCancelAfterWorkStarted(self): self.do_next_exclusive_step("Review Action", choice='Approve') self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) time.sleep(0.6) self.workflow.refresh_waiting_tasks() self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step("Start Work") self.workflow.do_engine_steps() self.do_next_named_step("Cancel Action (if necessary)") self.workflow.do_engine_steps() self.assertTrue(self.workflow.is_completed()) self.assertEqual( 'ACTION CANCELLED', self.workflow.get_data('script_output'))
class ActionManagementTest(BpmnWorkflowTestCase): def setUp(self): self.spec = self.load_spec() self.workflow = BpmnWorkflow(self.spec) start_time = datetime.datetime.now() + datetime.timedelta(seconds=0.5) finish_time = datetime.datetime.now() + datetime.timedelta(seconds=1.5) self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.workflow.get_tasks(Task.READY)[0].set_data( start_time=start_time, finish_time=finish_time) def load_spec(self): return self.load_workflow_spec('Test-Workflows/*.bpmn20.xml', 'Action Management') def testRunThroughHappy(self): self.do_next_exclusive_step("Review Action", choice='Approve') self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual( 'NEW ACTION', self.workflow.get_tasks(Task.READY)[0].get_data('script_output')) self.assertEqual( 'Cancel Action (if necessary)', self.workflow.get_tasks(Task.READY)[0].task_spec.description) time.sleep(0.6) self.workflow.refresh_waiting_tasks() self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step("Start Work") self.workflow.do_engine_steps() self.do_next_named_step("Complete Work", choice="Done") self.workflow.do_engine_steps() self.assertTrue(self.workflow.is_completed()) def testRunThroughOverdue(self): self.do_next_exclusive_step("Review Action", choice='Approve') self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual( 'Cancel Action (if necessary)', self.workflow.get_tasks(Task.READY)[0].task_spec.description) time.sleep(0.6) self.workflow.refresh_waiting_tasks() self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step("Start Work") self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual( 'Finish Time', self.workflow.get_tasks(Task.WAITING)[0].task_spec.description) time.sleep(1.1) self.workflow.refresh_waiting_tasks() self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.assertNotEqual( 'Finish Time', self.workflow.get_tasks(Task.WAITING)[0].task_spec.description) overdue_escalation_task = [ t for t in self.workflow.get_tasks() if t.task_spec.description == 'Overdue Escalation' ] self.assertEqual(1, len(overdue_escalation_task)) overdue_escalation_task = overdue_escalation_task[0] self.assertEqual(Task.COMPLETED, overdue_escalation_task.state) self.assertEqual('ACTION OVERDUE', overdue_escalation_task.get_data('script_output')) self.do_next_named_step("Complete Work", choice="Done") self.workflow.do_engine_steps() self.assertTrue(self.workflow.is_completed()) def testRunThroughCancel(self): self.do_next_exclusive_step("Review Action", choice='Cancel') self.workflow.do_engine_steps() self.assertTrue(self.workflow.is_completed()) def testRunThroughCancelAfterApproved(self): self.do_next_exclusive_step("Review Action", choice='Approve') self.workflow.do_engine_steps() self.do_next_named_step("Cancel Action (if necessary)") self.workflow.do_engine_steps() self.assertTrue(self.workflow.is_completed()) self.assertEqual('ACTION CANCELLED', self.workflow.get_data('script_output')) def testRunThroughCancelAfterWorkStarted(self): self.do_next_exclusive_step("Review Action", choice='Approve') self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) time.sleep(0.6) self.workflow.refresh_waiting_tasks() self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step("Start Work") self.workflow.do_engine_steps() self.do_next_named_step("Cancel Action (if necessary)") self.workflow.do_engine_steps() self.assertTrue(self.workflow.is_completed()) self.assertEqual('ACTION CANCELLED', self.workflow.get_data('script_output'))
class MessageNonInterruptsSpTest(BpmnWorkflowTestCase): def setUp(self): self.spec = self.load_spec() def load_spec(self): return self.load_workflow_spec('Test-Workflows/*.bpmn20.xml', 'Message Non Interrupt SP') def testRunThroughHappySaveAndRestore(self): self.workflow = BpmnWorkflow(self.spec) self.save_restore() self.workflow.do_engine_steps() self.save_restore() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.do_next_exclusive_step('Do Something In a Subprocess') self.workflow.do_engine_steps() self.save_restore() self.do_next_exclusive_step('Ack Subprocess Done') self.workflow.do_engine_steps() self.save_restore() self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughMessageSaveAndRestore(self): self.workflow = BpmnWorkflow(self.spec) self.save_restore() self.workflow.do_engine_steps() self.save_restore() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.accept_message('Test Message') self.do_next_named_step('Do Something In a Subprocess') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Ack Subprocess Done') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Acknowledge SP Parallel Message') self.workflow.do_engine_steps() self.save_restore() self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughMessageOrder2SaveAndRestore(self): self.workflow = BpmnWorkflow(self.spec) self.save_restore() self.workflow.do_engine_steps() self.save_restore() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.accept_message('Test Message') self.do_next_named_step('Do Something In a Subprocess') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Acknowledge SP Parallel Message') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Ack Subprocess Done') self.workflow.do_engine_steps() self.save_restore() self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughMessageOrder3SaveAndRestore(self): self.workflow = BpmnWorkflow(self.spec) self.save_restore() self.workflow.do_engine_steps() self.save_restore() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.accept_message('Test Message') self.do_next_named_step('Acknowledge SP Parallel Message') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Do Something In a Subprocess') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Ack Subprocess Done') self.workflow.do_engine_steps() self.save_restore() self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
class ParallelJoinLongInclusiveTest(ParallelJoinLongTest): def load_spec(self): return self.load_workflow_spec('Test-Workflows/Parallel-Join-Long-Inclusive.bpmn20.xml', 'Parallel Join Long Inclusive') def testRunThroughThread1FirstThenNo(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step( 'Thread 1 - Choose', choice='Yes', with_save_load=True) self.workflow.do_engine_steps() for i in range(1, 13): self.do_next_named_step('Thread 1 - Task %d' % i) self.workflow.do_engine_steps() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.do_next_named_step( 'Thread 2 - Choose', choice='No', with_save_load=True) self.workflow.do_engine_steps() self.do_next_named_step('Done', with_save_load=True) self.workflow.do_engine_steps() self.do_next_named_step('Thread 2 - No Task', with_save_load=True) self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testNoFirstThenThread1(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step( 'Thread 2 - Choose', choice='No', with_save_load=True) self.workflow.do_engine_steps() self.do_next_named_step( 'Thread 1 - Choose', choice='Yes', with_save_load=True) self.workflow.do_engine_steps() for i in range(1, 13): self.do_next_named_step('Thread 1 - Task %d' % i) self.workflow.do_engine_steps() self.do_next_named_step('Done', with_save_load=True) self.workflow.do_engine_steps() self.do_next_named_step('Thread 2 - No Task', with_save_load=True) self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
class ParallelOnePathEndsTest(BpmnWorkflowTestCase): def setUp(self): self.spec = self.load_spec() def load_spec(self): return self.load_workflow_spec('Test-Workflows/Parallel-One-Path-Ends.bpmn20.xml', 'Parallel One Path Ends') def testRunThroughParallelTaskFirst(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Parallel Task') self.workflow.do_engine_steps() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.do_next_named_step('Choice 1', choice='No') self.workflow.do_engine_steps() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughChoiceFirst(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Choice 1', choice='No') self.workflow.do_engine_steps() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.do_next_named_step('Parallel Task') self.workflow.do_engine_steps() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughParallelTaskFirstYes(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Parallel Task') self.workflow.do_engine_steps() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.do_next_named_step('Choice 1', choice='Yes') self.workflow.do_engine_steps() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.do_next_named_step('Yes Task') self.workflow.do_engine_steps() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
class ParallelJoinLongTest(BpmnWorkflowTestCase): def setUp(self): self.spec = self.load_spec() def load_spec(self): return self.load_workflow_spec( 'Test-Workflows/Parallel-Join-Long.bpmn20.xml', 'Parallel Join Long') def testRunThroughAlternating(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Thread 1 - Choose', choice='Yes', with_save_load=True) self.workflow.do_engine_steps() self.do_next_named_step('Thread 2 - Choose', choice='Yes', with_save_load=True) self.workflow.do_engine_steps() for i in range(1, 13): self.do_next_named_step('Thread 1 - Task %d' % i, with_save_load=True) self.workflow.do_engine_steps() self.do_next_named_step('Thread 2 - Task %d' % i, with_save_load=True) self.workflow.do_engine_steps() self.do_next_named_step('Done', with_save_load=True) self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughThread1First(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Thread 1 - Choose', choice='Yes', with_save_load=True) self.workflow.do_engine_steps() for i in range(1, 13): self.do_next_named_step('Thread 1 - Task %d' % i) self.workflow.do_engine_steps() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.do_next_named_step('Thread 2 - Choose', choice='Yes', with_save_load=True) self.workflow.do_engine_steps() for i in range(1, 13): self.do_next_named_step('Thread 2 - Task %d' % i, with_save_load=True) self.workflow.do_engine_steps() self.do_next_named_step('Done', with_save_load=True) self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
class MessageInterruptsSpTest(BpmnWorkflowTestCase): def setUp(self): self.spec = self.load_spec() def load_spec(self): return self.load_workflow_spec('Test-Workflows/*.bpmn20.xml', 'Message Interrupts SP') def testRunThroughHappySaveAndRestore(self): self.workflow = BpmnWorkflow(self.spec) self.save_restore() self.workflow.do_engine_steps() self.save_restore() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.do_next_exclusive_step('Do Something In a Subprocess') self.workflow.do_engine_steps() self.save_restore() self.do_next_exclusive_step('Ack Subprocess Done') self.workflow.do_engine_steps() self.save_restore() self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughInterruptSaveAndRestore(self): self.workflow = BpmnWorkflow(self.spec) self.save_restore() self.workflow.do_engine_steps() self.save_restore() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.accept_message('Test Message') self.workflow.do_engine_steps() self.save_restore() self.do_next_exclusive_step('Acknowledge SP Interrupt Message') self.workflow.do_engine_steps() self.save_restore() self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
if __name__ == '__main__': spec=load_workflow_spec('Test-Workflows/*.bpmn20.xml', 'Test Workflows') workflow=BpmnWorkflow(spec) task_spec0=workflow.get_task_spec_from_name('sid-6A83C24E-9609-47CD-B595-BCFC30BBF790') task_spec0.ready_event.connect(usertask1) task_spec1=workflow.get_task_spec_from_name('sid-5A3ED200-8278-4D1F-9F84-B5E53B268133') task_spec2=workflow.get_task_spec_from_name('sid-464B8E64-10B4-4158-BDEE-11144CE20306') task_spec2.ready_event.connect(end) workflow.do_engine_steps() workflow.get_tasks(Task.READY)[0].complete() workflow.do_engine_steps() workflow.accept_message('Test Message') workflow.get_tasks(Task.READY)[0].complete() workflow.do_engine_steps()
class ParallelJoinLongInclusiveTest(ParallelJoinLongTest): def load_spec(self): return self.load_workflow_spec( 'Test-Workflows/Parallel-Join-Long-Inclusive.bpmn20.xml', 'Parallel Join Long Inclusive') def testRunThroughThread1FirstThenNo(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Thread 1 - Choose', choice='Yes', with_save_load=True) self.workflow.do_engine_steps() for i in range(1, 13): self.do_next_named_step('Thread 1 - Task %d' % i) self.workflow.do_engine_steps() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.do_next_named_step('Thread 2 - Choose', choice='No', with_save_load=True) self.workflow.do_engine_steps() self.do_next_named_step('Done', with_save_load=True) self.workflow.do_engine_steps() self.do_next_named_step('Thread 2 - No Task', with_save_load=True) self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testNoFirstThenThread1(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Thread 2 - Choose', choice='No', with_save_load=True) self.workflow.do_engine_steps() self.do_next_named_step('Thread 1 - Choose', choice='Yes', with_save_load=True) self.workflow.do_engine_steps() for i in range(1, 13): self.do_next_named_step('Thread 1 - Task %d' % i) self.workflow.do_engine_steps() self.do_next_named_step('Done', with_save_load=True) self.workflow.do_engine_steps() self.do_next_named_step('Thread 2 - No Task', with_save_load=True) self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
class ParallelOnePathEndsTest(BpmnWorkflowTestCase): def setUp(self): self.spec = self.load_spec() def load_spec(self): return self.load_workflow_spec( 'Test-Workflows/Parallel-One-Path-Ends.bpmn20.xml', 'Parallel One Path Ends') def testRunThroughParallelTaskFirst(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Parallel Task') self.workflow.do_engine_steps() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.do_next_named_step('Choice 1', choice='No') self.workflow.do_engine_steps() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughChoiceFirst(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Choice 1', choice='No') self.workflow.do_engine_steps() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.do_next_named_step('Parallel Task') self.workflow.do_engine_steps() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughParallelTaskFirstYes(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Parallel Task') self.workflow.do_engine_steps() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.do_next_named_step('Choice 1', choice='Yes') self.workflow.do_engine_steps() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.do_next_named_step('Yes Task') self.workflow.do_engine_steps() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
class ParallelThroughSameTaskTest(BpmnWorkflowTestCase): def setUp(self): self.spec = self.load_spec() def load_spec(self): return self.load_workflow_spec( 'Test-Workflows/Parallel-Through-Same-Task.bpmn20.xml', 'Parallel Through Same Task') def testRunThroughFirstRepeatTaskFirst(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Repeated Task') self.workflow.do_engine_steps() # The inclusive gateway allows this to pass through (since there is a # route to it on the same sequence flow) self.do_next_named_step('Done') self.workflow.do_engine_steps() self.do_next_named_step('Choice 1', choice='Yes') self.workflow.do_engine_steps() self.do_next_named_step('Yes Task') self.workflow.do_engine_steps() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.do_next_named_step('Repeated Task') self.workflow.do_engine_steps() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRepeatTasksReadyTogether(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Choice 1', choice='Yes') self.workflow.do_engine_steps() self.do_next_named_step('Yes Task') self.workflow.do_engine_steps() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') ready_tasks = self.workflow.get_tasks(Task.READY) self.assertEqual(2, len(ready_tasks)) self.assertEqual('Repeated Task', ready_tasks[0].task_spec.description) ready_tasks[0].complete() self.workflow.do_engine_steps() # The inclusive gateway allows us through here, because there is no route for the other thread # that doesn't use the same sequence flow self.do_next_named_step('Done') self.workflow.do_engine_steps() self.do_next_named_step('Repeated Task') self.workflow.do_engine_steps() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRepeatTasksReadyTogetherSaveRestore(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.save_restore() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Choice 1', choice='Yes') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Yes Task') self.workflow.do_engine_steps() self.save_restore() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') ready_tasks = self.workflow.get_tasks(Task.READY) self.assertEqual(2, len(ready_tasks)) self.assertEqual('Repeated Task', ready_tasks[0].task_spec.description) ready_tasks[0].complete() self.workflow.do_engine_steps() self.save_restore() # The inclusive gateway allows us through here, because there is no route for the other thread # that doesn't use the same sequence flow self.do_next_named_step('Done') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Repeated Task') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.save_restore() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testNoRouteRepeatTaskFirst(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.save_restore() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Repeated Task') self.workflow.do_engine_steps() self.save_restore() # The inclusive gateway allows this to pass through (since there is a # route to it on the same sequence flow) self.do_next_named_step('Done') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Choice 1', choice='No') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('No Task') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.save_restore() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testNoRouteNoTaskFirst(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.save_restore() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Choice 1', choice='No') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('No Task') self.workflow.do_engine_steps() self.save_restore() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.do_next_named_step('Repeated Task') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.save_restore() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testNoRouteNoFirstThenRepeating(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.save_restore() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Choice 1', choice='No') self.workflow.do_engine_steps() self.save_restore() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.do_next_named_step('Repeated Task') self.workflow.do_engine_steps() self.save_restore() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.do_next_named_step('No Task') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.save_restore() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
class ParallelMultipleSplitsTest(BpmnWorkflowTestCase): def setUp(self): self.spec = self.load_spec() def load_spec(self): return self.load_workflow_spec( 'Test-Workflows/Parallel-Multiple-Splits.bpmn20.xml', 'Parallel Multiple Splits') def testRunThroughAlternating(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Do First') self.workflow.do_engine_steps() self.do_next_named_step('SP 1 - Choose', choice='Yes') self.workflow.do_engine_steps() self.do_next_named_step('SP 2 - Choose', choice='Yes') self.workflow.do_engine_steps() self.do_next_named_step('SP 3 - Choose', choice='Yes') self.workflow.do_engine_steps() self.do_next_named_step('SP 1 - Yes Task') self.workflow.do_engine_steps() self.do_next_named_step('SP 2 - Yes Task') self.workflow.do_engine_steps() self.do_next_named_step('SP 3 - Yes Task') self.workflow.do_engine_steps() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
class MessageNonInterruptTest(BpmnWorkflowTestCase): def setUp(self): self.spec = self.load_spec() # self.spec.dump() def load_spec(self): return self.load_workflow_spec('Test-Workflows/*.bpmn20.xml', 'Test Workflows') def testRunThroughHappySaveAndRestore(self): self.workflow = BpmnWorkflow(self.spec) self.save_restore() self.do_next_exclusive_step('Select Test', choice='Message Non Interrupt') self.workflow.do_engine_steps() self.save_restore() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.do_next_exclusive_step('Do Something That Takes A Long Time') self.save_restore() self.workflow.do_engine_steps() self.assertEqual(0, len(self.workflow.get_tasks(Task.WAITING))) self.save_restore() self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughMessageInterruptSaveAndRestore(self): self.workflow = BpmnWorkflow(self.spec) self.save_restore() self.do_next_exclusive_step('Select Test', choice='Message Non Interrupt') self.workflow.do_engine_steps() self.save_restore() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.accept_message('Test Message') self.save_restore() self.workflow.do_engine_steps() self.assertEqual(0, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Acknowledge Non-Interrupt Message') self.workflow.do_engine_steps() self.save_restore() self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Do Something That Takes A Long Time') self.workflow.do_engine_steps() self.save_restore() self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughHappy(self): self.workflow = BpmnWorkflow(self.spec) self.do_next_exclusive_step('Select Test', choice='Message Non Interrupt') self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.do_next_exclusive_step('Do Something That Takes A Long Time') self.workflow.do_engine_steps() self.assertEqual(0, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughMessageInterrupt(self): self.workflow = BpmnWorkflow(self.spec) self.do_next_exclusive_step('Select Test', choice='Message Non Interrupt') self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.accept_message('Test Message') self.workflow.do_engine_steps() self.assertEqual(0, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Acknowledge Non-Interrupt Message') self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.do_next_named_step('Do Something That Takes A Long Time') self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughMessageInterruptOtherOrder(self): self.workflow = BpmnWorkflow(self.spec) self.do_next_exclusive_step('Select Test', choice='Message Non Interrupt') self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.accept_message('Test Message') self.workflow.do_engine_steps() self.assertEqual(0, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Do Something That Takes A Long Time') self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Acknowledge Non-Interrupt Message') self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughMessageInterruptOtherOrderSaveAndRestore(self): self.workflow = BpmnWorkflow(self.spec) self.save_restore() self.do_next_exclusive_step('Select Test', choice='Message Non Interrupt') self.workflow.do_engine_steps() self.save_restore() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.accept_message('Test Message') self.save_restore() self.workflow.do_engine_steps() self.assertEqual(0, len(self.workflow.get_tasks(Task.WAITING))) self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Do Something That Takes A Long Time') self.save_restore() self.workflow.do_engine_steps() self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.assertEqual(1, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Acknowledge Non-Interrupt Message') self.save_restore() self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
class ParallelJoinLongTest(BpmnWorkflowTestCase): def setUp(self): self.spec = self.load_spec() def load_spec(self): return self.load_workflow_spec('Test-Workflows/Parallel-Join-Long.bpmn20.xml', 'Parallel Join Long') def testRunThroughAlternating(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step( 'Thread 1 - Choose', choice='Yes', with_save_load=True) self.workflow.do_engine_steps() self.do_next_named_step( 'Thread 2 - Choose', choice='Yes', with_save_load=True) self.workflow.do_engine_steps() for i in range(1, 13): self.do_next_named_step( 'Thread 1 - Task %d' % i, with_save_load=True) self.workflow.do_engine_steps() self.do_next_named_step( 'Thread 2 - Task %d' % i, with_save_load=True) self.workflow.do_engine_steps() self.do_next_named_step('Done', with_save_load=True) self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRunThroughThread1First(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step( 'Thread 1 - Choose', choice='Yes', with_save_load=True) self.workflow.do_engine_steps() for i in range(1, 13): self.do_next_named_step('Thread 1 - Task %d' % i) self.workflow.do_engine_steps() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.assertEqual(1, len(self.workflow.get_tasks(Task.WAITING))) self.do_next_named_step( 'Thread 2 - Choose', choice='Yes', with_save_load=True) self.workflow.do_engine_steps() for i in range(1, 13): self.do_next_named_step( 'Thread 2 - Task %d' % i, with_save_load=True) self.workflow.do_engine_steps() self.do_next_named_step('Done', with_save_load=True) self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
class ParallelMultipleSplitsTest(BpmnWorkflowTestCase): def setUp(self): self.spec = self.load_spec() def load_spec(self): return self.load_workflow_spec('Test-Workflows/Parallel-Multiple-Splits.bpmn20.xml', 'Parallel Multiple Splits') def testRunThroughAlternating(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Do First') self.workflow.do_engine_steps() self.do_next_named_step('SP 1 - Choose', choice='Yes') self.workflow.do_engine_steps() self.do_next_named_step('SP 2 - Choose', choice='Yes') self.workflow.do_engine_steps() self.do_next_named_step('SP 3 - Choose', choice='Yes') self.workflow.do_engine_steps() self.do_next_named_step('SP 1 - Yes Task') self.workflow.do_engine_steps() self.do_next_named_step('SP 2 - Yes Task') self.workflow.do_engine_steps() self.do_next_named_step('SP 3 - Yes Task') self.workflow.do_engine_steps() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
class ParallelThroughSameTaskTest(BpmnWorkflowTestCase): def setUp(self): self.spec = self.load_spec() def load_spec(self): return self.load_workflow_spec('Test-Workflows/Parallel-Through-Same-Task.bpmn20.xml', 'Parallel Through Same Task') def testRunThroughFirstRepeatTaskFirst(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Repeated Task') self.workflow.do_engine_steps() # The inclusive gateway allows this to pass through (since there is a # route to it on the same sequence flow) self.do_next_named_step('Done') self.workflow.do_engine_steps() self.do_next_named_step('Choice 1', choice='Yes') self.workflow.do_engine_steps() self.do_next_named_step('Yes Task') self.workflow.do_engine_steps() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.do_next_named_step('Repeated Task') self.workflow.do_engine_steps() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRepeatTasksReadyTogether(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Choice 1', choice='Yes') self.workflow.do_engine_steps() self.do_next_named_step('Yes Task') self.workflow.do_engine_steps() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') ready_tasks = self.workflow.get_tasks(Task.READY) self.assertEqual(2, len(ready_tasks)) self.assertEqual( 'Repeated Task', ready_tasks[0].task_spec.description) ready_tasks[0].complete() self.workflow.do_engine_steps() # The inclusive gateway allows us through here, because there is no route for the other thread # that doesn't use the same sequence flow self.do_next_named_step('Done') self.workflow.do_engine_steps() self.do_next_named_step('Repeated Task') self.workflow.do_engine_steps() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testRepeatTasksReadyTogetherSaveRestore(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.save_restore() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Choice 1', choice='Yes') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Yes Task') self.workflow.do_engine_steps() self.save_restore() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') ready_tasks = self.workflow.get_tasks(Task.READY) self.assertEqual(2, len(ready_tasks)) self.assertEqual( 'Repeated Task', ready_tasks[0].task_spec.description) ready_tasks[0].complete() self.workflow.do_engine_steps() self.save_restore() # The inclusive gateway allows us through here, because there is no route for the other thread # that doesn't use the same sequence flow self.do_next_named_step('Done') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Repeated Task') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.save_restore() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testNoRouteRepeatTaskFirst(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.save_restore() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Repeated Task') self.workflow.do_engine_steps() self.save_restore() # The inclusive gateway allows this to pass through (since there is a # route to it on the same sequence flow) self.do_next_named_step('Done') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Choice 1', choice='No') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('No Task') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.save_restore() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testNoRouteNoTaskFirst(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.save_restore() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Choice 1', choice='No') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('No Task') self.workflow.do_engine_steps() self.save_restore() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.do_next_named_step('Repeated Task') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.save_restore() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING))) def testNoRouteNoFirstThenRepeating(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.save_restore() self.assertEqual(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Choice 1', choice='No') self.workflow.do_engine_steps() self.save_restore() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.do_next_named_step('Repeated Task') self.workflow.do_engine_steps() self.save_restore() self.assertRaises(AssertionError, self.do_next_named_step, 'Done') self.do_next_named_step('No Task') self.workflow.do_engine_steps() self.save_restore() self.do_next_named_step('Done') self.workflow.do_engine_steps() self.save_restore() self.assertEqual( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))