def testRunThroughFirstRepeatTaskFirst(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEquals(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.assertEquals( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
def testRunThroughAlternating(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEquals(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.assertEquals( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
def testRunThroughAlternating(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEquals(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.assertEquals( 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.assertEquals(1, len(self.workflow.get_tasks(Task.READY))) self.assertEquals(1, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.accept_message('Test Message') self.workflow.do_engine_steps() self.assertEquals(0, len(self.workflow.get_tasks(Task.WAITING))) self.assertEquals(2, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Acknowledge Non-Interrupt Message') self.workflow.do_engine_steps() self.assertEquals(1, len(self.workflow.get_tasks(Task.READY))) self.assertEquals(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.assertEquals(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.assertEquals(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.assertEquals( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
def testRunThroughThread1FirstThenNo(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEquals(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.assertEquals(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.assertEquals( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
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.assertEquals(0, len(unfinished))
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.assertEquals(1, len(self.workflow.get_tasks(Task.READY))) self.assertEquals(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.assertEquals(0, len(self.workflow.get_tasks(Task.WAITING))) self.assertEquals(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.assertEquals( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
def create_workflow(self): """ Creates WF instance for current WF spec. Returns: BpmnWorkflow """ return BpmnWorkflow(self.workflow_spec)
def testRunThroughMessageOrder2SaveAndRestore(self): self.workflow = BpmnWorkflow(self.spec) self.save_restore() self.workflow.do_engine_steps() self.save_restore() self.assertEquals(1, len(self.workflow.get_tasks(Task.READY))) self.assertEquals(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.assertEquals( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
def testRepeatTasksReadyTogether(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEquals(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.assertEquals(2, len(ready_tasks)) self.assertEquals('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.assertEquals( 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.assertEquals(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.assertEquals( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
def new_workflow(self, workflow_spec, read_only=False, **kwargs): """ Create a new workflow instance from the given spec and arguments. :param workflow_spec: the workflow spec to use :param read_only: this should be in read only mode :param kwargs: Any extra kwargs passed to the deserialize_workflow method will be passed through here """ return BpmnWorkflow(workflow_spec, read_only=read_only)
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.assertEquals(1, len(self.workflow.get_tasks(Task.READY))) self.workflow.get_tasks(Task.READY)[0].set_attribute( start_time=start_time, finish_time=finish_time)
def __init__(self, file_path, entrypoint=None): entrypoint = entrypoint or 'main_process' bpmn = ET.parse(file_path) self.parser = BpmnParser() self.parser.add_bpmn_xml(bpmn, filename=file_path) self.spec = self.parser.get_spec(entrypoint) self.workflow = BpmnWorkflow(self.spec) self.graph = Graph(directed=True) self.data = {} self.data_watch = True self.vertices = {} self.vertice_id = 0 self.edges = {} self.edge_id = 0
def testRunThroughHappy(self): self.workflow = BpmnWorkflow(self.spec) self.do_next_named_step('Action1') self.workflow.do_engine_steps() self.save_restore() self.assertEquals(1, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Action2') self.workflow.do_engine_steps() self.save_restore() self.assertEquals(1, len(self.workflow.get_tasks(Task.READY))) self.do_next_named_step('Action3') self.workflow.do_engine_steps() self.save_restore() self.assertEquals(0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
def testRunThroughHappyOtherOrders(self): self.workflow = BpmnWorkflow(self.spec) self.do_next_named_step('First_Approval_Wins.Supervisor_Approval') self.do_next_exclusive_step('Approvals.First_Approval_Wins_Done') self.do_next_named_step('Approvals.Supervisor_Approval__P_') self.do_next_named_step('Approvals.Manager_Approval__P_') self.do_next_exclusive_step('Approvals.Parallel_Approvals_Done') self.do_next_named_step('Parallel_Approvals_SP.Manager_Approval') self.do_next_named_step('Parallel_Approvals_SP.Step1') self.do_next_named_step('Parallel_Approvals_SP.Supervisor_Approval') self.do_next_exclusive_step('Approvals.Parallel_SP_Done')
def load_or_create_workflow(self): """ tries to load the workflow from session creates a new one if it can't find :return: """ try: workflow_path = self.get_worfklow_path() serialized_wf = self.request.session.workflows[workflow_path] self.workflow = BpmnWorkflow.deserialize(DictionarySerializer(), serialized_wf) except Exception as e: print e wf_pkg_file = open(self.workflow_name) self.workflow_spec = BpmnSerializer().deserialize_workflow_spec(wf_pkg_file) self.workflow = BpmnWorkflow(self.workflow_spec)
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.assertEquals(1, len(self.workflow.get_tasks(Task.READY))) self.assertEquals(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.assertEquals(0, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.do_engine_steps() self.assertEquals(0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
def testRunThroughChoiceFirst(self): self.workflow = BpmnWorkflow(self.spec) self.workflow.do_engine_steps() self.assertEquals(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.assertEquals(0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
def testSaveRestore(self): self.workflow = BpmnWorkflow(self.spec) self.do_next_named_step('First_Approval_Wins.Manager_Approval') self.save_restore() self.do_next_exclusive_step('Approvals.First_Approval_Wins_Done') self.save_restore() self.do_next_named_step('Approvals.Supervisor_Approval__P_') self.do_next_named_step('Approvals.Manager_Approval__P_') self.do_next_exclusive_step('Approvals.Parallel_Approvals_Done') self.save_restore() self.do_next_named_step('Parallel_Approvals_SP.Manager_Approval') self.do_next_exclusive_step('Parallel_Approvals_SP.Step1') self.do_next_exclusive_step( 'Parallel_Approvals_SP.Supervisor_Approval') self.do_next_exclusive_step('Approvals.Parallel_SP_Done')
def testRunThroughHappy(self): self.workflow = BpmnWorkflow(self.spec) self.do_next_exclusive_step('Select Test', choice='Messages') self.workflow.do_engine_steps() self.assertEquals([], self.workflow.get_tasks(Task.READY)) self.assertEquals(1, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.accept_message('Wrong Message') self.assertEquals([], self.workflow.get_tasks(Task.READY)) self.workflow.accept_message('Test Message') self.assertEquals(1, len(self.workflow.get_tasks(Task.READY))) self.assertEquals( 'Test Message', self.workflow.get_tasks(Task.READY)[0].task_spec.description) self.workflow.do_engine_steps() self.assertEquals( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
def testRunThroughHappySaveAndRestore(self): self.workflow = BpmnWorkflow(self.spec) self.save_restore() self.workflow.do_engine_steps() self.save_restore() self.assertEquals(1, len(self.workflow.get_tasks(Task.READY))) self.assertEquals(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.assertEquals( 0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
def testRunThroughHappy(self): self.workflow = BpmnWorkflow(self.spec) due_time = datetime.datetime.now() + datetime.timedelta(seconds=0.5) self.assertEquals(1, len(self.workflow.get_tasks(Task.READY))) self.workflow.get_tasks(Task.READY)[0].set_attribute(due_time=due_time) self.workflow.do_engine_steps() self.assertEquals(1, len(self.workflow.get_tasks(Task.WAITING))) time.sleep(0.6) self.assertEquals(1, len(self.workflow.get_tasks(Task.WAITING))) self.workflow.refresh_waiting_tasks() self.assertEquals(0, len(self.workflow.get_tasks(Task.WAITING))) self.assertEquals(1, len(self.workflow.get_tasks(Task.READY))) self.workflow.do_engine_steps() self.assertEquals(0, len(self.workflow.get_tasks(Task.READY | Task.WAITING)))
def create_workflow(self): return BpmnWorkflow(self.workflow_spec)
def __init__(self, process_name, filename='*.bpmn'): self.spec = self.load_workflow_spec(filename, process_name) self.workflow = BpmnWorkflow(self.spec)
def testReadonlyWaiting(self): self.workflow = BpmnWorkflow(self.spec) self.do_next_named_step('First_Approval_Wins.Manager_Approval') readonly = self.get_read_only_workflow() self.assertEquals(1, len(readonly.get_ready_user_tasks())) self.assertEquals('Approvals.First_Approval_Wins_Done', readonly.get_ready_user_tasks()[0].task_spec.name) self.assertRaises(AssertionError, readonly.do_engine_steps) self.assertRaises(AssertionError, readonly.refresh_waiting_tasks) self.assertRaises(AssertionError, readonly.accept_message, 'Cheese') self.assertRaises(AssertionError, readonly.get_ready_user_tasks()[0].complete) self.do_next_exclusive_step('Approvals.First_Approval_Wins_Done') readonly = self.get_read_only_workflow() self.assertEquals(2, len(readonly.get_ready_user_tasks())) self.assertEquals([ 'Approvals.Manager_Approval__P_', 'Approvals.Supervisor_Approval__P_' ], sorted(t.task_spec.name for t in readonly.get_ready_user_tasks())) self.assertRaises(AssertionError, readonly.get_ready_user_tasks()[0].complete) self.do_next_named_step('Approvals.Supervisor_Approval__P_') readonly = self.get_read_only_workflow() self.assertEquals(1, len(readonly.get_ready_user_tasks())) self.assertEquals('Approvals.Manager_Approval__P_', readonly.get_ready_user_tasks()[0].task_spec.name) self.assertRaises(AssertionError, readonly.get_ready_user_tasks()[0].complete) self.do_next_named_step('Approvals.Manager_Approval__P_') readonly = self.get_read_only_workflow() self.assertEquals(1, len(readonly.get_ready_user_tasks())) self.assertEquals('Approvals.Parallel_Approvals_Done', readonly.get_ready_user_tasks()[0].task_spec.name) self.assertRaises(AssertionError, readonly.get_ready_user_tasks()[0].complete) self.do_next_exclusive_step('Approvals.Parallel_Approvals_Done') readonly = self.get_read_only_workflow() self.assertEquals(2, len(readonly.get_ready_user_tasks())) self.assertEquals([ 'Parallel_Approvals_SP.Manager_Approval', 'Parallel_Approvals_SP.Step1' ], sorted(t.task_spec.name for t in readonly.get_ready_user_tasks())) self.assertRaises(AssertionError, readonly.get_ready_user_tasks()[0].complete) self.do_next_named_step('Parallel_Approvals_SP.Manager_Approval') readonly = self.get_read_only_workflow() self.assertEquals(1, len(readonly.get_ready_user_tasks())) self.assertEquals('Parallel_Approvals_SP.Step1', readonly.get_ready_user_tasks()[0].task_spec.name) self.assertRaises(AssertionError, readonly.get_ready_user_tasks()[0].complete) self.do_next_exclusive_step('Parallel_Approvals_SP.Step1') readonly = self.get_read_only_workflow() self.assertEquals(1, len(readonly.get_ready_user_tasks())) self.assertEquals('Parallel_Approvals_SP.Supervisor_Approval', readonly.get_ready_user_tasks()[0].task_spec.name) self.assertRaises(AssertionError, readonly.get_ready_user_tasks()[0].complete) self.do_next_exclusive_step( 'Parallel_Approvals_SP.Supervisor_Approval') readonly = self.get_read_only_workflow() self.assertEquals(1, len(readonly.get_ready_user_tasks())) self.assertEquals('Approvals.Parallel_SP_Done', readonly.get_ready_user_tasks()[0].task_spec.name) self.assertRaises(AssertionError, readonly.get_ready_user_tasks()[0].complete) self.do_next_exclusive_step('Approvals.Parallel_SP_Done') readonly = self.get_read_only_workflow() self.assertEquals(0, len(readonly.get_ready_user_tasks())) self.assertEquals(0, len(readonly.get_waiting_tasks()))