spiff-arena/tests/SpiffWorkflow/bpmn/CollaborationTest.py
burnettk f1b8cfcc07 Squashed 'SpiffWorkflow/' changes from bee868d38..96ad2a2b0
96ad2a2b0 Merge pull request #311 from sartography/feature/error-message-on-bad-child-task
3fb69038d Merge remote-tracking branch 'origin/main' into feature/error-message-on-bad-child-task
df703ebb8 Merge remote-tracking branch 'origin/feature/add_task_not_found_error'
d6e244bcf also raise TaskNotFoundException from bpmn workflow w/ burnettk
37d7ae679 Merge pull request #310 from sartography/feature/add_task_not_found_error
7f4d38ce2 give us a better error if for some reason a task does not exist
b98efbd20 added an exception for task not found w/ burnettk
e1add839d Merge pull request #308 from sartography/bugfix/execute-event-gateways-on-ready
964c0231a do not predict tasks when deserializing, add method to predict all unfinished tasks
114f87aa9 update event gateway
62454c99c Merge pull request #307 from sartography/feature/standardize-task-execution
a087d29ea update task_spec._run to return a boolean & misc cleanup
9864d753d reenable recursion test
1bb1246a0 rename methods & move ready_before tasks from run to ready
12ce08519 move event task execution to run
d51bb68eb cleanup predictions
5e05458a3 make all tasks execute when run rather than completed (except bpmn events)
273d7b325 create a run method for tasks
3c3345c85 Merge pull request #306 from sartography/feature/create-core-test-package
ed85547d7 hopefully fix CI job, also update some deprecated assertions
80d68c231 cleanup around finding tasks
ea5ffff41 create tests based on individual patterns
afe41fba1 move core tests into one package
c075d52bc remove locks from task spec -- they don't do anything
d78c7cc04 reorganize so that related methods are near each other
f162aac43 Merge pull request #305 from sartography/feature/remove-loop-reset
6cad29817 'fix' old serializer to remove loop resets -- or at least get the tests to pass
a95d2fc12 add serialization migration that removes loop resets
c076175c8 account for DST in timers
42b483054 Merge pull request #303 from sartography/bugfix/execute-tasks-on-ready
2bb08aae1 update script/service tasks to execute on ready
0bd23a0ab fix scripts in business rule tasks
13034aaf1 prevent loop reset tasks from being inserted
3fb80518d update join execution model

git-subtree-dir: SpiffWorkflow
git-subtree-split: 96ad2a2b060deb445c39374f065690023351de19
2023-04-07 11:46:14 -04:00

155 lines
7.3 KiB
Python

from SpiffWorkflow.bpmn.specs.SubWorkflowTask import CallActivity
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow, BpmnMessage
from SpiffWorkflow.task import TaskState
from tests.SpiffWorkflow.bpmn.BpmnWorkflowTestCase import BpmnWorkflowTestCase
class CollaborationTest(BpmnWorkflowTestCase):
def testParserProvidesInfoOnMessagesAndCorrelations(self):
parser = self.get_parser('collaboration.bpmn')
self.assertEqual(list(parser.messages.keys()), ['love_letter', 'love_letter_response'])
self.assertEqual(parser.correlations,
{'lover_name': {'name': "Lover's Name",
'retrieval_expressions': [
{'expression': 'lover_name',
'messageRef': 'love_letter'},
{'expression': 'from_name',
'messageRef': 'love_letter_response'}]}}
)
def testCollaboration(self):
spec, subprocesses = self.load_collaboration('collaboration.bpmn', 'my_collaboration')
# Only executable processes should be started
self.assertIn('process_buddy', subprocesses)
self.assertNotIn('random_person_process', subprocesses)
self.workflow = BpmnWorkflow(spec, subprocesses)
start = self.workflow.get_tasks_from_spec_name('Start')[0]
# Set up some data to be evaluated so that the workflow can proceed
start.data['lover_name'] = 'Peggy'
self.workflow.do_engine_steps()
# Call activities should be created for executable processes and be reachable
buddy = self.workflow.get_tasks_from_spec_name('process_buddy')[0]
self.assertIsInstance(buddy.task_spec, CallActivity)
self.assertEqual(buddy.task_spec.spec, 'process_buddy')
self.assertEqual(buddy.state, TaskState.WAITING)
def testBpmnMessage(self):
spec, subprocesses = self.load_workflow_spec('collaboration.bpmn', 'process_buddy')
workflow = BpmnWorkflow(spec, subprocesses)
start = workflow.get_tasks_from_spec_name('Start')[0]
# Set up some data to be evaluated so that the workflow can proceed
start.data['lover_name'] = 'Peggy'
workflow.do_engine_steps()
# An external message should be created
messages = workflow.get_bpmn_messages()
self.assertEqual(len(messages), 1)
self.assertEqual(len(workflow.bpmn_messages), 0)
receive = workflow.get_tasks_from_spec_name('EventReceiveLetter')[0]
# Waiting Events should contain details about what we are no waiting on.
events = workflow.waiting_events()
self.assertEqual(1, len(events))
self.assertEqual("Message", events[0]['event_type'])
self.assertEqual("Love Letter Response", events[0]['name'])
self.assertEqual(['lover'], events[0]['value'][0].correlation_keys)
self.assertEqual('from_name', events[0]['value'][0].retrieval_expression)
self.assertEqual('lover_name', events[0]['value'][0].name)
# As shown above, the waiting event is looking for a payload with a
# 'from_name' that should be used to retrieve the lover's name.
new_message_payload = {'from_name': 'Peggy', 'other_nonsense': 1001}
workflow.catch_bpmn_message('Love Letter Response', new_message_payload)
workflow.do_engine_steps()
# The external message created above should be caught
self.assertEqual(receive.state, TaskState.COMPLETED)
# Spiff extensions allow us to specify the destination of a workflow
# but base BPMN does not, and all keys are added directly to the
# task data.
self.assertEqual(workflow.last_task.data, {'from_name': 'Peggy', 'lover_name': 'Peggy', 'other_nonsense': 1001})
self.assertEqual(workflow.correlations, {'lover':{'lover_name':'Peggy'}})
self.assertEqual(workflow.is_completed(), True)
def testCorrelation(self):
specs = self.get_all_specs('correlation.bpmn')
proc_1 = specs['proc_1']
workflow = BpmnWorkflow(proc_1, specs)
workflow.do_engine_steps()
for idx, task in enumerate(workflow.get_ready_user_tasks()):
task.data['task_num'] = idx
task.run()
workflow.do_engine_steps()
ready_tasks = workflow.get_ready_user_tasks()
waiting = workflow.get_tasks_from_spec_name('get_response')
# Two processes should have been started and two corresponding catch events should be waiting
self.assertEqual(len(ready_tasks), 2)
self.assertEqual(len(waiting), 2)
for task in waiting:
self.assertEqual(task.state, TaskState.WAITING)
# Now copy the task_num that was sent into a new variable
for task in ready_tasks:
task.data.update(init_id=task.data['task_num'])
task.run()
workflow.do_engine_steps()
# If the messages were routed properly, the id should match
for task in workflow.get_tasks_from_spec_name('subprocess_end'):
self.assertEqual(task.data['task_num'], task.data['init_id'])
def testTwoCorrelationKeys(self):
specs = self.get_all_specs('correlation_two_conversations.bpmn')
proc_1 = specs['proc_1']
workflow = BpmnWorkflow(proc_1, specs)
workflow.do_engine_steps()
for idx, task in enumerate(workflow.get_ready_user_tasks()):
task.data['task_num'] = idx
task.run()
workflow.do_engine_steps()
# Two processes should have been started and two corresponding catch events should be waiting
ready_tasks = workflow.get_ready_user_tasks()
waiting = workflow.get_tasks_from_spec_name('get_response_one')
self.assertEqual(len(ready_tasks), 2)
self.assertEqual(len(waiting), 2)
for task in waiting:
self.assertEqual(task.state, TaskState.WAITING)
# Now copy the task_num that was sent into a new variable
for task in ready_tasks:
task.data.update(init_id=task.data['task_num'])
task.run()
workflow.do_engine_steps()
# Complete dummy tasks
for task in workflow.get_ready_user_tasks():
task.run()
workflow.do_engine_steps()
# Repeat for the other process, using a different mapped name
ready_tasks = workflow.get_ready_user_tasks()
waiting = workflow.get_tasks_from_spec_name('get_response_two')
self.assertEqual(len(ready_tasks), 2)
self.assertEqual(len(waiting), 2)
for task in ready_tasks:
task.data.update(subprocess=task.data['task_num'])
task.run()
workflow.do_engine_steps()
# If the messages were routed properly, the id should match
for task in workflow.get_tasks_from_spec_name('subprocess_end'):
self.assertEqual(task.data['task_num'], task.data['init_id'])
self.assertEqual(task.data['task_num'], task.data['subprocess'])
def testSerialization(self):
spec, subprocesses = self.load_collaboration('collaboration.bpmn', 'my_collaboration')
self.workflow = BpmnWorkflow(spec, subprocesses)
start = self.workflow.get_tasks_from_spec_name('Start')[0]
start.data['lover_name'] = 'Peggy'
self.workflow.do_engine_steps()
self.save_restore()