示例#1
0
    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'])
示例#2
0
    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_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")])
示例#4
0
 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)
示例#5
0
 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)
示例#6
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, {}))
示例#7
0
 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)
示例#8
0
    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'])
示例#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')])
示例#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', {})
示例#11
0
 def test_get_action_from_reference(self):
     arg = Argument('test', reference='a')
     self.assertEqual(
         arg._get_action_from_reference({
             'a': 1,
             'b': 3,
             'c': 7
         }), 1)
示例#12
0
 def test_get_value_reference_and_selection(self):
     arg = Argument('test', reference='a', selection=['a', 0, '1', 'b'])
     input_ = {'a': [[{'one': 1},
                      {'three': 3, 'b': 4}],
                     [{'one': 1}, {'two': 2}]],
               'b': 15,
               'c': 'something'}
     self.assertEqual(arg.get_value({'a': input_, 'b': 2}), 4)
示例#13
0
 def test_select(self):
     arg = Argument('test', reference='some_id', selection=['a', 0, '1', 'b'])
     input_ = {'a': [[{'one': 1},
                      {'three': 3, 'b': 4}],
                     [{'one': 1}, {'two': 2}]],
               'b': 15,
               'c': 'something'}
     self.assertEqual(arg._select(input_), 4)
示例#14
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")])
示例#15
0
 def test_select_selection_too_deep(self):
     arg = Argument('test', reference='some_id', selection=['a', 0, '1', 'b', 10])
     input_ = {'a': [[{'one': 1},
                      {'three': 3, 'b': 4}],
                     [{'one': 1}, {'two': 2}]],
               'b': 15,
               'c': 'something'}
     with self.assertRaises(InvalidArgument):
         arg._select(input_)
示例#16
0
 def test_get_value_reference_and_bad_selection(self):
     arg = Argument('test', reference='a', selection=['a', 0, '1', 'invalid'])
     input_ = {'a': [[{'one': 1},
                      {'three': 3, 'b': 4}],
                     [{'one': 1}, {'two': 2}]],
               'b': 15,
               'c': 'something'}
     with self.assertRaises(InvalidArgument):
         arg.get_value({'a': input_, 'b': 2})
示例#17
0
 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')])
示例#18
0
 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"))
示例#19
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)
示例#20
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 = TestAction._make_app_instance()
     action.execute(LocalActionExecutionStrategy(), accumulator,
                    instance.instance)
示例#21
0
 def test_update_value_reference_from_value(self):
     input_output = {
         (None, None): (42, None),
         (43, None): (43, None),
         (42, None): (42, None),
         (43, 'a'): (43, None),
         (None, 'a'): (None, 'a'),
         (42, 'a'): (None, 'a')
     }
     for inputs, outputs in input_output.items():
         arg = Argument('test', value=42)
         arg.update_value_reference(*inputs)
         self.assertEqual(arg.value, outputs[0])
         self.assertEqual(arg.reference, outputs[1])
示例#22
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 = TestAction._make_app_instance()
     acc = {}
     result = action.execute(LocalActionExecutionStrategy(), acc,
                             instance.instance)
     self.assertAlmostEqual(acc[action.id], 8.9)
     self.assertEqual(result, 'Success')
示例#23
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)
示例#24
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 = 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_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', {}))
示例#26
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 = TestAction._make_app_instance()
     acc = {}
     result = action.execute(LocalActionExecutionStrategy(), acc,
                             instance.instance)
     self.assertAlmostEqual(acc[action.id], 11.0)
     self.assertEqual(result, 'Success')
示例#27
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)
示例#28
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
示例#29
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
示例#30
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
示例#31
0
 def test_update_value_reference_from_reference(self):
     input_output = {
         (None, None): (None, 'a'),
         (None, 'b'): (None, 'b'),
         (None, 'a'): (None, 'a'),
         (None, ''): (None, 'a'),
         (42, None): (42, None),
         (42, 'a'): (42, None),
         (42, ''): (42, None)
     }
     for inputs, outputs in input_output.items():
         arg = Argument('test', reference='a', selection=[1, 'a'])
         arg.update_value_reference(*inputs)
         self.assertEqual(arg.value, outputs[0])
         self.assertEqual(arg.reference, outputs[1])
         if outputs[1] is None:
             self.assertListEqual(arg.selection, [])
示例#32
0
 def test_select_one_on_dict(self):
     arg = Argument('test', reference='some_id', selection=['b'])
     self.assertEqual(arg._select({'a': 1, 'b': 2, 'c': 3}), 2)
示例#33
0
 def test_select_one_on_list(self):
     arg = Argument('test', reference='some_id', selection=[1])
     self.assertEqual(arg._select(['a', 'b', 'c']), 'b')
示例#34
0
 def test_select_one_on_list_out_of_range(self):
     arg = Argument('test', reference='some_id', selection=[10])
     with self.assertRaises(InvalidArgument):
         arg._select(['a', 'b', 'c'])
示例#35
0
 def test_get_next_selection_str_index_on_list(self):
     self.assertEqual(Argument._get_next_selection(['a', 1, '2', 'something'], '3'), 'something')
示例#36
0
 def test_get_next_selection_index_on_list_out_of_bounds(self):
     with self.assertRaises(IndexError):
         Argument._get_next_selection(['a', 1, '2', 'something'], 10)
示例#37
0
 def test_get_next_selection_key_on_value(self):
     with self.assertRaises(ValueError):
         Argument._get_next_selection('something', 'a')
示例#38
0
 def test_get_next_selection_index_on_dict(self):
     with self.assertRaises(KeyError):
         Argument._get_next_selection({'a': 1, '2': 'something'}, 3)
示例#39
0
 def test_get_action_from_reference(self):
     arg = Argument('test', reference='a')
     self.assertEqual(arg._get_action_from_reference({'a': 1, 'b': 3, 'c': 7}), 1)
示例#40
0
 def test_get_action_from_reference_not_in_accumulator(self):
     arg = Argument('test', reference='a')
     with self.assertRaises(InvalidArgument):
         arg._get_action_from_reference({'b': 3, 'c': 7})
示例#41
0
 def test_select_one_on_dict_key_error(self):
     arg = Argument('test', reference='some_id', selection=['d'])
     with self.assertRaises(InvalidArgument):
         arg._select({'a': 1, 'b': 2, 'c': 3})
示例#42
0
 def test_get_value_value_only(self):
     arg = Argument('test', value=42)
     self.assertEqual(arg.get_value({}), 42)
示例#43
0
 def test_get_value_value_with_reference(self):
     arg = Argument('test', value=42, reference='a')
     self.assertEqual(arg.get_value({'a': 1}), 42)
示例#44
0
 def test_get_value_reference_only(self):
     arg = Argument('test', reference='a')
     self.assertEqual(arg.get_value({'a': 1, 'b': 2}), 1)
示例#45
0
 def test_get_value_reference_not_found(self):
     arg = Argument('test', reference='c')
     with self.assertRaises(InvalidArgument):
         arg.get_value({'a': 1, 'b': 2})
示例#46
0
 def test_select_one_on_value(self):
     arg = Argument('test', reference='some_id', selection=['d'])
     with self.assertRaises(InvalidArgument):
         arg._select('some raw value')
示例#47
0
 def test_get_next_selection_key_on_dict(self):
     self.assertEqual(Argument._get_next_selection({'a': 1, '2': 'something'}, 'a'), 1)
示例#48
0
 def test_get_next_selection_key_on_list(self):
     with self.assertRaises(ValueError):
         Argument._get_next_selection(['a', 1, '2', 'something'], 'a')
示例#49
0
 def test_get_action_from_reference_empty_accumulator(self):
     arg = Argument('test', reference='a')
     with self.assertRaises(InvalidArgument):
         arg._get_action_from_reference({})