def test_error_workflow(self): workflow_name = construct_workflow_name_key( 'multistepError', 'multiactionErrorWorkflow') step_names = ['start', '1', 'error'] setup_subscriptions_for_step(workflow_name, step_names) self.controller.execute_workflow('multistepError', 'multiactionErrorWorkflow') shutdown_pool() steps = executed_steps('defaultController', workflow_name, self.start, datetime.utcnow()) self.assertEqual(len(steps), 2) names = [step['ancestry'].split(',')[-1] for step in steps] orderless_list_compare(self, names, ['start', 'error']) name_result = { 'start': { 'result': { "message": "HELLO WORLD" }, 'status': 'Success' }, 'error': { 'status': 'Success', 'result': 'REPEATING: Hello World' } } for step in steps: name = step['ancestry'].split(',')[-1] self.assertIn(name, name_result) result = json.loads(step['data']) self.assertDictEqual(result['result'], name_result[name])
def test_simple_tiered_workflow(self): workflow_name1 = construct_workflow_name_key('tieredWorkflow', 'parentWorkflow') workflow_name2 = construct_workflow_name_key('tieredWorkflow', 'childWorkflow') step_names = ['start', '1'] setup_subscriptions_for_step([workflow_name1, workflow_name2], step_names) self.controller.execute_workflow('tieredWorkflow', 'parentWorkflow') shutdown_pool() steps = executed_steps('defaultController', workflow_name1, self.start, datetime.utcnow()) steps.extend(executed_steps('defaultController', workflow_name2, self.start, datetime.utcnow())) ancestries = [step['ancestry'].split(',') for step in steps] name_ids = [(ancestry[-2], ancestry[-1]) for ancestry in ancestries] expected_ids = [(workflow_name1, 'start'), (workflow_name1, '1'), (workflow_name2, 'start')] orderless_list_compare(self, name_ids, expected_ids) name_result = {(workflow_name1, 'start'): {'status': 'Success', 'result': 'REPEATING: Parent Step One'}, (workflow_name2, 'start'): {'status': 'Success', 'result': 'REPEATING: Child Step One'}, (workflow_name1, '1'): {'status': 'Success', 'result': 'REPEATING: Parent Step Two'}} for step in steps: ancestry = step['ancestry'].split(',') name_id = (ancestry[-2], ancestry[-1]) self.assertIn(name_id, name_result) result = json.loads(step['data']) if type(name_result[name_id]) == dict: self.assertDictEqual(result['result'], name_result[name_id]) else: self.assertEqual(result['result'], name_result[name_id])
def test_workflow_with_dataflow(self): workflow_name = construct_workflow_name_key('dataflowTest', 'dataflowWorkflow') step_names = ['start', '1', '2'] setup_subscriptions_for_step(workflow_name, step_names) self.controller.execute_workflow('dataflowTest', 'dataflowWorkflow') shutdown_pool() steps = executed_steps('defaultController', workflow_name, self.start, datetime.utcnow()) self.assertEqual(len(steps), 3) names = [step['ancestry'].split(',')[-1] for step in steps] orderless_list_compare(self, names, ['start', '1', '2']) name_result = { 'start': { 'result': 6, 'status': 'Success' }, '1': { 'result': 6, 'status': 'Success' }, '2': { 'result': 15, 'status': 'Success' } } for step in steps: name = step['ancestry'].split(',')[-1] self.assertIn(name, name_result) result = json.loads(step['data']) self.assertDictEqual(result['result'], name_result[name])
def test_ffkExecutionEventsCase(self): c = Controller(name="testStepFFKEventsController") c.load_workflows_from_file(path=config.test_workflows_path + "basicWorkflowTest.playbook") workflow_name = construct_workflow_name_key('basicWorkflowTest', 'helloWorldWorkflow') filter_sub = Subscription(events=['Filter Error']) flag_sub = Subscription(events=['Flag Success', 'Flag Error'], subscriptions={'length': filter_sub}) next_sub = Subscription( events=['Next Step Taken', 'Next Step Not Taken'], subscriptions={'regMatch': flag_sub}) step_sub = Subscription(events=[ 'Function Execution Success', 'Input Validated', 'Conditionals Executed' ], subscriptions={'1': next_sub}) subs = { 'testStepFFKEventsController': Subscription( subscriptions={ workflow_name: Subscription( subscriptions={'start': step_sub}) }) } global_subs = case_subscription.GlobalSubscriptions( step=[ 'Function Execution Success', 'Input Validated', 'Conditionals Executed' ], next_step=['Next Step Taken', 'Next Step Not Taken'], flag=['Flag Success', 'Flag Error'], filter=['Filter Error']) case_subscription.set_subscriptions({ 'testStepFFKEventsEvents': case_subscription.CaseSubscriptions( subscriptions=subs, global_subscriptions=global_subs) }) c.execute_workflow('basicWorkflowTest', 'helloWorldWorkflow') shutdown_pool() step_ffk_events_case = case_database.case_db.session.query(case_database.Case) \ .filter(case_database.Case.name == 'testStepFFKEventsEvents').first() step_ffk_event_history = step_ffk_events_case.events.all() self.assertEqual( len(step_ffk_event_history), 5, 'Incorrect length of event history. ' 'Expected {0}, got {1}'.format(5, len(step_ffk_event_history))) step_json = [ step.as_json() for step in step_ffk_event_history if step.as_json()['message'] == 'STEP' ] for step in step_json: if step['type'] == 'Function executed successfully': self.assertDictEqual(step['data'], {'result': 'REPEATING: Hello World'}) else: self.assertEqual(step['data'], '')
def test_loop(self): from gevent import monkey, spawn from gevent.event import Event from core.case.callbacks import WorkflowShutdown monkey.patch_all() workflow_name = construct_workflow_name_key('loopWorkflow', 'loopWorkflow') step_names = ['start', '1'] setup_subscriptions_for_step(workflow_name, step_names) waiter = Event() def wait_for_shutdown(sender, **kwargs): waiter.set() WorkflowShutdown.connect(wait_for_shutdown) self.controller.execute_workflow('loopWorkflow', 'loopWorkflow') shutdown_pool() steps = executed_steps('defaultController', workflow_name, self.start, datetime.utcnow()) names = [step['ancestry'].split(',')[-1] for step in steps] expected_steps = ['start', 'start', 'start', 'start', '1'] self.assertListEqual(names, expected_steps) self.assertEqual(len(steps), 5) input_output = [('start', 1), ('start', 2), ('start', 3), ('start', 4), ('1', 'REPEATING: 5')] for step_name, output in input_output: for step in steps: name = step['ancestry'].split(',') if name == step_name: result = json.loads(step['data']) self.assertEqual(result['result'], output)
def test_workflowExecutionEvents(self): workflow_name = construct_workflow_name_key('multiactionWorkflowTest', 'multiactionWorkflow') c = Controller(name="testExecutionEventsController") c.load_workflows_from_file(path=config.test_workflows_path + "multiactionWorkflowTest.playbook") subs = { 'testExecutionEventsController': Subscription( subscriptions={ workflow_name: Subscription(events=[ "App Instance Created", "Step Execution Success", "Next Step Found", "Workflow Shutdown" ]) }) } case_subscription.set_subscriptions({ 'testExecutionEvents': case_subscription.CaseSubscriptions(subscriptions=subs) }) c.execute_workflow('multiactionWorkflowTest', 'multiactionWorkflow') shutdown_pool() execution_events_case = case_database.case_db.session.query(case_database.Case) \ .filter(case_database.Case.name == 'testExecutionEvents').first() execution_event_history = execution_events_case.events.all() self.assertEqual( len(execution_event_history), 6, 'Incorrect length of event history. ' 'Expected {0}, got {1}'.format(6, len(execution_event_history)))
def test_TemplatedWorkflow(self): workflow_name = construct_workflow_name_key('templatedWorkflowTest', 'templatedWorkflow') step_names = ['start', '1'] setup_subscriptions_for_step(workflow_name, step_names) self.controller.execute_workflow('templatedWorkflowTest', 'templatedWorkflow') shutdown_pool() steps = executed_steps('defaultController', workflow_name, self.start, datetime.utcnow()) self.assertEqual( len(steps), 2, 'Unexpected number of steps executed. ' 'Expected {0}, got {1}'.format(2, len(steps))) names = [step['ancestry'].split(',')[-1] for step in steps] orderless_list_compare(self, names, step_names) name_result = { 'start': { "message": "HELLO WORLD" }, '1': "REPEATING: {'message': 'HELLO WORLD'}" } for step in steps: name = step['ancestry'].split(',')[-1] self.assertIn(name, name_result) result = json.loads(step['data']) if type(name_result[name]) == dict: self.assertDictEqual(result['result'], name_result[name]) else: self.assertEqual(result['result'], name_result[name])
def test_workflow_with_dataflow_step_not_executed(self): workflow_name = construct_workflow_name_key('dataflowTest', 'dataflowWorkflow') step_names = ['start', '1'] setup_subscriptions_for_step(workflow_name, step_names) self.controller.execute_workflow('dataflowTest', 'dataflowWorkflow') shutdown_pool() steps = executed_steps('defaultController', workflow_name, self.start, datetime.utcnow()) self.assertEqual(len(steps), 2) names = [step['ancestry'].split(',')[-1] for step in steps] orderless_list_compare(self, names, ['start', '1'])
def test_simple_workflow_execution(self): workflow_name = construct_workflow_name_key('basicWorkflowTest', 'helloWorldWorkflow') setup_subscriptions_for_step(workflow_name, ['start']) self.controller.execute_workflow('basicWorkflowTest', 'helloWorldWorkflow') shutdown_pool() steps = executed_steps('defaultController', workflow_name, self.start, datetime.utcnow()) self.assertEqual(len(steps), 1) step = steps[0] ancestry = step['ancestry'].split(',') self.assertEqual(ancestry[-1], "start") result = json.loads(step['data']) self.assertEqual(result['result'], "REPEATING: Hello World")
def test_ffkExecutionEvents(self): workflow_name = construct_workflow_name_key('basicWorkflowTest', 'helloWorldWorkflow') c = Controller(name="testStepFFKEventsController") c.load_workflows_from_file(path=config.test_workflows_path + "basicWorkflowTest.playbook") filter_sub = Subscription(events=['Filter Success', 'Filter Error']) flag_sub = Subscription(events=['Flag Success', 'Flag Error'], subscriptions={'length': filter_sub}) next_sub = Subscription( events=['Next Step Taken', 'Next Step Not Taken'], subscriptions={'regMatch': flag_sub}) step_sub = Subscription(events=[ "Function Execution Success", "Input Validated", "Conditionals Executed" ], subscriptions={'1': next_sub}) subs = { 'testStepFFKEventsController': Subscription( subscriptions={ workflow_name: Subscription( subscriptions={'start': step_sub}) }) } case_subscription.set_subscriptions({ 'testStepFFKEventsEvents': case_subscription.CaseSubscriptions(subscriptions=subs) }) c.execute_workflow('basicWorkflowTest', 'helloWorldWorkflow') shutdown_pool() step_ffk_events_case = case_database.case_db.session.query(case_database.Case) \ .filter(case_database.Case.name == 'testStepFFKEventsEvents').first() step_ffk_event_history = step_ffk_events_case.events.all() self.assertEqual( len(step_ffk_event_history), 6, 'Incorrect length of event history. ' 'Expected {0}, got {1}'.format(6, len(step_ffk_event_history)))
def test_stepExecutionEvents(self): workflow_name = construct_workflow_name_key('basicWorkflowTest', 'helloWorldWorkflow') c = Controller(name="testStepExecutionEventsController") c.load_workflows_from_file(path=config.test_workflows_path + "basicWorkflowTest.playbook") subs = { 'testStepExecutionEventsController': Subscription( subscriptions={ workflow_name: Subscription( subscriptions={ 'start': Subscription(events=[ "Function Execution Success", "Input Validated", "Conditionals Executed" ]) }) }) } case_subscription.set_subscriptions({ 'testStepExecutionEvents': case_subscription.CaseSubscriptions(subscriptions=subs) }) c.execute_workflow('basicWorkflowTest', 'helloWorldWorkflow') shutdown_pool() step_execution_events_case = case_database.case_db.session.query(case_database.Case) \ .filter(case_database.Case.name == 'testStepExecutionEvents').first() step_execution_event_history = step_execution_events_case.events.all() self.assertEqual( len(step_execution_event_history), 3, 'Incorrect length of event history. ' 'Expected {0}, got {1}'.format(3, len(step_execution_event_history)))
def tearDownClass(cls): shutdown_pool()
def shutdown_threads(): """Shuts down the threadpool. """ from core.controller import shutdown_pool shutdown_pool()
def shutdown_threads(): from core.controller import shutdown_pool shutdown_pool()