def test_accumulated_risk_with_error(self): workflow = Workflow(name='workflow') step1 = Step(name="step_one", app='HelloWorld', action='Buggy', risk=1) step2 = Step(name="step_two", app='HelloWorld', action='Buggy', risk=2) step3 = Step(name="step_three", app='HelloWorld', action='Buggy', risk=3.5) workflow.steps = { 'step_one': step1, 'step_two': step2, 'step_three': step3 } workflow.total_risk = 6.5 instance = Instance.create(app_name='HelloWorld', device_name='test_device_name') workflow._Workflow__execute_step(workflow.steps["step_one"], instance) self.assertAlmostEqual(workflow.accumulated_risk, 1.0 / 6.5) workflow._Workflow__execute_step(workflow.steps["step_two"], instance) self.assertAlmostEqual(workflow.accumulated_risk, (1.0 / 6.5) + (2.0 / 6.5)) workflow._Workflow__execute_step(workflow.steps["step_three"], instance) self.assertAlmostEqual(workflow.accumulated_risk, 1.0)
def test_get_children(self): step = Step() names = ['step1', 'step2', 'step3'] for name in names: self.assertIsNone(step.get_children([name])) self.assertDictEqual(step.get_children([]), step.as_json(with_children=False)) next_steps = [ NextStep(name='name1'), NextStep(name='name2'), NextStep(name='name3') ] names = ['name1', 'name2', 'name3'] step = Step(next_steps=next_steps) for i, name in enumerate(names): self.assertDictEqual(step.get_children([name]), next_steps[i].as_json()) step = Step(errors=next_steps) for i, name in enumerate(names): self.assertDictEqual(step.get_children([name]), next_steps[i].as_json()) errors = [ NextStep(name='name1'), NextStep(name='error1'), NextStep(name='error2'), NextStep(name='name2') ] next_names = list(names) error_names = ['error1', 'error2'] all_names = list(next_names) all_names.extend(error_names) step = Step(next_steps=next_steps, errors=errors) for i, name in enumerate(all_names): if not name.startswith('error'): self.assertDictEqual(step.get_children([name]), next_steps[i].as_json()) else: self.assertDictEqual(step.get_children([name]), errors[i - 2].as_json()) flags = [Flag(), Flag(action='action1'), Flag(action='action2')] next_steps = [NextStep(name='name1', flags=flags)] names = ['', 'action1', 'action2'] step = Step(next_steps=next_steps) ancestries = [[name, 'name1'] for name in names] for i, ancestry in enumerate(ancestries): self.assertDictEqual(step.get_children(ancestry), flags[i].as_json())
def test_execute_with_complex_inputs(self): step = Step(app='HelloWorld', action='Json Sample', inputs={ 'json_in': { 'a': '-5.6', 'b': { 'a': '4.3', 'b': 5.3 }, 'c': ['1', '2', '3'], 'd': [{ 'a': '', 'b': 3 }, { 'a': '', 'b': -1.5 }, { 'a': '', 'b': -0.5 }] } }) instance = Instance.create(app_name='HelloWorld', device_name='device1') result = step.execute(instance.instance, {}) self.assertIsInstance(result, tuple) self.assertAlmostEqual(result.result, 11.0) self.assertEqual(result.status, 'Success') self.assertTupleEqual(step.output, result)
def test_execute_action_which_raises_exception(self): from tests.apps.HelloWorld.exceptions import CustomException step = Step(app='HelloWorld', action='Buggy') instance = Instance.create(app_name='HelloWorld', device_name='device1') with self.assertRaises(CustomException): step.execute(instance.instance, {})
def test_from_json(self): next_step_names = ['next1', 'next2'] error_names = ['error1', 'error2'] inputs = [{'name': 'name1', 'action': 'action1', 'app': 'app1', 'device': 'dev1', 'next': [], 'error': []}, {'name': 'name2', 'action': 'action2', 'app': 'app2', 'device': 'opt2', 'next': next_step_names, 'error': []}, {'name': 'name3', 'action': 'action3', 'app': 'app3', 'device': 'opt3', 'next': [], 'error': error_names}, {'name': 'name4', 'action': 'action4', 'app': 'app4', 'device': 'dev4', 'next': next_step_names, 'error': error_names}] for input_params in inputs: step = Step(name=input_params['name'], action=input_params['action'], app=input_params['app'], device=input_params['device']) step.conditionals = [NextStep(name=name, parent_name=step.name, ancestry=list(step.ancestry)) for name in input_params['next']] step.errors = [NextStep(name=name, parent_name=step.name, ancestry=list(step.ancestry)) for name in input_params['error']] step_json = step.as_json() derived_step = Step.from_json(step_json, parent_name=step.parent_name, ancestry=list(step.ancestry)[:-1]) self.assertDictEqual(derived_step.as_json(), step_json) self.assertEqual(step.parent_name, derived_step.parent_name) self.assertListEqual(step.ancestry, derived_step.ancestry) # check the ancestry of the next_steps original_next_step_ancestries = [list(next_step.ancestry) for next_step in step.conditionals] derived_next_step_ancestries = [list(next_step.ancestry) for next_step in derived_step.conditionals] self.assertEqual(len(original_next_step_ancestries), len(derived_next_step_ancestries)) for original_next_step_ancestry, derived_next_step_ancestry in zip(original_next_step_ancestries, derived_next_step_ancestries): self.assertListEqual(derived_next_step_ancestry, original_next_step_ancestry) # check the ancestry of the next_steps original_error_ancestries = [list(error.ancestry) for error in step.errors] derived_error_ancestries = [list(error.ancestry) for error in derived_step.errors] self.assertEqual(len(original_error_ancestries), len(derived_error_ancestries)) for original_error_ancestry, derived_error_ancestry in zip(original_error_ancestries, derived_error_ancestries): self.assertListEqual(derived_error_ancestry, original_error_ancestry)
def test_as_json_with_children_with_inputs(self): step = Step(app='HelloWorld', action='returnPlusOne', inputs={'number': '-5.6'}) self.basic_json['action'] = 'returnPlusOne' self.basic_json['input'] = {'number': -5.6} self.assertDictEqual(step.as_json(with_children=True), self.basic_json)
def test_init_with_name_and_parent_name(self): step = Step(app='HelloWorld', action='helloWorld', name='name', parent_name='parent') self.__compare_init(step, 'name', 'parent', 'helloWorld', 'HelloWorld', '', {}, [], ['parent', 'name'], [])
def createStep(self, id="", action="", app="", device="", input={}, next=[], errors=[]): # Creates new step object input = { input[key]["tag"]: arguments.Argument(key=input[key]["tag"], value=input[key]["value"], format=input[key]["format"]) for key in input } ancestry = list(self.ancestry) ancestry.append(id) self.steps[id] = Step(name=id, action=action, app=app, device=device, input=input, next=next, errors=errors, ancestry=ancestry, parent_name=self.name) stepXML = self.steps[id].to_xml() self.workflowXML.find(".//steps").append(stepXML)
def test_get_next_step_error_with_next_steps(self): flag1 = [ Flag(action='mod1_flag2', args={'arg1': '3'}), Flag(action='mod1_flag2', args={'arg1': '-1'}) ] flag2 = [ Flag(action='mod1_flag2', args={'arg1': '-1'}), Flag(action='mod1_flag2', args={'arg1': '3'}) ] next_steps = [ NextStep(flags=flag1, name='name1'), NextStep(name='name2') ] error_steps = [ NextStep(flags=flag2, name='error1'), NextStep(name='error2') ] step = Step(app='HelloWorld', action='helloWorld', next_steps=next_steps, errors=error_steps) step.output = 2 self.assertEqual(step.get_next_step({}, error=True), 'error2') step.output = 1 self.assertEqual(step.get_next_step({}, error=True), 'error1')
def test_execute_no_args(self): step = Step(app='HelloWorld', action='helloWorld') instance = Instance.create(app_name='HelloWorld', device_name='device1') self.assertDictEqual(step.execute(instance.instance, {}), {'message': 'HELLO WORLD'}) self.assertDictEqual(step.output, {'message': 'HELLO WORLD'})
def test_to_from_xml_with_next_steps(self): next_steps = [ NextStep(), NextStep(name='name'), NextStep(name='name2') ] self.__assert_xml_is_convertible( Step(app='HelloWorld', action='helloWorld', next_steps=next_steps))
def test_to_xml_with_position(self): step = Step(app='HelloWorld', action='helloWorld', position={ 'x': -12.3, 'y': 485 }) self.__check_xml(step, position={'x': '-12.3', 'y': '485'})
def test_as_json_with_children_with_widgets(self): widgets = [('aaa', 'bbb'), ('ccc', 'ddd'), ('eee', 'fff')] step = Step(app='HelloWorld', action='helloWorld', widgets=widgets) self.basic_json['widgets'] = [{ 'app': widget[0], 'name': widget[1] } for widget in widgets] self.assertDictEqual(step.as_json(with_children=True), self.basic_json)
def test_as_json_without_children_with_input_routing(self): step = Step(app='HelloWorld', action='returnPlusOne', inputs={'number': '@step1'}) self.basic_json['action'] = 'returnPlusOne' self.basic_json['input'] = {'number': '@step1'} self.assertDictEqual(step.as_json(with_children=False), self.basic_json)
def test_get_children_next_not_found(self): next_steps = [NextStep(name='name1'), NextStep(name='name2')] error_steps = [NextStep(name='error1'), NextStep(name='error2')] step = Step(app='HelloWorld', action='helloWorld', next_steps=next_steps, errors=error_steps) self.assertIsNone(step.get_children(['invalid']))
def test_to_from_xml_with_position(self): self.__assert_xml_is_convertible( Step(app='HelloWorld', action='helloWorld', position={ 'x': '-12.3', 'y': '485' }))
def test_function_alias_lookup_invalid(self): app = 'HelloWorld' action = 'JunkAction1' step = Step(action=action, app=app) assert_raises_with_error( self, InvalidStepActionError, 'Error: Step action {0} not found for app {1}'.format(action, app), step._Step__lookup_function)
def test_function_alias_lookup(self): app = 'HelloWorld' function_aliases = load_function_aliases(app) self.assertIsNotNone(function_aliases) for function, aliases in function_aliases.items(): for alias in aliases: step = Step(action=alias, app=app) self.assertEqual(step._Step__lookup_function(), function)
def test_get_children_duplicate_in_both_next_steps_and_error(self): next_steps = [NextStep(name='name1'), NextStep(name='name2')] error_steps = [NextStep(name='name1'), NextStep(name='error2')] step = Step(app='HelloWorld', action='helloWorld', next_steps=next_steps, errors=error_steps) self.assertDictEqual(step.get_children(['name1']), next_steps[0].as_json(with_children=False))
def _from_xml(self, xml_element, *args): self.options = options.Options(xml=xml_element.find(".//options"), workflow_name=self.name) self.steps = {} for step_xml in xml_element.findall(".//steps/*"): step = Step(xml=step_xml, parent_name=self.name, ancestry=self.ancestry) self.steps[step.name] = step
def test_init_with_risk(self): step = Step(app='HelloWorld', action='helloWorld', risk=42.3) self.__compare_init(step, '', '', 'helloWorld', 'HelloWorld', '', {}, [], ['', ''], [], risk=42.3)
def test_as_json_with_children_with_position(self): step = Step(app='HelloWorld', action='helloWorld', position={ 'x': -12.3, 'y': 485 }) self.basic_json['position'] = {'x': -12.3, 'y': 485} self.assertDictEqual(step.as_json(with_children=True), self.basic_json)
def test_name_parent_rename(self): step = Step(app='HelloWorld', action='helloWorld', ancestry=['step_parent'], name='step') new_ancestry = ['step_parent_update'] step.reconstruct_ancestry(new_ancestry) new_ancestry.append('step') self.assertListEqual(new_ancestry, step.ancestry)
def test_get_children_in_next_step(self): next_steps = [NextStep(name='name1'), NextStep(name='name2')] step = Step(app='HelloWorld', action='helloWorld', next_steps=next_steps) self.assertDictEqual(step.get_children(['name1']), next_steps[0].as_json(with_children=False)) self.assertDictEqual(step.get_children(['name2']), next_steps[1].as_json(with_children=False))
def test_to_from_xml_with_inputs(self): self.__assert_xml_is_convertible( Step(app='HelloWorld', action='Add Three', inputs={ 'num1': '-5.6', 'num2': '4.3', 'num3': '-10.265' }))
def test_name_parent_multiple_step_rename(self): workflow = controller.wf.Workflow(parent_name='workflow_parent', name='workflow') step_one = Step(name="test_step_one", ancestry=workflow.ancestry) step_two = Step(name="test_step_two", ancestry=workflow.ancestry) workflow.steps["test_step_one"] = step_one workflow.steps["test_step_two"] = step_two new_ancestry = ["workflow_parent_update"] workflow.reconstruct_ancestry(new_ancestry) new_ancestry.append("workflow") new_ancestry.append("test_step_one") self.assertListEqual(new_ancestry, workflow.steps["test_step_one"].ancestry) new_ancestry.remove("test_step_one") new_ancestry.append("test_step_two") self.assertListEqual(new_ancestry, workflow.steps["test_step_two"].ancestry)
def test_name_parent_nextstep_rename_error(self): step = Step(ancestry=['step_parent'], name='step') nextstep = NextStep(name="test_nextstep", ancestry=step.ancestry) step.errors = [nextstep] new_ancestry = ["step_parent_update"] step.reconstruct_ancestry(new_ancestry) new_ancestry.append("step") new_ancestry.append("test_nextstep") self.assertListEqual(new_ancestry, step.errors[0].ancestry)
def test_get_next_step_with_errors(self): flags1 = [ Flag(action='regMatch', args={ 'regex': Argument(key='regex', value='(.*)', format='str') }) ] flags2 = [ Flag(action='regMatch', args={ 'regex': Argument(key='regex', value='(.*)', format='str') }), Flag( action='regMatch', args={'regex': Argument(key='regex', value='a', format='str')}) ] next_step1 = NextStep(name='name1', flags=flags1) next_step2 = NextStep(name='name2', flags=flags2) step1 = Step(next_steps=[next_step2, next_step1], errors=[]) step1.output = 'aaaa' self.assertEqual(step1.get_next_step(), next_step2.name) self.assertEqual(step1.next_up, next_step2.name) step1.output = 'aaa' self.assertIsNone(step1.get_next_step(error=True)) self.assertEqual(step1.next_up, next_step2.name) step2 = Step(next_steps=[next_step1], errors=[next_step2]) step2.output = 'bbbb' self.assertEqual(step2.get_next_step(), next_step1.name) step2.output = 'aaa' self.assertEqual(step2.get_next_step(error=True), next_step2.name) self.assertEqual(step2.next_up, next_step2.name) step3 = Step(next_steps=[], errors=[next_step2, next_step1]) self.assertIsNone(step3.get_next_step()) step3.output = 'bbbbb' self.assertEqual(step3.get_next_step(error=True), next_step1.name) self.assertEqual(step3.next_up, next_step1.name) step3.output = 'aaa' self.assertEqual(step3.get_next_step(error=True), next_step2.name) self.assertEqual(step3.next_up, next_step2.name)
def test_set_input_invalid_format(self): step = Step(app='HelloWorld', action='Add Three', inputs={ 'num1': '-5.6', 'num2': '4.3', 'num3': '10.2' }) with self.assertRaises(InvalidInput): step.set_input({'num1': '-5.62', 'num2': '5', 'num3': 'invalid'})
def test_to_xml_with_next_steps(self): next_steps = [ NextStep(), NextStep(name='name'), NextStep(name='name2') ] step = Step(app='HelloWorld', action='helloWorld', next_steps=next_steps) self.__check_xml(step, next_steps=next_steps)