def test_init_with_arguments_with_routing(self):
     condition = Condition(
         'HelloWorld',
         action_name='mod1_flag2',
         arguments=[Argument('arg1', reference='action2')])
     self.__compare_init(condition, 'HelloWorld', 'mod1_flag2', [],
                         [Argument('arg1', reference="action2")])
    def test_execute_sends_callbacks(self):
        action = Action(app_name='HelloWorld',
                        action_name='Add Three',
                        name='helloWorld',
                        arguments=[
                            Argument('num1', value='-5.6'),
                            Argument('num2', value='4.3'),
                            Argument('num3', value='10.2')
                        ])
        instance = TestAction._make_app_instance()

        result = {'started_triggered': False, 'result_triggered': False}

        def callback_is_sent(sender, **kwargs):
            if isinstance(sender, Action):
                self.assertIn('event', kwargs)
                self.assertIn(kwargs['event'],
                              (WalkoffEvent.ActionStarted,
                               WalkoffEvent.ActionExecutionSuccess))
                if kwargs['event'] == WalkoffEvent.ActionStarted:
                    result['started_triggered'] = True
                else:
                    self.assertIn('data', kwargs)
                    data = kwargs['data']
                    self.assertEqual(data['status'], 'Success')
                    self.assertAlmostEqual(data['result'], 8.9)
                    result['result_triggered'] = True

        WalkoffEvent.CommonWorkflowSignal.connect(callback_is_sent)

        action.execute(LocalActionExecutionStrategy(), {}, instance.instance)
        self.assertTrue(result['started_triggered'])
        self.assertTrue(result['result_triggered'])
    def test_execute_default_return_success(self):
        action = Action(app_name='HelloWorld',
                        action_name='dummy action',
                        name='helloWorld',
                        arguments=[
                            Argument('status', value=True),
                            Argument('other', value=True)
                        ])
        instance = TestAction._make_app_instance()
        result = {'started_triggered': False, 'result_triggered': False}

        def callback_is_sent(sender, **kwargs):
            if isinstance(sender, Action):
                self.assertIn('event', kwargs)
                self.assertIn(kwargs['event'],
                              (WalkoffEvent.ActionStarted,
                               WalkoffEvent.ActionExecutionSuccess))
                if kwargs['event'] == WalkoffEvent.ActionStarted:
                    result['started_triggered'] = True
                else:
                    self.assertIn('data', kwargs)
                    data = kwargs['data']
                    self.assertEqual(data['status'], 'Success')
                    self.assertEqual(data['result'], None)
                    result['result_triggered'] = True

        WalkoffEvent.CommonWorkflowSignal.connect(callback_is_sent)

        action.execute(LocalActionExecutionStrategy(), {}, instance.instance)

        self.assertTrue(result['started_triggered'])
        self.assertTrue(result['result_triggered'])
 def test_validate_parameters_missing_required_without_default(self):
     parameter_apis = [{
         'name': 'name1',
         'type': 'string',
         'minLength': 1,
         'maxLength': 25,
         'enum': ['test', 'test3']
     }, {
         'name': 'name2',
         'type': 'integer',
         'minimum': -3,
         'maximum': 25
     }, {
         'name': 'name3',
         'type': 'number',
         'required': True,
         'minimum': -10.5,
         'maximum': 30.725
     }]
     arguments = [
         Argument('name1', value='test'),
         Argument('name2', value='5')
     ]
     with self.assertRaises(InvalidArgument):
         validate_parameters(parameter_apis, arguments, self.message)
    def test_execute_with_accumulator_missing_action_callbacks(self):
        action = Action(app_name='HelloWorld',
                        action_name='Add Three',
                        name='helloWorld',
                        arguments=[
                            Argument('num1', reference='1'),
                            Argument('num2', reference='action2'),
                            Argument('num3', value='10.2')
                        ])
        accumulator = {'1': '-5.6', 'missing': '4.3', '3': '45'}
        instance = TestAction._make_app_instance()

        result = {'started_triggered': False, 'result_triggered': False}

        def callback_is_sent(sender, **kwargs):
            if isinstance(sender, Action):
                self.assertIn('event', kwargs)
                self.assertIn(kwargs['event'],
                              (WalkoffEvent.ActionStarted,
                               WalkoffEvent.ActionArgumentsInvalid))
                if kwargs['event'] == WalkoffEvent.ActionStarted:
                    result['started_triggered'] = True
                else:
                    result['result_triggered'] = True

        WalkoffEvent.CommonWorkflowSignal.connect(callback_is_sent)
        action.execute(LocalActionExecutionStrategy(), accumulator,
                       instance.instance)

        self.assertTrue(result['started_triggered'])
        self.assertTrue(result['result_triggered'])
 def test_validate_parameters_missing_without_default(self):
     parameter_apis = [{
         'name': 'name1',
         'type': 'string',
         'minLength': 1,
         'maxLength': 25,
         'enum': ['test', 'test3']
     }, {
         'name': 'name2',
         'type': 'integer',
         'minimum': -3,
         'maximum': 25
     }, {
         'name': 'name3',
         'type': 'number',
         'minimum': -10.5,
         'maximum': 30.725
     }]
     arguments = [
         Argument('name1', value='test'),
         Argument('name2', value='5')
     ]
     expected = {'name1': 'test', 'name2': 5, 'name3': None}
     self.assertAlmostEqual(
         validate_parameters(parameter_apis, arguments, self.message),
         expected)
Exemple #7
0
    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_validate_parameters_skip_action_references_inputs_non_string(
         self):
     parameter_apis = [{
         'name': 'name1',
         'type': 'string',
         'minLength': 1,
         'maxLength': 25,
         'enum': ['test', 'test3']
     }, {
         'name': 'name2',
         'type': 'integer',
         'minimum': -3,
         'maximum': 25
     }, {
         'name': 'name3',
         'type': 'number',
         'required': True,
         'minimum': -10.5,
         'maximum': 30.725
     }]
     arguments = [
         Argument('name1', value='test'),
         Argument('name2', value=5),
         Argument('name3', reference='action1')
     ]
     expected = {'name1': 'test', 'name2': 5}
     self.assertDictEqual(
         validate_parameters(parameter_apis, arguments, self.message),
         expected)
Exemple #9
0
 def test_init_with_args(self):
     filter_elem = Transform('HelloWorld',
                             action_name='mod1_filter2',
                             arguments=[Argument('arg1', value='5.4')])
     self.__compare_init(filter_elem,
                         'HelloWorld',
                         'mod1_filter2',
                         arguments=[Argument('arg1', value='5.4')])
Exemple #10
0
 def test_execute_action_with_valid_arguments_and_transforms_invalid_data(self):
     transforms = [Transform('HelloWorld', action_name='mod1_filter2', arguments=[Argument('arg1', value='5')]),
                   Transform('HelloWorld', action_name='Top Transform')]
     # should go <input = invalid> -> <mod1_filter2 with error = invalid> -> <Top Transform with error = invalid>
     # -> <mod1_flag2 4+invalid throws error> -> False
     with self.assertRaises(InvalidArgument):
         Condition('HelloWorld', action_name='mod1_flag2', arguments=[Argument('arg1', value=4)],
                   transforms=transforms).execute('invalid', {})
Exemple #11
0
 def test_init_with_args_with_routing(self):
     filter_elem = Transform(
         'HelloWorld',
         action_name='mod1_filter2',
         arguments=[Argument('arg1', reference="action1")])
     self.__compare_init(filter_elem,
                         'HelloWorld',
                         'mod1_filter2',
                         arguments=[Argument('arg1', reference="action1")])
 def test_init_with_arguments_with_conversion(self):
     action = Action('HelloWorld',
                     'returnPlusOne',
                     'returnPlusOne',
                     arguments=[Argument('number', value='-5.6')])
     self.__compare_init(action,
                         'HelloWorld',
                         'returnPlusOne',
                         'returnPlusOne',
                         arguments=[Argument('number', value='-5.6')])
 def test_init_app_action_only_with_device(self):
     action = Action('HelloWorld',
                     'helloWorld',
                     'helloWorld',
                     device_id=Argument(name='__device__', value="test"))
     self.__compare_init(action,
                         'HelloWorld',
                         'helloWorld',
                         'helloWorld',
                         device_id=Argument(name='__device__',
                                            value="test"))
 def test_execute_with_accumulator_missing_action(self):
     action = Action(app_name='HelloWorld',
                     action_name='Add Three',
                     name='helloWorld',
                     arguments=[
                         Argument('num1', reference='1'),
                         Argument('num2', reference='action2'),
                         Argument('num3', value='10.2')
                     ])
     accumulator = {'1': '-5.6', 'missing': '4.3', '3': '45'}
     instance = TestAction._make_app_instance()
     action.execute(LocalActionExecutionStrategy(), accumulator,
                    instance.instance)
Exemple #15
0
 def test_execute_with_accumulator_missing_action(self):
     action = Action(app_name='HelloWorld',
                     action_name='Add Three',
                     name='helloWorld',
                     arguments=[
                         Argument('num1', reference='1'),
                         Argument('num2', reference='action2'),
                         Argument('num3', value='10.2')
                     ])
     accumulator = {'1': '-5.6', 'missing': '4.3', '3': '45'}
     instance = AppInstance.create(app_name='HelloWorld',
                                   device_name='device1')
     action.execute(instance.instance, accumulator)
Exemple #16
0
 def test_execute_with_args(self):
     action = Action(app_name='HelloWorld',
                     action_name='Add Three',
                     name='helloWorld',
                     arguments=[
                         Argument('num1', value='-5.6'),
                         Argument('num2', value='4.3'),
                         Argument('num3', value='10.2')
                     ])
     instance = AppInstance.create(app_name='HelloWorld',
                                   device_name='device1')
     result = action.execute(instance.instance, {})
     self.assertAlmostEqual(result.result, 8.9)
     self.assertEqual(result.status, 'Success')
     self.assertEqual(action._output, result)
 def test_execute_action_with_valid_arguments_and_transforms_valid_data(
         self):
     transforms = [
         Transform('HelloWorld',
                   action_name='mod1_filter2',
                   arguments=[Argument('arg1', value='5')]),
         Transform('HelloWorld', action_name='Top Transform')
     ]
     # should go <input = 1> -> <mod1_filter2 = 5+1 = 6> -> <Top Transform 6=6> -> <mod1_flag2 4+6%2==0> -> True
     self.assertTrue(
         Condition('HelloWorld',
                   action_name='mod1_flag2',
                   arguments=[Argument('arg1', value=4)],
                   transforms=transforms).execute(
                       LocalActionExecutionStrategy(), '1', {}))
 def test_execute_with_accumulator_with_extra_actions(self):
     action = Action(app_name='HelloWorld',
                     action_name='Add Three',
                     name='helloWorld',
                     arguments=[
                         Argument('num1', reference='1'),
                         Argument('num2', reference='action2'),
                         Argument('num3', value='10.2')
                     ])
     accumulator = {'1': '-5.6', 'action2': '4.3', '3': '45'}
     instance = TestAction._make_app_instance()
     result = action.execute(LocalActionExecutionStrategy(), accumulator,
                             instance.instance)
     self.assertAlmostEqual(accumulator[action.id], 8.9)
     self.assertEqual(result, 'Success')
 def test_execute_with_args(self):
     action = Action(app_name='HelloWorld',
                     action_name='Add Three',
                     name='helloWorld',
                     arguments=[
                         Argument('num1', value='-5.6'),
                         Argument('num2', value='4.3'),
                         Argument('num3', value='10.2')
                     ])
     instance = TestAction._make_app_instance()
     acc = {}
     result = action.execute(LocalActionExecutionStrategy(), acc,
                             instance.instance)
     self.assertAlmostEqual(acc[action.id], 8.9)
     self.assertEqual(result, 'Success')
Exemple #20
0
    def __func():
        data = request.get_json()
        workflows_in = set(data['execution_ids'])
        data_in = data['data_in']
        arguments = data['arguments'] if 'arguments' in data else []

        workflows_awaiting_data = set(
            current_app.running_context.executor.get_waiting_workflows())
        execution_ids = set.intersection(workflows_in, workflows_awaiting_data)

        user_id = get_jwt_identity()
        authorization_not_required, authorized_execution_ids = get_authorized_execution_ids(
            execution_ids, user_id,
            get_jwt_claims().get('roles', []))
        execution_ids = list(authorized_execution_ids
                             | authorization_not_required)
        completed_execution_ids = []

        arg_objects = []
        for arg in arguments:
            arg_objects.append(Argument(**arg))

        for execution_id in execution_ids:
            if current_app.running_context.executor.resume_trigger_step(
                    execution_id, data_in, arg_objects):
                completed_execution_ids.append(execution_id)
                log_action_taken_on_message(user_id, execution_id)

        return completed_execution_ids, SUCCESS
Exemple #21
0
    def receive_workflows(self):
        """Receives requests to execute workflows, and sends them off to worker threads"""
        logger.info('Starting workflow receiver')
        box = Box(self.key, self.server_key)
        while not self.exit:
            received_message = self.cache.rpop("request_queue")
            if received_message is not None:
                try:
                    decrypted_msg = box.decrypt(received_message)
                except CryptoError:
                    logger.error(
                        'Worker could not decrypt received workflow message')
                    continue
                try:
                    message = ExecuteWorkflowMessage()
                    message.ParseFromString(decrypted_msg)
                except DecodeError:
                    logger.error(
                        'Workflow could not decode received workflow message')
                else:
                    start = message.start if hasattr(message,
                                                     'start') else None

                    start_arguments = []
                    if hasattr(message, 'arguments'):
                        for arg in message.arguments:
                            start_arguments.append(
                                Argument(**(MessageToDict(
                                    arg, preserving_proto_field_name=True))))
                    yield message.workflow_id, message.workflow_execution_id, start, start_arguments, message.resume
            else:
                yield None
        raise StopIteration
Exemple #22
0
 def __update_arguments_with_data(self, data):
     arguments = []
     for argument in self.arguments:
         if argument.name != self._data_param_name:
             arguments.append(argument)
     arguments.append(Argument(self._data_param_name, value=data))
     return arguments
Exemple #23
0
    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)
Exemple #24
0
    def test_execute_return_failure(self):
        action = Action(app_name='HelloWorld',
                        action_name='dummy action',
                        name='helloWorld',
                        arguments=[Argument('status', value=False)])
        instance = AppInstance.create(app_name='HelloWorld',
                                      device_name='device1')
        result = {'started_triggered': False, 'result_triggered': False}

        def callback_is_sent(sender, **kwargs):
            if isinstance(sender, Action):
                self.assertIn('event', kwargs)
                self.assertIn(kwargs['event'],
                              (WalkoffEvent.ActionStarted,
                               WalkoffEvent.ActionExecutionError))
                if kwargs['event'] == WalkoffEvent.ActionStarted:
                    result['started_triggered'] = True
                else:
                    self.assertIn('data', kwargs)
                    data = kwargs['data']
                    self.assertEqual(data['status'], 'Failure')
                    self.assertEqual(data['result'], False)
                    result['result_triggered'] = True

        WalkoffEvent.CommonWorkflowSignal.connect(callback_is_sent)

        action.execute(instance.instance, {})
        self.assertTrue(result['started_triggered'])
        self.assertTrue(result['result_triggered'])
Exemple #25
0
 def test_execute_with_accumulator_with_extra_actions(self):
     action = Action(app_name='HelloWorld',
                     action_name='Add Three',
                     name='helloWorld',
                     arguments=[
                         Argument('num1', reference='1'),
                         Argument('num2', reference='action2'),
                         Argument('num3', value='10.2')
                     ])
     accumulator = {'1': '-5.6', 'action2': '4.3', '3': '45'}
     instance = AppInstance.create(app_name='HelloWorld',
                                   device_name='device1')
     result = action.execute(instance.instance, accumulator)
     self.assertAlmostEqual(result.result, 8.9)
     self.assertEqual(result.status, 'Success')
     self.assertEqual(action._output, result)
 def test_execute_with_complex_args(self):
     action = Action(app_name='HelloWorld',
                     action_name='Json Sample',
                     name='helloWorld',
                     arguments=[
                         Argument('json_in',
                                  value={
                                      '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 = TestAction._make_app_instance()
     acc = {}
     result = action.execute(LocalActionExecutionStrategy(), acc,
                             instance.instance)
     self.assertAlmostEqual(acc[action.id], 11.0)
     self.assertEqual(result, 'Success')
Exemple #27
0
 def test_execute_with_complex_args(self):
     action = Action(app_name='HelloWorld',
                     action_name='Json Sample',
                     name='helloWorld',
                     arguments=[
                         Argument('json_in',
                                  value={
                                      '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 = AppInstance.create(app_name='HelloWorld',
                                   device_name='device1')
     result = action.execute(instance.instance, {})
     self.assertAlmostEqual(result.result, 11.0)
     self.assertEqual(result.status, 'Success')
     self.assertEqual(action._output, result)
Exemple #28
0
 def test_execute_with_complex_args(self):
     original_filter = Transform(
         'HelloWorld',
         action_name='sub1_filter1',
         arguments=[Argument('arg1', value={'a': '5.4', 'b': 'string_in'})]
     )
     self.assertEqual(original_filter.execute(LocalActionExecutionStrategy(), 3, {}), '3.0 5.4 string_in')
Exemple #29
0
    def __func(workflow):
        if not workflow.is_valid:
            return Problem(INVALID_INPUT_ERROR, 'Cannot execute workflow',
                           'Workflow is invalid')
        args = data['arguments'] if 'arguments' in data else None
        start = data['start'] if 'start' in data else None

        arguments = []
        if args:
            errors = []
            arguments = [Argument(**arg) for arg in args]
            for argument in arguments:
                if argument.errors:
                    errors.append('Errors in argument {}: {}'.format(
                        argument.name, argument.errors))
            if errors:
                current_app.logger.error(
                    'Could not execute workflow. Invalid Argument construction'
                )
                return Problem(
                    INVALID_INPUT_ERROR, 'Cannot execute workflow.',
                    'Some arguments are invalid. Reason: {}'.format(errors))

        execution_id = current_app.running_context.executor.execute_workflow(
            workflow_id, start=start, start_arguments=arguments)
        current_app.logger.info('Executed workflow {0}'.format(workflow_id))
        return {'id': execution_id}, SUCCESS_ASYNC
Exemple #30
0
 def test_execute_with_args_with_conversion(self):
     self.assertAlmostEqual(
         Transform('HelloWorld',
                   action_name='mod1_filter2',
                   arguments=[Argument('arg1',
                                       value='10.3')]).execute(5.4, {}),
         15.7)