def test_execute_xor_conditions_only(self): expression = ConditionalExpression( operator='xor', conditions=[self.get_regex_condition('bb'), self.get_regex_condition('aa')]) for true_pattern in ('aa', 'bb'): self.assertTrue(expression.execute(LocalActionExecutionStrategy(), true_pattern, {})) for false_pattern in ('aabb', 'cc'): self.assertFalse(expression.execute(LocalActionExecutionStrategy(), false_pattern, {}))
def test_execute(self): condition1 = ConditionalExpression( 'and', conditions=[ Condition('HelloWorld', action_name='regMatch', arguments=[Argument('regex', value='(.*)')]) ]) condition2 = ConditionalExpression( 'and', conditions=[ Condition('HelloWorld', action_name='regMatch', arguments=[Argument('regex', value='(.*)')]), Condition('HelloWorld', action_name='regMatch', arguments=[Argument('regex', value='a')]) ]) inputs = [('name1', None, ActionResult('aaaa', 'Success'), True), ('name2', condition1, ActionResult('anyString', 'Success'), True), ('name3', condition2, ActionResult('anyString', 'Success'), True), ('name4', condition2, ActionResult('bbbb', 'Success'), False), ('name4', condition2, ActionResult('aaaa', 'Custom'), False)] for name, condition, input_str, expect_name in inputs: branch = Branch(source_id=1, destination_id=2, condition=condition) if expect_name: expected_name = branch.destination_id self.assertEqual(branch.execute(input_str, {}), expected_name) else: self.assertIsNone(branch.execute(input_str, {}))
def test_read_does_not_infinitely_recurse(self): expression = ConditionalExpression( operator='xor', conditions=[self.get_regex_condition('aa')], child_expressions=[ ConditionalExpression(conditions=[self.get_regex_condition('bb')]), ConditionalExpression(conditions=[self.get_regex_condition('cc')])]) dump_element(expression)
def test_execute_error_sends_event(self): expression = ConditionalExpression(conditions=[Condition('HelloWorld', 'mod1_flag1')]) result = {'triggered': False} @WalkoffEvent.CommonWorkflowSignal.connect def callback_is_sent(sender, **kwargs): if isinstance(sender, ConditionalExpression): self.assertIn('event', kwargs) self.assertEqual(kwargs['event'], WalkoffEvent.ConditionalExpressionFalse) result['triggered'] = True self.assertFalse(expression.execute(LocalActionExecutionStrategy(), 'any', {})) self.assertTrue(result['triggered'])
def test_execute_false_sends_event(self): expression = ConditionalExpression(conditions=[self.get_always_true_condition()], is_negated=True) result = {'triggered': False} @WalkoffEvent.CommonWorkflowSignal.connect def callback_is_sent(sender, **kwargs): if isinstance(sender, ConditionalExpression): self.assertIn('event', kwargs) self.assertEqual(kwargs['event'], WalkoffEvent.ConditionalExpressionFalse) result['triggered'] = True expression.execute(LocalActionExecutionStrategy(), '3.4', {}) self.assertTrue(result['triggered'])
def convert_branch(branch, action_map): condition = None if 'conditions' in branch and len(branch['conditions']) > 0: condition = ConditionalExpression() for cond in branch['conditions']: condition.conditions.append(convert_condition(cond)) status = branch['status'] if 'status' in branch else None priority = branch['priority'] if 'priority' in branch else 999 if branch['source_uid'] in action_map: source_id = action_map[branch['source_uid']] else: print("Source ID not found in actions, skipping branch") return None if branch['destination_uid'] in action_map: destination_id = action_map[branch['destination_uid']] else: print("Destination ID not found in actions, skipping branch") return None branch_obj = Branch(source_id=source_id, destination_id=destination_id, status=status, condition=condition, priority=priority) return branch_obj
def convert_action(action, action_map): uid = action.pop('uid') try: action_id = uuid.UUID(uid) action_map[uid] = action_id except Exception: print("Action UID is not valid UUID, creating new UID") action_id = uuid.uuid4() action_map[uid] = action_id arguments = [] if 'arguments' in action: for argument in action['arguments']: arguments.append(convert_arg(argument)) trigger = None if 'triggers' in action and len(action['triggers']) > 0: trigger = ConditionalExpression() for trig in action['triggers']: trigger.conditions.append(convert_condition(trig)) name = action['name'] if 'name' in action else action['action_name'] device_id = action['device_id'] if 'device_id' in action else None x = None y = None if 'position' in action and action['position']: x = action['position']['x'] y = action['position']['y'] position = Position(x, y) if x and y else None action_obj = Action(id=action_id, app_name=action['app_name'], action_name=action['action_name'], name=name, device_id=device_id, position=position, arguments=arguments, trigger=trigger) return action_obj
def test_branch_with_priority(self): action = Action('HelloWorld', 'helloWorld', 'helloWorld', id=10) action2 = Action('HelloWorld', 'helloWorld', 'helloWorld', id=5) action3 = Action('HelloWorld', 'helloWorld', 'helloWorld', id=1) condition = ConditionalExpression( 'and', conditions=[ Condition('HelloWorld', action_name='regMatch', arguments=[Argument('regex', value='aaa')]) ]) branch_one = Branch(source_id=action.id, destination_id=5, condition=condition, priority=5) branch_two = Branch(source_id=action.id, destination_id=1, condition=condition, priority=1) action_result = ActionResult(result='aaa', status='Success') workflow = Workflow('test', 1, actions=[action, action2, action3], branches=[branch_one, branch_two]) wf_ctx = WorkflowExecutionContext(workflow, {}, None, None) wf_ctx.accumulator[action.id] = action_result.result wf_ctx.last_status = action_result.status wf_ctx.executing_action = action self.assertEqual( Executor.get_branch(wf_ctx, LocalActionExecutionStrategy()), 1)
def test_branch_with_priority(self): action = Action('HelloWorld', 'helloWorld', 'helloWorld', id=10) action2 = Action('HelloWorld', 'helloWorld', 'helloWorld', id=5) action3 = Action('HelloWorld', 'helloWorld', 'helloWorld', id=1) condition = ConditionalExpression( 'and', conditions=[ Condition('HelloWorld', action_name='regMatch', arguments=[Argument('regex', value='aaa')]) ]) branch_one = Branch(source_id=action.id, destination_id=5, condition=condition, priority=5) branch_two = Branch(source_id=action.id, destination_id=1, condition=condition, priority=1) action._output = ActionResult(result='aaa', status='Success') workflow = Workflow('test', 1, actions=[action, action2, action3], branches=[branch_one, branch_two]) self.assertEqual(workflow.get_branch(action, {}), 1)
def test_get_branch(self): action = Action('HelloWorld', 'helloWorld', 'helloWorld', id=10) action2 = Action('HelloWorld', 'helloWorld', 'helloWorld', id=2) condition = ConditionalExpression( 'and', conditions=[ Condition('HelloWorld', action_name='regMatch', arguments=[Argument('regex', value='aaa')]) ]) branch = Branch(source_id=action.id, destination_id=2, condition=condition) action._output = ActionResult(result='aaa', status='Success') workflow = Workflow("helloWorld", action.id, actions=[action, action2], branches=[branch]) result = {'triggered': False} def validate_sent_data(sender, **kwargs): if isinstance(sender, Branch): self.assertIn('event', kwargs) self.assertEqual(kwargs['event'], WalkoffEvent.BranchTaken) result['triggered'] = True WalkoffEvent.CommonWorkflowSignal.connect(validate_sent_data) self.assertEqual(workflow.get_branch(action, {}), 2) self.assertTrue(result['triggered'])
def test_execute(self): class MockAction(object): id = 13 condition1 = ConditionalExpression( 'and', conditions=[ Condition('HelloWorld', action_name='regMatch', arguments=[Argument('regex', value='(.*)')]) ]) condition2 = ConditionalExpression( 'and', conditions=[ Condition('HelloWorld', action_name='regMatch', arguments=[Argument('regex', value='(.*)')]), Condition('HelloWorld', action_name='regMatch', arguments=[Argument('regex', value='a')]) ]) inputs = [('name1', None, ActionResult('aaaa', 'Success'), True), ('name2', condition1, ActionResult('anyString', 'Success'), True), ('name3', condition2, ActionResult('anyString', 'Success'), True), ('name4', condition2, ActionResult('bbbb', 'Success'), False), ('name4', condition2, ActionResult('aaaa', 'Custom'), False)] for name, condition, previous_result, expect_name in inputs: branch = Branch(source_id=1, destination_id=2, condition=condition) acc = {MockAction.id: previous_result.result} status = previous_result.status action = MockAction() if expect_name: expected_name = branch.destination_id self.assertEqual( branch.execute(LocalActionExecutionStrategy(), status, action, acc), expected_name) else: self.assertIsNone( branch.execute(LocalActionExecutionStrategy(), status, action, acc))
def test_init_with_conditions(self): condition = ConditionalExpression( 'and', conditions=[ Condition('HelloWorld', 'Top Condition'), Condition('HelloWorld', 'mod1_flag1') ]) branch = Branch(1, 2, condition=condition) self.__compare_init(branch, 1, 2, condition=condition)
def test_get_branch_invalid_action(self): condition = ConditionalExpression( 'and', conditions=[ Condition('HelloWorld', action_name='regMatch', arguments=[Argument('regex', value='aaa')]) ]) branch = Branch(source_id=1, destination_id=2, condition=condition) action = Action('HelloWorld', 'helloWorld', 'helloWorld') action._output = ActionResult(result='bbb', status='Success') with self.assertRaises(InvalidExecutionElement): Workflow('test', 1, actions=[action], branches=[branch])
def test_execute_and_expressions_only(self): expression = ConditionalExpression( child_expressions=[ ConditionalExpression(conditions=[self.get_regex_condition('aa')]), ConditionalExpression(conditions=[self.get_regex_condition('bb')])]) self.assertTrue(expression.execute(LocalActionExecutionStrategy(), 'aabb', {})) for false_pattern in ('aa', 'bb', 'cc'): self.assertFalse(expression.execute(LocalActionExecutionStrategy(), false_pattern, {}))
def test_execute_and_with_conditions_and_expressions(self): expression = ConditionalExpression( conditions=[self.get_regex_condition('aa')], child_expressions=[ ConditionalExpression(conditions=[self.get_regex_condition('bb')]), ConditionalExpression(conditions=[self.get_regex_condition('cc')])]) self.assertTrue(expression.execute('aabbcc', {})) for false_pattern in ('aa', 'bb', 'cc', 'dd'): self.assertFalse(expression.execute(false_pattern, {}))
def test_execute_or_expressions_only(self): expression = ConditionalExpression( operator='or', child_expressions=[ ConditionalExpression(conditions=[self.get_regex_condition('aa')]), ConditionalExpression(conditions=[self.get_regex_condition('bb')])]) for true_pattern in ('aa', 'bb', 'aabb'): self.assertTrue(expression.execute(true_pattern, {})) self.assertFalse(expression.execute('ccc', {}))
def test_execute_with_triggers(self): trigger = ConditionalExpression( 'and', conditions=[ Condition('HelloWorld', action_name='regMatch', arguments=[Argument('regex', value='aaa')]) ]) action = Action(app_name='HelloWorld', action_name='helloWorld', name='helloWorld', trigger=trigger) ret = action.execute_trigger({"data_in": {"data": 'aaa'}}, {}) self.assertTrue(ret)
def test_execute_or_with_conditions_and_expressions(self): expression = ConditionalExpression( operator='or', conditions=[self.get_regex_condition('aa')], child_expressions=[ ConditionalExpression(conditions=[self.get_regex_condition('bb')]), ConditionalExpression(conditions=[self.get_regex_condition('cc')])]) for true_pattern in ('aa', 'bb', 'cc', 'aabb', 'bbcc', 'aacc'): self.assertTrue(expression.execute(LocalActionExecutionStrategy(), true_pattern, {})) self.assertFalse(expression.execute(LocalActionExecutionStrategy(), 'd', {}))
def test_eq(self): condition = ConditionalExpression( 'and', conditions=[ Condition('HelloWorld', 'mod1_flag1'), Condition('HelloWorld', 'Top Condition') ]) branches = [ Branch(source_id=1, destination_id=2), Branch(source_id=1, destination_id=2, status='TestStatus'), Branch(source_id=1, destination_id=2, condition=condition) ] for i in range(len(branches)): for j in range(len(branches)): if i == j: self.assertEqual(branches[i], branches[j]) else: self.assertNotEqual(branches[i], branches[j])
def test_execute_multiple_triggers(self): trigger = ConditionalExpression( 'and', conditions=[ Condition('HelloWorld', action_name='regMatch', arguments=[Argument('regex', value='aaa')]) ]) action = Action(app_name='HelloWorld', action_name='helloWorld', name='helloWorld', trigger=trigger) AppInstance.create(app_name='HelloWorld', device_name='device1') self.assertFalse(action.execute_trigger({"data_in": { "data": 'a' }}, {})) self.assertTrue( action.execute_trigger({"data_in": { "data": 'aaa' }}, {}))
def test_init_with_triggers(self): trigger = ConditionalExpression( 'and', conditions=[ Condition('HelloWorld', action_name='regMatch', arguments=[Argument('regex', value='(.*)')]), Condition('HelloWorld', action_name='regMatch', arguments=[Argument('regex', value='a')]) ]) action = Action('HelloWorld', 'helloWorld', 'helloWorld', trigger=trigger) self.__compare_init(action, 'HelloWorld', 'helloWorld', 'helloWorld', trigger=trigger)
def test_execute_multiple_triggers(self): trigger = ConditionalExpression( 'and', conditions=[ Condition('HelloWorld', action_name='regMatch', arguments=[Argument('regex', value='aaa')]) ]) action = Action(app_name='HelloWorld', action_name='helloWorld', name='helloWorld', trigger=trigger) TestAction._make_app_instance() self.assertFalse( action.execute_trigger(LocalActionExecutionStrategy(), {"data_in": { "data": 'a' }}, {})) self.assertTrue( action.execute_trigger(LocalActionExecutionStrategy(), {"data_in": { "data": 'aaa' }}, {}))
def test_get_branch(self): action = Action('HelloWorld', 'helloWorld', 'helloWorld', id=10) action2 = Action('HelloWorld', 'helloWorld', 'helloWorld', id=2) condition = ConditionalExpression( 'and', conditions=[ Condition('HelloWorld', action_name='regMatch', arguments=[Argument('regex', value='aaa')]) ]) branch = Branch(source_id=action.id, destination_id=2, condition=condition) action_result = ActionResult(result='aaa', status='Success') workflow = Workflow("helloWorld", action.id, actions=[action, action2], branches=[branch]) wf_ctx = WorkflowExecutionContext(workflow, {}, None, None) wf_ctx.accumulator[action.id] = action_result.result wf_ctx.last_status = action_result.status wf_ctx.executing_action = action result = {'triggered': False} def validate_sent_data(sender, **kwargs): if isinstance(sender, Branch): self.assertIn('event', kwargs) self.assertEqual(kwargs['event'], WalkoffEvent.BranchTaken) result['triggered'] = True WalkoffEvent.CommonWorkflowSignal.connect(validate_sent_data) self.assertEqual( Executor.get_branch(wf_ctx, LocalActionExecutionStrategy()), 2) self.assertTrue(result['triggered'])
def test_execute_and_conditions_only(self): expression = ConditionalExpression(conditions=[self.get_regex_condition(), self.get_regex_condition('aa')]) self.assertTrue(expression.execute(LocalActionExecutionStrategy(), 'aaa', {})) self.assertFalse(expression.execute(LocalActionExecutionStrategy(), 'bbb', {}))
def test_execute_inverted(self): expression = ConditionalExpression(is_negated=True) self.assertFalse(expression.execute(LocalActionExecutionStrategy(), '', {}))
def test_execute_no_conditions(self): for operator in ('and', 'or', 'xor'): expression = ConditionalExpression(operator=operator) self.assertTrue(expression.execute(LocalActionExecutionStrategy(), '', {}))
def test_init_with_child_expressions(self): children = [ConditionalExpression() for _ in range(3)] expression = ConditionalExpression(child_expressions=children) self.assert_construction(expression, child_expressions=children)
def test_init_with_conditions(self): conditions = [self.get_always_true_condition(), Condition('HelloWorld', 'mod1_flag1')] expression = ConditionalExpression(operator='or', conditions=conditions) self.assert_construction(expression, operator='or', conditions=conditions)
def test_init_inverted(self): expression = ConditionalExpression(is_negated=True) self.assert_construction(expression, is_negated=True)
def test_init_with_operator(self): expression = ConditionalExpression(operator='or') self.assert_construction(expression, operator='or')