Ejemplo n.º 1
0
    def heavy_init(cls):
        super(RunActionEngineTest, cls).heavy_init()

        action = """---
        version: '2.0'

        concat:
          base: std.echo
          base-input:
            output: <% $.left %><% $.right %>
          input:
            - left
            - right

        concat3:
          base: concat
          base-input:
            left: <% $.left %><% $.center %>
            right: <% $.right %>
          input:
            - left
            - center
            - right

        concat4:
          base: concat3
          base-input:
            left: <% $.left %>
            center: <% $.center_left %><% $.center_right %>
            right: <% $.right %>
          input:
            - left
            - center_left
            - center_right
            - right

        missing_base:
          base: wrong
          input:
            - some_input

        loop_action:
          base: loop_action
          base-input:
            output: <% $.output %>
          input:
            - output

        level2_loop_action:
          base: loop_action
          base-input:
            output: <% $.output %>
          input:
            - output
        """
        actions.create_actions(action)
Ejemplo n.º 2
0
    def heavy_init(cls):
        super(RunActionEngineTest, cls).heavy_init()

        action = """---
        version: '2.0'

        concat:
          base: std.echo
          base-input:
            output: <% $.left %><% $.right %>
          input:
            - left
            - right

        concat3:
          base: concat
          base-input:
            left: <% $.left %><% $.center %>
            right: <% $.right %>
          input:
            - left
            - center
            - right

        concat4:
          base: concat3
          base-input:
            left: <% $.left %>
            center: <% $.center_left %><% $.center_right %>
            right: <% $.right %>
          input:
            - left
            - center_left
            - center_right
            - right

        missing_base:
          base: wrong
          input:
            - some_input

        loop_action:
          base: loop_action
          base-input:
            output: <% $.output %>
          input:
            - output

        level2_loop_action:
          base: loop_action
          base-input:
            output: <% $.output %>
          input:
            - output
        """
        actions.create_actions(action)
Ejemplo n.º 3
0
    def heavy_init(cls):
        super(RunActionEngineTest, cls).heavy_init()

        action = """---
        version: '2.0'

        concat:
          base: std.echo
          base-input:
            output: <% $.left %><% $.right %>
          input:
            - left
            - right
        """
        actions.create_actions(action)
Ejemplo n.º 4
0
    def heavy_init(cls):
        super(RunActionEngineTest, cls).heavy_init()

        action = """---
        version: '2.0'

        concat:
          base: std.echo
          base-input:
            output: <% $.left %><% $.right %>
          input:
            - left
            - right
        """
        actions.create_actions(action)
Ejemplo n.º 5
0
    def test_delete_action(self):

        # Create action.
        action_service.create_actions(ACTION_LIST, namespace=NAMESPACE)

        action = db_api.get_action_definition('action1', namespace=NAMESPACE)
        self.assertEqual(NAMESPACE, action.get('namespace'))
        self.assertEqual('action1', action.get('name'))

        # Delete action.
        db_api.delete_action_definition('action1', namespace=NAMESPACE)

        self.assertRaises(DBEntityNotFoundError,
                          db_api.get_action_definition,
                          name='action1',
                          namespace=NAMESPACE)
Ejemplo n.º 6
0
    def post(self):
        """Create a new action.

        NOTE: This text is allowed to have definitions
            of multiple actions. In this case they all will be created.
        """
        acl.enforce('actions:create', context.ctx())
        definition = pecan.request.text
        scope = pecan.request.GET.get('scope', 'private')
        pecan.response.status = 201

        if scope not in resources.SCOPE_TYPES.values:
            raise exc.InvalidModelException(
                "Scope must be one of the following: %s; actual: "
                "%s" % (resources.SCOPE_TYPES.values, scope))

        LOG.info("Create action(s) [definition=%s]", definition)

        with db_api.transaction():
            db_acts = actions.create_actions(definition, scope=scope)

        models_dicts = [db_act.to_dict() for db_act in db_acts]
        action_list = [resources.Action.from_dict(act) for act in models_dicts]

        return resources.Actions(actions=action_list).to_json()
Ejemplo n.º 7
0
    def test_update_actions(self):
        db_actions = action_service.create_actions(ACTION_LIST)

        self.assertEqual(2, len(db_actions))

        action1_db = self._assert_single_item(db_actions, name='action1')
        action1_spec = spec_parser.get_action_spec(action1_db.spec)

        self.assertEqual('action1', action1_spec.get_name())
        self.assertEqual('std.echo', action1_spec.get_base())
        self.assertDictEqual({'output': 'Hi'}, action1_spec.get_base_input())
        self.assertDictEqual({}, action1_spec.get_input())

        db_actions = action_service.update_actions(UPDATED_ACTION_LIST)

        # Action 1.
        action1_db = self._assert_single_item(db_actions, name='action1')
        action1_spec = spec_parser.get_action_spec(action1_db.spec)

        self.assertEqual('action1', action1_spec.get_name())
        self.assertListEqual([], action1_spec.get_tags())
        self.assertEqual('std.echo', action1_spec.get_base())
        self.assertDictEqual({'output': 'Hi'}, action1_spec.get_base_input())
        self.assertIn('param1', action1_spec.get_input())
        self.assertIs(action1_spec.get_input().get('param1'), utils.NotDefined)
Ejemplo n.º 8
0
    def post(self):
        """Create a new action.

        NOTE: This text is allowed to have definitions
            of multiple actions. In this case they all will be created.
        """
        acl.enforce('actions:create', context.ctx())
        definition = pecan.request.text
        scope = pecan.request.GET.get('scope', 'private')
        pecan.response.status = 201

        if scope not in SCOPE_TYPES.values:
            raise exc.InvalidModelException(
                "Scope must be one of the following: %s; actual: "
                "%s" % (SCOPE_TYPES.values, scope)
            )

        LOG.info("Create action(s) [definition=%s]" % definition)

        db_acts = actions.create_actions(definition, scope=scope)
        models_dicts = [db_act.to_dict() for db_act in db_acts]

        action_list = [Action.from_dict(act) for act in models_dicts]

        return Actions(actions=action_list).to_json()
Ejemplo n.º 9
0
    def test_update_actions(self):
        db_actions = action_service.create_actions(ACTION_LIST)

        self.assertEqual(2, len(db_actions))

        action1_db = self._assert_single_item(db_actions, name='action1')
        action1_spec = spec_parser.get_action_spec(action1_db.spec)

        self.assertEqual('action1', action1_spec.get_name())
        self.assertEqual('std.echo', action1_spec.get_base())
        self.assertDictEqual({'output': 'Hi'}, action1_spec.get_base_input())
        self.assertDictEqual({}, action1_spec.get_input())

        db_actions = action_service.update_actions(UPDATED_ACTION_LIST)

        # Action 1.
        action1_db = self._assert_single_item(db_actions, name='action1')
        action1_spec = spec_parser.get_action_spec(action1_db.spec)

        self.assertEqual('action1', action1_spec.get_name())
        self.assertListEqual([], action1_spec.get_tags())
        self.assertEqual('std.echo', action1_spec.get_base())
        self.assertDictEqual({'output': 'Hi'}, action1_spec.get_base_input())
        self.assertIn('param1', action1_spec.get_input())
        self.assertIs(
            action1_spec.get_input().get('param1'),
            utils.NotDefined
        )
Ejemplo n.º 10
0
    def test_create_actions_in_namespace(self):
        db_actions = action_service.create_actions(ACTION_LIST,
                                                   namespace=NAMESPACE)

        self.assertEqual(2, len(db_actions))

        action1_db = self._assert_single_item(db_actions, name='action1')
        self.assertEqual(NAMESPACE, action1_db.namespace)

        action2_db = self._assert_single_item(db_actions, name='action2')
        self.assertEqual(NAMESPACE, action2_db.namespace)

        self.assertRaises(DBEntityNotFoundError,
                          db_api.get_action_definition,
                          name='action1',
                          namespace='')
Ejemplo n.º 11
0
    def post(self):
        """Create a new action.

        NOTE: This text is allowed to have definitions
            of multiple actions. In this case they all will be created.
        """
        definition = pecan.request.text
        pecan.response.status = 201

        LOG.info("Create action(s) [definition=%s]" % definition)

        db_acts = actions.create_actions(definition)
        models_dicts = [db_act.to_dict() for db_act in db_acts]

        action_list = [Action.from_dict(act) for act in models_dicts]

        return Actions(actions=action_list).to_string()
Ejemplo n.º 12
0
    def post(self):
        """Create a new action.

        NOTE: This text is allowed to have definitions
            of multiple actions. In this case they all will be created.
        """
        definition = pecan.request.text
        pecan.response.status = 201

        LOG.info("Create action(s) [definition=%s]" % definition)

        db_acts = actions.create_actions(definition)
        models_dicts = [db_act.to_dict() for db_act in db_acts]

        action_list = [Action.from_dict(act) for act in models_dicts]

        return Actions(actions=action_list).to_string()
Ejemplo n.º 13
0
    def test_create_actions(self):
        db_actions = action_service.create_actions(ACTION_LIST)

        self.assertEqual(2, len(db_actions))

        # Action 1.
        action1_db = self._assert_single_item(db_actions, name='action1')
        action1_spec = spec_parser.get_action_spec(action1_db.spec)

        self.assertEqual('action1', action1_spec.get_name())
        self.assertListEqual(['test', 'v2'], action1_spec.get_tags())
        self.assertEqual('std.echo', action1_spec.get_base())
        self.assertDictEqual({'output': 'Hi'}, action1_spec.get_base_input())

        # Action 2.
        action2_db = self._assert_single_item(db_actions, name='action2')
        action2_spec = spec_parser.get_action_spec(action2_db.spec)

        self.assertEqual('action2', action2_spec.get_name())
        self.assertEqual('std.echo', action1_spec.get_base())
        self.assertDictEqual({'output': 'Hey'}, action2_spec.get_base_input())
Ejemplo n.º 14
0
    def test_create_actions(self):
        db_actions = action_service.create_actions(ACTION_LIST)

        self.assertEqual(2, len(db_actions))

        # Action 1.
        action1_db = self._assert_single_item(db_actions, name='action1')
        action1_spec = spec_parser.get_action_spec(action1_db.spec)

        self.assertEqual('action1', action1_spec.get_name())
        self.assertListEqual(['test', 'v2'], action1_spec.get_tags())
        self.assertEqual('std.echo', action1_spec.get_base())
        self.assertDictEqual({'output': 'Hi'}, action1_spec.get_base_input())

        # Action 2.
        action2_db = self._assert_single_item(db_actions, name='action2')
        action2_spec = spec_parser.get_action_spec(action2_db.spec)

        self.assertEqual('action2', action2_spec.get_name())
        self.assertEqual('std.echo', action1_spec.get_base())
        self.assertDictEqual({'output': 'Hey'}, action2_spec.get_base_input())
Ejemplo n.º 15
0
    def post(self):
        """Create a new action.

        NOTE: This text is allowed to have definitions
            of multiple actions. In this case they all will be created.
        """
        definition = pecan.request.text
        scope = pecan.request.GET.get('scope', 'private')
        pecan.response.status = 201

        if scope not in SCOPE_TYPES.values:
            raise exc.InvalidModelException(
                "Scope must be one of the following: %s; actual: "
                "%s" % (SCOPE_TYPES.values, scope))

        LOG.info("Create action(s) [definition=%s]" % definition)

        db_acts = actions.create_actions(definition, scope=scope)
        models_dicts = [db_act.to_dict() for db_act in db_acts]

        action_list = [Action.from_dict(act) for act in models_dicts]

        return Actions(actions=action_list).to_string()
Ejemplo n.º 16
0
    def test_run_action_with_namespace(self):
        namespace = 'test_ns'

        action_text = """---
        version: '2.0'

        concat1:
          base: std.echo
          base-input:
            output: <% $.left %><% $.right %>
          input:
            - left
            - right

        concat2:
          base: concat1
          base-input:
            left: <% $.left %><% $.center %>
            right: <% $.right %>
          input:
            - left
            - center
            - right
        """

        actions.create_actions(action_text, namespace=namespace)

        self.assertRaises(exc.InvalidActionException,
                          self.engine.start_action,
                          'concat1', {
                              'left': 'Hello, ',
                              'right': 'John Doe!'
                          },
                          save_result=True,
                          namespace='')

        action_ex = self.engine.start_action('concat1', {
            'left': 'Hello, ',
            'right': 'John Doe!'
        },
                                             save_result=True,
                                             namespace=namespace)

        self.assertEqual(namespace, action_ex.workflow_namespace)

        self.await_action_success(action_ex.id)

        with db_api.transaction():
            action_ex = db_api.get_action_execution(action_ex.id)

            self.assertEqual(states.SUCCESS, action_ex.state)
            self.assertEqual({'result': u'Hello, John Doe!'}, action_ex.output)

        action_ex = self.engine.start_action('concat2', {
            'left': 'Hello, ',
            'center': 'John',
            'right': ' Doe!'
        },
                                             save_result=True,
                                             namespace=namespace)

        self.assertEqual(namespace, action_ex.workflow_namespace)

        self.await_action_success(action_ex.id)

        with db_api.transaction():
            action_ex = db_api.get_action_execution(action_ex.id)

            self.assertEqual(states.SUCCESS, action_ex.state)
            self.assertEqual('Hello, John Doe!', action_ex.output['result'])
Ejemplo n.º 17
0
 def _create_action_definitions():
     with db_api.transaction():
         return actions.create_actions(definition, scope=scope)
Ejemplo n.º 18
0
    def test_action_definition_cache_ttl(self):
        action = """---
        version: '2.0'

        action1:
          base: std.echo output='Hi'
          output:
            result: $
        """

        wf_text = """---
        version: '2.0'

        wf:
          tasks:
            task1:
              action: action1
              on-success: join_task

            task2:
              action: action1
              on-success: join_task

            join_task:
              join: all
              on-success: task4

            task4:
              action: action1
              pause-before: true
        """

        wf_service.create_workflows(wf_text)

        # Create an action.
        db_actions = action_service.create_actions(action)

        self.assertEqual(1, len(db_actions))
        self._assert_single_item(db_actions, name='action1')

        # Explicitly mark the action to be deleted after the test execution.
        self.addCleanup(db_api.delete_action_definitions, name='action1')

        # Reinitialise the cache with reduced action_definition_cache_time
        # to make the test faster.
        new_cache = cachetools.TTLCache(
            maxsize=1000,
            ttl=5  # 5 seconds
        )
        cache_patch = mock.patch.object(lookup_utils, '_ACTION_DEF_CACHE',
                                        new_cache)
        cache_patch.start()
        self.addCleanup(cache_patch.stop)

        # Start workflow.
        wf_ex = self.engine.start_workflow('wf')

        self.await_workflow_paused(wf_ex.id)

        # Check that 'action1' 'echo' and 'noop' are cached.
        self.assertEqual(3, lookup_utils.get_action_definition_cache_size())
        self.assertIn('action1', lookup_utils._ACTION_DEF_CACHE)
        self.assertIn('std.noop', lookup_utils._ACTION_DEF_CACHE)
        self.assertIn('std.echo', lookup_utils._ACTION_DEF_CACHE)

        # Wait some time until cache expires
        self._await(
            lambda: lookup_utils.get_action_definition_cache_size() == 0,
            fail_message="No triggers were found")

        self.assertEqual(0, lookup_utils.get_action_definition_cache_size())

        self.engine.resume_workflow(wf_ex.id)

        self.await_workflow_success(wf_ex.id)

        # Check all actions are cached again.
        self.assertEqual(2, lookup_utils.get_action_definition_cache_size())
        self.assertIn('action1', lookup_utils._ACTION_DEF_CACHE)
        self.assertIn('std.echo', lookup_utils._ACTION_DEF_CACHE)
Ejemplo n.º 19
0
    def test_action_definition_cache_ttl(self):
        action = """---
        version: '2.0'

        action1:
          base: std.echo output='Hi'
          output:
            result: $
        """

        wf_text = """---
        version: '2.0'

        wf:
          tasks:
            task1:
              action: action1
              on-success: join_task

            task2:
              action: action1
              on-success: join_task

            join_task:
              join: all
              on-success: task4

            task4:
              action: action1
              pause-before: true
        """

        wf_service.create_workflows(wf_text)

        # Create an action.
        db_actions = action_service.create_actions(action)

        self.assertEqual(1, len(db_actions))
        self._assert_single_item(db_actions, name='action1')

        # Explicitly mark the action to be deleted after the test execution.
        self.addCleanup(db_api.delete_action_definitions, name='action1')

        # Reinitialise the cache with reduced action_definition_cache_time
        # to make the test faster.
        # Save the existing cache into a temporary variable and restore
        # the value when the test passed.
        old_cache = lookup_utils._ACTION_DEF_CACHE
        lookup_utils._ACTION_DEF_CACHE = cachetools.TTLCache(
            maxsize=1000,
            ttl=5  # 5 seconds
        )
        self.addCleanup(setattr, lookup_utils, '_ACTION_DEF_CACHE', old_cache)

        # Start workflow.
        wf_ex = self.engine.start_workflow('wf')

        self.await_workflow_paused(wf_ex.id)

        # Check that 'action1' 'echo' and 'noop' are cached.
        self.assertEqual(3, lookup_utils.get_action_definition_cache_size())
        self.assertIn('action1', lookup_utils._ACTION_DEF_CACHE)
        self.assertIn('std.noop', lookup_utils._ACTION_DEF_CACHE)
        self.assertIn('std.echo', lookup_utils._ACTION_DEF_CACHE)

        # Wait some time until cache expires
        time.sleep(7)
        self.assertEqual(0, lookup_utils.get_action_definition_cache_size())

        self.engine.resume_workflow(wf_ex.id)

        self.await_workflow_success(wf_ex.id)

        # Check all actions are cached again.
        self.assertEqual(2, lookup_utils.get_action_definition_cache_size())
        self.assertIn('action1', lookup_utils._ACTION_DEF_CACHE)
        self.assertIn('std.echo', lookup_utils._ACTION_DEF_CACHE)
Ejemplo n.º 20
0
 def _create_action_definitions():
     with db_api.transaction():
         return actions.create_actions(definition, scope=scope)
Ejemplo n.º 21
0
    def test_action_definition_cache_ttl(self):
        action = """---
        version: '2.0'

        action1:
          base: std.echo output='Hi'
          output:
            result: $
        """

        wf_text = """---
        version: '2.0'

        wf:
          tasks:
            task1:
              action: action1
              on-success: join_task

            task2:
              action: action1
              on-success: join_task

            join_task:
              join: all
              on-success: task4

            task4:
              action: action1
              pause-before: true
        """

        wf_service.create_workflows(wf_text)

        # Create an action.
        db_actions = action_service.create_actions(action)

        self.assertEqual(1, len(db_actions))
        self._assert_single_item(db_actions, name='action1')

        # Explicitly mark the action to be deleted after the test execution.
        self.addCleanup(db_api.delete_action_definitions, name='action1')

        # Reinitialise the cache with reduced action_definition_cache_time
        # to make the test faster.
        new_cache = cachetools.TTLCache(
            maxsize=1000,
            ttl=5  # 5 seconds
        )
        cache_patch = mock.patch.object(
            actions, '_ACTION_DEF_CACHE', new_cache)
        cache_patch.start()
        self.addCleanup(cache_patch.stop)

        # Start workflow.
        wf_ex = self.engine.start_workflow('wf')

        self.await_workflow_paused(wf_ex.id)

        # Check that 'action1' 'echo' and 'noop' are cached.
        self.assertEqual(3, len(actions._ACTION_DEF_CACHE))
        self.assertIn('action1', actions._ACTION_DEF_CACHE)
        self.assertIn('std.noop', actions._ACTION_DEF_CACHE)
        self.assertIn('std.echo', actions._ACTION_DEF_CACHE)

        # Wait some time until cache expires
        self._await(
            lambda: len(actions._ACTION_DEF_CACHE) == 0,
            fail_message="No triggers were found"
        )

        self.assertEqual(0, len(actions._ACTION_DEF_CACHE))

        self.engine.resume_workflow(wf_ex.id)

        self.await_workflow_success(wf_ex.id)

        # Check all actions are cached again.
        self.assertEqual(2, len(actions._ACTION_DEF_CACHE))
        self.assertIn('action1', actions._ACTION_DEF_CACHE)
        self.assertIn('std.echo', actions._ACTION_DEF_CACHE)