From cbee740de5e8df9214394eae66776904cacf9ef5 Mon Sep 17 00:00:00 2001 From: Michal Gershenzon Date: Wed, 19 Jul 2017 18:30:38 +0000 Subject: [PATCH] Create and run a workflow within a namespace Allow adding many workflows with the same name. The way this works is by adding the new workflows under another namespace. Notice that: 1. Namespaces are not part of the mistral DSL. 2. When executing a workflow, the namespace passes down to the subworkflow. 3. When searching for the sub-workflow definition - If no workflow was found in the given namespace, than the defualt namespace will be used. 4. The default namespace is an empty string. 5. The namespace property or the workflow execution will be under params Partially-Implements: blueprint create-and-run-workflows-within-a-namespace Change-Id: Id248ec5906a0899d188675d002b45f6249d36d90 --- functionaltests/run_tests.sh | 6 +- mistral/api/controllers/v2/execution.py | 1 + mistral/api/controllers/v2/resources.py | 15 ++- mistral/api/controllers/v2/workflow.py | 49 +++++--- .../versions/022_namespace_support.py | 114 ++++++++++++++++++ mistral/db/v2/api.py | 16 +-- mistral/db/v2/sqlalchemy/api.py | 89 ++++++++++++-- mistral/db/v2/sqlalchemy/models.py | 9 +- mistral/engine/actions.py | 8 +- mistral/engine/base.py | 5 +- mistral/engine/default_engine.py | 10 +- mistral/engine/engine_server.py | 6 +- mistral/engine/tasks.py | 1 + mistral/engine/utils.py | 9 +- mistral/engine/workflow_handler.py | 9 +- mistral/engine/workflows.py | 1 + mistral/rpc/clients.py | 5 +- mistral/services/workbooks.py | 1 + mistral/services/workflows.py | 38 ++++-- .../for_wf_namespace/lowest_level_wf.yaml | 6 + .../resources/for_wf_namespace/middle_wf.yaml | 6 + .../for_wf_namespace/top_level_wf.yaml | 6 + mistral/tests/unit/api/v2/test_executions.py | 1 + mistral/tests/unit/api/v2/test_members.py | 4 +- mistral/tests/unit/api/v2/test_workflows.py | 65 +++++++++- .../unit/db/v2/test_sqlalchemy_db_api.py | 6 +- .../tests/unit/engine/test_action_context.py | 2 +- .../tests/unit/engine/test_action_defaults.py | 6 +- .../tests/unit/engine/test_adhoc_actions.py | 5 +- mistral/tests/unit/engine/test_commands.py | 32 ++--- mistral/tests/unit/engine/test_dataflow.py | 32 ++--- .../tests/unit/engine/test_default_engine.py | 12 ++ .../tests/unit/engine/test_direct_workflow.py | 22 ++-- .../unit/engine/test_direct_workflow_rerun.py | 22 ++-- .../test_direct_workflow_rerun_cancelled.py | 8 +- .../test_direct_workflow_with_cycles.py | 6 +- mistral/tests/unit/engine/test_environment.py | 6 +- .../tests/unit/engine/test_error_handling.py | 37 +++--- .../tests/unit/engine/test_error_result.py | 3 + .../test_execution_fields_size_limitation.py | 11 +- .../unit/engine/test_javascript_action.py | 4 +- mistral/tests/unit/engine/test_join.py | 42 +++---- .../tests/unit/engine/test_lookup_utils.py | 2 +- mistral/tests/unit/engine/test_noop_task.py | 4 +- mistral/tests/unit/engine/test_policies.py | 54 +++++---- mistral/tests/unit/engine/test_profiler.py | 4 +- .../tests/unit/engine/test_race_condition.py | 4 +- .../unit/engine/test_reverse_workflow.py | 13 +- .../engine/test_reverse_workflow_rerun.py | 5 +- .../test_reverse_workflow_rerun_cancelled.py | 2 +- mistral/tests/unit/engine/test_safe_rerun.py | 6 +- mistral/tests/unit/engine/test_state_info.py | 8 +- .../tests/unit/engine/test_subworkflows.py | 15 ++- mistral/tests/unit/engine/test_task_cancel.py | 8 +- .../tests/unit/engine/test_task_defaults.py | 10 +- .../tests/unit/engine/test_task_publish.py | 2 +- .../tests/unit/engine/test_tasks_function.py | 11 +- mistral/tests/unit/engine/test_with_items.py | 53 ++++---- .../tests/unit/engine/test_workflow_cancel.py | 20 +-- .../tests/unit/engine/test_workflow_resume.py | 13 +- .../tests/unit/engine/test_workflow_stop.py | 2 +- .../unit/engine/test_workflow_variables.py | 2 +- .../tests/unit/engine/test_yaql_functions.py | 20 +-- .../unit/executors/test_local_executor.py | 4 +- mistral_tempest_tests/services/base.py | 4 +- .../services/v2/mistral_client.py | 92 +++++++++++--- .../tests/api/v2/test_action_executions.py | 28 +++++ .../tests/api/v2/test_actions.py | 11 +- .../tests/api/v2/test_event_triggers.py | 2 +- .../tests/api/v2/test_executions.py | 97 ++++++++++++++- .../tests/api/v2/test_tasks.py | 3 +- .../tests/api/v2/test_workflows.py | 61 ++++++++++ 72 files changed, 961 insertions(+), 335 deletions(-) create mode 100644 mistral/db/sqlalchemy/migration/alembic_migrations/versions/022_namespace_support.py create mode 100644 mistral/tests/resources/for_wf_namespace/lowest_level_wf.yaml create mode 100644 mistral/tests/resources/for_wf_namespace/middle_wf.yaml create mode 100644 mistral/tests/resources/for_wf_namespace/top_level_wf.yaml diff --git a/functionaltests/run_tests.sh b/functionaltests/run_tests.sh index 162ea39de..ec093b79a 100755 --- a/functionaltests/run_tests.sh +++ b/functionaltests/run_tests.sh @@ -23,7 +23,7 @@ fi echo "Successfully contacted Mistral API" # Where tempest code lives -TEMPEST_DIR=${TEMPEST_DIR:-/opt/stack/new/tempest} +TEMPEST_DIR=${TEMPEST_DIR:-/opt/stack/tempest} # Path to directory with tempest.conf file, otherwise it will # take relative path from where the run tests command is being executed. @@ -31,8 +31,8 @@ export TEMPEST_CONFIG_DIR=${TEMPEST_CONFIG_DIR:-$TEMPEST_DIR/etc/} echo "Tempest configuration file directory: $TEMPEST_CONFIG_DIR" # Where mistral code and mistralclient code live -MISTRAL_DIR=/opt/stack/new/mistral -MISTRALCLIENT_DIR=/opt/stack/new/python-mistralclient +MISTRAL_DIR=/opt/stack/mistral +MISTRALCLIENT_DIR=/opt/stack/python-mistralclient # Define PYTHONPATH export PYTHONPATH=$PYTHONPATH:$TEMPEST_DIR diff --git a/mistral/api/controllers/v2/execution.py b/mistral/api/controllers/v2/execution.py index a6c1de9f9..36154aa09 100644 --- a/mistral/api/controllers/v2/execution.py +++ b/mistral/api/controllers/v2/execution.py @@ -208,6 +208,7 @@ class ExecutionsController(rest.RestController): result = engine.start_workflow( exec_dict.get('workflow_id', exec_dict.get('workflow_name')), + exec_dict.get('workflow_namespace', ''), exec_dict.get('input'), exec_dict.get('description', ''), **exec_dict.get('params') or {} diff --git a/mistral/api/controllers/v2/resources.py b/mistral/api/controllers/v2/resources.py index 93e450af4..c1224e424 100644 --- a/mistral/api/controllers/v2/resources.py +++ b/mistral/api/controllers/v2/resources.py @@ -69,6 +69,7 @@ class Workflow(resource.Resource): id = wtypes.text name = wtypes.text + namespace = wtypes.text input = wtypes.text definition = wtypes.text @@ -92,7 +93,8 @@ class Workflow(resource.Resource): scope='private', project_id='a7eb669e9819420ea4bd1453e672c0a7', created_at='1970-01-01T00:00:00.000000', - updated_at='1970-01-01T00:00:00.000000') + updated_at='1970-01-01T00:00:00.000000', + namespace='') @classmethod def _set_input(cls, obj, wf_spec): @@ -214,6 +216,14 @@ class Execution(resource.Resource): workflow_name = wtypes.text "reference to workflow definition" + workflow_namespace = wtypes.text + ("reference to workflow namespace. The workflow namespace is also saved " + "under params and passed to all sub-workflow executions. When looking for" + " the next sub-workflow to run, The correct workflow will be found by " + "name and namespace, where the namespace can be the workflow namespace or" + " the default namespace. Workflows in the same namespace will be given " + "a higher priority.") + workflow_id = wtypes.text "reference to workflow ID" @@ -246,6 +256,7 @@ class Execution(resource.Resource): def sample(cls): return cls(id='123e4567-e89b-12d3-a456-426655440000', workflow_name='flow', + workflow_namespace='some_namespace', workflow_id='123e4567-e89b-12d3-a456-426655441111', description='this is the first execution.', state='SUCCESS', @@ -287,6 +298,7 @@ class Task(resource.Resource): type = wtypes.text workflow_name = wtypes.text + workflow_namespace = wtypes.text workflow_id = wtypes.text workflow_execution_id = wtypes.text @@ -358,6 +370,7 @@ class ActionExecution(resource.Resource): id = wtypes.text workflow_name = wtypes.text + workflow_namespace = wtypes.text task_name = wtypes.text task_execution_id = wtypes.text diff --git a/mistral/api/controllers/v2/workflow.py b/mistral/api/controllers/v2/workflow.py index 49b750a52..c997e882e 100644 --- a/mistral/api/controllers/v2/workflow.py +++ b/mistral/api/controllers/v2/workflow.py @@ -76,27 +76,34 @@ class WorkflowsController(rest.RestController, hooks.HookController): ) @rest_utils.wrap_wsme_controller_exception - @wsme_pecan.wsexpose(resources.Workflow, wtypes.text) - def get(self, identifier): + @wsme_pecan.wsexpose(resources.Workflow, wtypes.text, wtypes.text) + def get(self, identifier, namespace=''): """Return the named workflow. :param identifier: Name or UUID of the workflow to retrieve. + :param namespace: Optional. Namespace of the workflow to retrieve. """ acl.enforce('workflows:get', context.ctx()) LOG.info("Fetch workflow [identifier=%s]", identifier) - db_model = db_api.get_workflow_definition(identifier) + db_model = db_api.get_workflow_definition( + identifier, + namespace=namespace + ) return resources.Workflow.from_db_model(db_model) @rest_utils.wrap_pecan_controller_exception @pecan.expose(content_type="text/plain") - def put(self, identifier=None): + def put(self, identifier=None, namespace=''): """Update one or more workflows. :param identifier: Optional. If provided, it's UUID of a workflow. Only one workflow can be updated with identifier param. + :param namespace: Optional. If provided int's the namespace of the + workflow/workflows. currently namespace cannot be + changed. The text is allowed to have definitions of multiple workflows. In this case they all will be updated. @@ -117,7 +124,8 @@ class WorkflowsController(rest.RestController, hooks.HookController): db_wfs = workflows.update_workflows( definition, scope=scope, - identifier=identifier + identifier=identifier, + namespace=namespace ) workflow_list = [ @@ -129,11 +137,15 @@ class WorkflowsController(rest.RestController, hooks.HookController): @rest_utils.wrap_pecan_controller_exception @pecan.expose(content_type="text/plain") - def post(self): + def post(self, namespace=''): """Create a new workflow. NOTE: The text is allowed to have definitions of multiple workflows. In this case they all will be created. + + :param namespace: Optional. The namespace to create the workflow + in. Workflows with the same name can be added to a given + project if are in two different namespaces. """ acl.enforce('workflows:create', context.ctx()) @@ -149,7 +161,11 @@ class WorkflowsController(rest.RestController, hooks.HookController): LOG.info("Create workflow(s) [definition=%s]", definition) - db_wfs = workflows.create_workflows(definition, scope=scope) + db_wfs = workflows.create_workflows( + definition, + scope=scope, + namespace=namespace + ) workflow_list = [ resources.Workflow.from_db_model(db_wf) for db_wf in db_wfs @@ -158,30 +174,32 @@ class WorkflowsController(rest.RestController, hooks.HookController): return resources.Workflows(workflows=workflow_list).to_json() @rest_utils.wrap_wsme_controller_exception - @wsme_pecan.wsexpose(None, wtypes.text, status_code=204) - def delete(self, identifier): + @wsme_pecan.wsexpose(None, wtypes.text, wtypes.text, status_code=204) + def delete(self, identifier, namespace=''): """Delete a workflow. :param identifier: Name or ID of workflow to delete. + :param namespace: Optional. Namespace of the workflow to delete. """ acl.enforce('workflows:delete', context.ctx()) - LOG.info("Delete workflow [identifier=%s]", identifier) + LOG.info("Delete workflow [identifier=%s, namespace=%s]", + identifier, namespace) with db_api.transaction(): - db_api.delete_workflow_definition(identifier) + db_api.delete_workflow_definition(identifier, namespace) @rest_utils.wrap_wsme_controller_exception @wsme_pecan.wsexpose(resources.Workflows, types.uuid, int, types.uniquelist, types.list, types.uniquelist, wtypes.text, wtypes.text, wtypes.text, wtypes.text, resources.SCOPE_TYPES, types.uuid, wtypes.text, - wtypes.text, bool) + wtypes.text, bool, wtypes.text) def get_all(self, marker=None, limit=None, sort_keys='created_at', sort_dirs='asc', fields='', name=None, input=None, definition=None, tags=None, scope=None, project_id=None, created_at=None, updated_at=None, - all_projects=False): + all_projects=False, namespace=None): """Return a list of workflows. :param marker: Optional. Pagination marker for large data sets. @@ -198,6 +216,8 @@ class WorkflowsController(rest.RestController, hooks.HookController): fields if it's provided, since it will be used when constructing 'next' link. :param name: Optional. Keep only resources with a specific name. + :param namespace: Optional. Keep only resources with a specific + namespace :param input: Optional. Keep only resources with a specific input. :param definition: Optional. Keep only resources with a specific definition. @@ -224,7 +244,8 @@ class WorkflowsController(rest.RestController, hooks.HookController): updated_at=updated_at, input=input, definition=definition, - project_id=project_id + project_id=project_id, + namespace=namespace ) LOG.info("Fetch workflows. marker=%s, limit=%s, sort_keys=%s, " diff --git a/mistral/db/sqlalchemy/migration/alembic_migrations/versions/022_namespace_support.py b/mistral/db/sqlalchemy/migration/alembic_migrations/versions/022_namespace_support.py new file mode 100644 index 000000000..cb61c2029 --- /dev/null +++ b/mistral/db/sqlalchemy/migration/alembic_migrations/versions/022_namespace_support.py @@ -0,0 +1,114 @@ +# Copyright 2017 OpenStack Foundation. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +# implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""namespace_support + +Revision ID: 022 +Revises: 021 +Create Date: 2017-06-11 13:09:06.782095 + +""" + +# revision identifiers, used by Alembic. +revision = '022' +down_revision = '021' + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.sql import table, column + +# A simple model of the workflow definitions table with only the field needed +wf_def = table('workflow_definitions_v2', column('namespace')) + +# A simple model of the workflow executions table with only the field needed +wf_exec = table('workflow_executions_v2', column('workflow_namespace')) + +# A simple model of the task executions table with only the field needed +task_exec = table('task_executions_v2', column('workflow_namespace')) + +# A simple model of the action executions table with only the fields needed +action_executions = sa.Table( + 'action_executions_v2', + sa.MetaData(), + sa.Column('id', sa.String(36), nullable=False), + sa.Column('workflow_name', sa.String(255)), + sa.Column('workflow_namespace', sa.String(255), nullable=True) +) + + +def upgrade(): + + # ### commands auto generated by Alembic - please adjust! ### + op.add_column( + 'workflow_definitions_v2', + sa.Column( + 'namespace', + sa.String(length=255), + nullable=True + ) + ) + + op.drop_index('name', table_name='workflow_definitions_v2') + op.create_unique_constraint( + None, + 'workflow_definitions_v2', + ['name', 'namespace', 'project_id'] + ) + + op.add_column( + 'workflow_executions_v2', + sa.Column( + 'workflow_namespace', + sa.String(length=255), + nullable=True + ) + ) + + op.add_column( + 'task_executions_v2', + sa.Column( + 'workflow_namespace', + sa.String(length=255), + nullable=True + ) + ) + + op.add_column( + 'action_executions_v2', + sa.Column('workflow_namespace', sa.String(length=255), nullable=True) + ) + + session = sa.orm.Session(bind=op.get_bind()) + values = [] + + for row in session.query(action_executions): + values.append({'id': row[0], + 'workflow_name': row[1]}) + + with session.begin(subtransactions=True): + session.execute(wf_def.update().values(namespace='')) + session.execute(wf_exec.update().values(workflow_namespace='')) + session.execute(task_exec.update().values(workflow_namespace='')) + + for value in values: + if value['workflow_name']: + session.execute(action_executions.update().values( + workflow_namespace='' + ).where(action_executions.c.id == value['id'])) + + # this commit appears to be necessary + session.commit() + +# ### end Alembic commands ### diff --git a/mistral/db/v2/api.py b/mistral/db/v2/api.py index 2cef2344b..b9339a89b 100644 --- a/mistral/db/v2/api.py +++ b/mistral/db/v2/api.py @@ -114,17 +114,17 @@ def delete_workbooks(**kwargs): # Workflow definitions. -def get_workflow_definition(identifier): - return IMPL.get_workflow_definition(identifier) +def get_workflow_definition(identifier, namespace=''): + return IMPL.get_workflow_definition(identifier, namespace=namespace) def get_workflow_definition_by_id(id): return IMPL.get_workflow_definition_by_id(id) -def load_workflow_definition(name): +def load_workflow_definition(name, namespace=''): """Unlike get_workflow_definition this method is allowed to return None.""" - return IMPL.load_workflow_definition(name) + return IMPL.load_workflow_definition(name, namespace) def get_workflow_definitions(limit=None, marker=None, sort_keys=None, @@ -143,16 +143,16 @@ def create_workflow_definition(values): return IMPL.create_workflow_definition(values) -def update_workflow_definition(identifier, values): - return IMPL.update_workflow_definition(identifier, values) +def update_workflow_definition(identifier, values, namespace): + return IMPL.update_workflow_definition(identifier, values, namespace) def create_or_update_workflow_definition(name, values): return IMPL.create_or_update_workflow_definition(name, values) -def delete_workflow_definition(identifier): - IMPL.delete_workflow_definition(identifier) +def delete_workflow_definition(identifier, namespace=''): + IMPL.delete_workflow_definition(identifier, namespace) def delete_workflow_definitions(**kwargs): diff --git a/mistral/db/v2/sqlalchemy/api.py b/mistral/db/v2/sqlalchemy/api.py index 5f991d67e..28b2bb83c 100644 --- a/mistral/db/v2/sqlalchemy/api.py +++ b/mistral/db/v2/sqlalchemy/api.py @@ -253,8 +253,36 @@ def _get_collection_sorted_by_time(model, insecure=False, fields=None, ) -def _get_db_object_by_name(model, name): - return _secure_query(model).filter_by(name=name).first() +def _get_db_object_by_name(model, name, filter_=None, order_by=None): + + query = _secure_query(model) + final_filter = model.name == name + + if filter_ is not None: + final_filter = sa.and_(final_filter, filter_) + + if order_by is not None: + query = query.order_by(order_by) + + return query.filter(final_filter).first() + + +def _get_wf_object_by_name_and_namespace(model, name, namespace=None): + + query = _secure_query(model) + filter_ = model.name == name + + if namespace is not None: + in_namespace = sa.or_( + model.namespace == namespace, + model.namespace == '' + ) + filter_ = sa.and_(filter_, in_namespace) + + # Give priority to objects not in the default namespace. + query = query.order_by(model.namespace.desc()) + + return query.filter(filter_).first() def _get_db_object_by_id(model, id, insecure=False): @@ -264,11 +292,28 @@ def _get_db_object_by_id(model, id, insecure=False): def _get_db_object_by_name_or_id(model, identifier, insecure=False): + return _get_db_object_by_name_and_namespace_or_id( + model, + identifier, + insecure=insecure + ) + + +def _get_db_object_by_name_and_namespace_or_id(model, identifier, + namespace=None, insecure=False): + query = b.model_query(model) if insecure else _secure_query(model) + + match_name = model.name == identifier + + if namespace is not None: + match_name = sa.and_(match_name, model.namespace == namespace) + + match_id = model.id == identifier query = query.filter( sa.or_( - model.id == identifier, - model.name == identifier + match_id, + match_name ) ) @@ -421,24 +466,27 @@ def delete_workbooks(session=None, **kwargs): # Workflow definitions. @b.session_aware() -def get_workflow_definition(identifier, session=None): +def get_workflow_definition(identifier, namespace='', session=None): """Gets workflow definition by name or uuid. :param identifier: Identifier could be in the format of plain string or uuid. + :param namespace: The namespace the workflow is in. Optional. :return: Workflow definition. """ ctx = context.ctx() - wf_def = _get_db_object_by_name_or_id( + wf_def = _get_db_object_by_name_and_namespace_or_id( models.WorkflowDefinition, identifier, + namespace=namespace, insecure=ctx.is_admin ) if not wf_def: raise exc.DBEntityNotFoundError( - "Workflow not found [workflow_identifier=%s]" % identifier + "Workflow not found [workflow_identifier=%s, namespace=%s]" + % (identifier, namespace) ) return wf_def @@ -457,8 +505,23 @@ def get_workflow_definition_by_id(id, session=None): @b.session_aware() -def load_workflow_definition(name, session=None): - return _get_db_object_by_name(models.WorkflowDefinition, name) +def load_workflow_definition(name, namespace='', session=None): + model = models.WorkflowDefinition + + filter_ = sa.or_( + model.namespace == namespace, + model.namespace == '' + ) + + # Give priority to objects not in the default namespace. + order_by = model.namespace.desc() + + return _get_db_object_by_name( + model, + name, + filter_, + order_by + ) @b.session_aware() @@ -493,8 +556,8 @@ def create_workflow_definition(values, session=None): @b.session_aware() -def update_workflow_definition(identifier, values, session=None): - wf_def = get_workflow_definition(identifier) +def update_workflow_definition(identifier, values, namespace='', session=None): + wf_def = get_workflow_definition(identifier, namespace=namespace) m_dbutils.check_db_obj_access(wf_def) @@ -537,8 +600,8 @@ def create_or_update_workflow_definition(name, values, session=None): @b.session_aware() -def delete_workflow_definition(identifier, session=None): - wf_def = get_workflow_definition(identifier) +def delete_workflow_definition(identifier, namespace='', session=None): + wf_def = get_workflow_definition(identifier, namespace) m_dbutils.check_db_obj_access(wf_def) diff --git a/mistral/db/v2/sqlalchemy/models.py b/mistral/db/v2/sqlalchemy/models.py index 83f948132..e2e4aae32 100644 --- a/mistral/db/v2/sqlalchemy/models.py +++ b/mistral/db/v2/sqlalchemy/models.py @@ -121,9 +121,13 @@ class WorkflowDefinition(Definition): """Contains info about workflow (including definition in Mistral DSL).""" __tablename__ = 'workflow_definitions_v2' - + namespace = sa.Column(sa.String(255), nullable=True) __table_args__ = ( - sa.UniqueConstraint('name', 'project_id'), + sa.UniqueConstraint( + 'name', + 'namespace', + 'project_id' + ), sa.Index('%s_is_system' % __tablename__, 'is_system'), sa.Index('%s_project_id' % __tablename__, 'project_id'), sa.Index('%s_scope' % __tablename__, 'scope'), @@ -162,6 +166,7 @@ class Execution(mb.MistralSecureModelBase): name = sa.Column(sa.String(255)) description = sa.Column(sa.String(255), nullable=True) workflow_name = sa.Column(sa.String(255)) + workflow_namespace = sa.Column(sa.String(255)) workflow_id = sa.Column(sa.String(80)) spec = sa.Column(st.JsonMediumDictType()) state = sa.Column(sa.String(20)) diff --git a/mistral/engine/actions.py b/mistral/engine/actions.py index 28414927d..392b8568d 100644 --- a/mistral/engine/actions.py +++ b/mistral/engine/actions.py @@ -144,6 +144,7 @@ class Action(object): values.update({ 'task_execution_id': self.task_ex.id, 'workflow_name': self.task_ex.workflow_name, + 'workflow_namespace': self.task_ex.workflow_namespace, 'workflow_id': self.task_ex.workflow_id, 'project_id': self.task_ex.project_id, }) @@ -492,7 +493,8 @@ class WorkflowAction(Action): wf_def = engine_utils.resolve_workflow_definition( parent_wf_ex.workflow_name, parent_wf_spec.get_name(), - wf_spec_name + namespace=parent_wf_ex.params['namespace'], + wf_spec_name=wf_spec_name ) wf_spec = spec_parser.get_workflow_spec_by_definition_id( @@ -502,7 +504,8 @@ class WorkflowAction(Action): wf_params = { 'task_execution_id': self.task_ex.id, - 'index': index + 'index': index, + 'namespace': parent_wf_ex.params['namespace'] } if 'env' in parent_wf_ex.params: @@ -516,6 +519,7 @@ class WorkflowAction(Action): wf_handler.start_workflow( wf_def.id, + wf_def.namespace, input_dict, "sub-workflow execution", wf_params diff --git a/mistral/engine/base.py b/mistral/engine/base.py index 48a2c5eb2..d2a99e48c 100644 --- a/mistral/engine/base.py +++ b/mistral/engine/base.py @@ -28,13 +28,14 @@ class Engine(object): """Engine interface.""" @abc.abstractmethod - def start_workflow(self, wf_identifier, wf_input, description='', - **params): + def start_workflow(self, wf_identifier, wf_namespace='', wf_input=None, + description='', **params): """Starts the specified workflow. :param wf_identifier: Workflow ID or name. Workflow ID is recommended, workflow name will be deprecated since Mitaka. :param wf_input: Workflow input data as a dictionary. + :param wf_namespace: Workflow input data as a dictionary. :param description: Execution description. :param params: Additional workflow type specific parameters. :return: Workflow execution object. diff --git a/mistral/engine/default_engine.py b/mistral/engine/default_engine.py index 4a879b148..d4c895dad 100644 --- a/mistral/engine/default_engine.py +++ b/mistral/engine/default_engine.py @@ -36,12 +36,16 @@ from mistral.workflow import states class DefaultEngine(base.Engine): @action_queue.process @profiler.trace('engine-start-workflow', hide_args=True) - def start_workflow(self, wf_identifier, wf_input, description='', - **params): + def start_workflow(self, wf_identifier, wf_namespace='', wf_input=None, + description='', **params): + if wf_namespace: + params['namespace'] = wf_namespace + with db_api.transaction(): wf_ex = wf_handler.start_workflow( wf_identifier, - wf_input, + wf_namespace, + wf_input or {}, description, params ) diff --git a/mistral/engine/engine_server.py b/mistral/engine/engine_server.py index b04f315da..3ef4b9e09 100644 --- a/mistral/engine/engine_server.py +++ b/mistral/engine/engine_server.py @@ -78,12 +78,13 @@ class EngineServer(service_base.MistralService): if self._rpc_server: self._rpc_server.stop(graceful) - def start_workflow(self, rpc_ctx, workflow_identifier, workflow_input, - description, params): + def start_workflow(self, rpc_ctx, workflow_identifier, workflow_namespace, + workflow_input, description, params): """Receives calls over RPC to start workflows on engine. :param rpc_ctx: RPC request context. :param workflow_identifier: Workflow definition identifier. + :param workflow_namespace: Workflow definition identifier. :param workflow_input: Workflow input. :param description: Workflow execution description. :param params: Additional workflow type specific parameters. @@ -101,6 +102,7 @@ class EngineServer(service_base.MistralService): return self.engine.start_workflow( workflow_identifier, + workflow_namespace, workflow_input, description, **params diff --git a/mistral/engine/tasks.py b/mistral/engine/tasks.py index 31acbf5da..758fe6e37 100644 --- a/mistral/engine/tasks.py +++ b/mistral/engine/tasks.py @@ -216,6 +216,7 @@ class Task(object): 'name': task_name, 'workflow_execution_id': self.wf_ex.id, 'workflow_name': self.wf_ex.workflow_name, + 'workflow_namespace': self.wf_ex.workflow_namespace, 'workflow_id': self.wf_ex.workflow_id, 'state': state, 'state_info': state_info, diff --git a/mistral/engine/utils.py b/mistral/engine/utils.py index 260f43340..3114f7b9f 100644 --- a/mistral/engine/utils.py +++ b/mistral/engine/utils.py @@ -67,7 +67,7 @@ def validate_input(expected_input, actual_input, obj_name, obj_class): def resolve_workflow_definition(parent_wf_name, parent_wf_spec_name, - wf_spec_name): + namespace, wf_spec_name): wf_def = None if parent_wf_name != parent_wf_spec_name: @@ -80,14 +80,15 @@ def resolve_workflow_definition(parent_wf_name, parent_wf_spec_name, wf_full_name = "%s.%s" % (wb_name, wf_spec_name) - wf_def = db_api.load_workflow_definition(wf_full_name) + wf_def = db_api.load_workflow_definition(wf_full_name, namespace) if not wf_def: - wf_def = db_api.load_workflow_definition(wf_spec_name) + wf_def = db_api.load_workflow_definition(wf_spec_name, namespace) if not wf_def: raise exc.WorkflowException( - "Failed to find workflow [name=%s]" % wf_spec_name + "Failed to find workflow [name=%s] [namespace=%s]" % + (wf_spec_name, namespace) ) return wf_def diff --git a/mistral/engine/workflow_handler.py b/mistral/engine/workflow_handler.py index 887a4a67e..06852ecd7 100644 --- a/mistral/engine/workflow_handler.py +++ b/mistral/engine/workflow_handler.py @@ -33,11 +33,16 @@ _CHECK_AND_COMPLETE_PATH = ( @profiler.trace('workflow-handler-start-workflow', hide_args=True) -def start_workflow(wf_identifier, wf_input, desc, params): +def start_workflow(wf_identifier, wf_namespace, wf_input, desc, params): wf = workflows.Workflow() + wf_def = db_api.get_workflow_definition(wf_identifier, wf_namespace) + + if 'namespace' not in params: + params['namespace'] = wf_def.namespace + wf.start( - wf_def=db_api.get_workflow_definition(wf_identifier), + wf_def=wf_def, input_dict=wf_input, desc=desc, params=params diff --git a/mistral/engine/workflows.py b/mistral/engine/workflows.py index 1de836624..82f42864b 100644 --- a/mistral/engine/workflows.py +++ b/mistral/engine/workflows.py @@ -233,6 +233,7 @@ class Workflow(object): 'name': wf_def.name, 'description': desc, 'workflow_name': wf_def.name, + 'workflow_namespace': wf_def.namespace, 'workflow_id': wf_def.id, 'spec': self.wf_spec.to_dict(), 'state': states.IDLE, diff --git a/mistral/rpc/clients.py b/mistral/rpc/clients.py index ec6dc7d16..1cdaa96cb 100644 --- a/mistral/rpc/clients.py +++ b/mistral/rpc/clients.py @@ -79,8 +79,8 @@ class EngineClient(eng.Engine): self._client = base.get_rpc_client_driver()(rpc_conf_dict) @base.wrap_messaging_exception - def start_workflow(self, wf_identifier, wf_input, description='', - **params): + def start_workflow(self, wf_identifier, wf_namespace, wf_input=None, + description='', **params): """Starts workflow sending a request to engine over RPC. :return: Workflow execution. @@ -89,6 +89,7 @@ class EngineClient(eng.Engine): auth_ctx.ctx(), 'start_workflow', workflow_identifier=wf_identifier, + workflow_namespace=wf_namespace, workflow_input=wf_input or {}, description=description, params=params diff --git a/mistral/services/workbooks.py b/mistral/services/workbooks.py index b1bb5ab76..1e9ab184d 100644 --- a/mistral/services/workbooks.py +++ b/mistral/services/workbooks.py @@ -99,6 +99,7 @@ def _create_or_update_workflows(wb_db, workflows_spec): 'spec': wf_spec.to_dict(), 'scope': wb_db.scope, 'project_id': wb_db.project_id, + 'namespace': '', 'tags': wf_spec.get_tags() } diff --git a/mistral/services/workflows.py b/mistral/services/workflows.py index c71472fb5..73a57a55f 100644 --- a/mistral/services/workflows.py +++ b/mistral/services/workflows.py @@ -36,7 +36,8 @@ def register_standard_workflows(run_in_tx=True): workflow_definition, scope='public', is_system=True, - run_in_tx=run_in_tx + run_in_tx=run_in_tx, + namespace='' ) @@ -52,7 +53,7 @@ def sync_db(): def create_workflows(definition, scope='private', is_system=False, - run_in_tx=True): + run_in_tx=True, namespace=''): LOG.debug("creating workflows") wf_list_spec = spec_parser.get_workflow_list_spec_from_yaml(definition) db_wfs = [] @@ -63,6 +64,7 @@ def create_workflows(definition, scope='private', is_system=False, definition, is_system, scope, + namespace, wf_list_spec, db_wfs ) @@ -71,6 +73,7 @@ def create_workflows(definition, scope='private', is_system=False, definition, is_system, scope, + namespace, wf_list_spec, db_wfs ) @@ -78,14 +81,22 @@ def create_workflows(definition, scope='private', is_system=False, return db_wfs -def _append_all_workflows(definition, is_system, scope, wf_list_spec, db_wfs): +def _append_all_workflows(definition, is_system, scope, namespace, + wf_list_spec, db_wfs): for wf_spec in wf_list_spec.get_workflows(): db_wfs.append( - _create_workflow(wf_spec, definition, scope, is_system) + _create_workflow( + wf_spec, + definition, + scope, + namespace, + is_system + ) ) -def update_workflows(definition, scope='private', identifier=None): +def update_workflows(definition, scope='private', identifier=None, + namespace=''): LOG.debug("updating workflows") wf_list_spec = spec_parser.get_workflow_list_spec_from_yaml(definition) wfs = wf_list_spec.get_workflows() @@ -105,6 +116,7 @@ def update_workflows(definition, scope='private', identifier=None): wf_spec, definition, scope, + namespace=namespace, identifier=identifier )) @@ -128,29 +140,33 @@ def update_workflow_execution_env(wf_ex, env): return wf_ex -def _get_workflow_values(wf_spec, definition, scope, is_system=False): +def _get_workflow_values(wf_spec, definition, scope, namespace=None, + is_system=False): values = { 'name': wf_spec.get_name(), 'tags': wf_spec.get_tags(), 'definition': definition, 'spec': wf_spec.to_dict(), 'scope': scope, + 'namespace': namespace, 'is_system': is_system } return values -def _create_workflow(wf_spec, definition, scope, is_system): +def _create_workflow(wf_spec, definition, scope, namespace, is_system): return db_api.create_workflow_definition( - _get_workflow_values(wf_spec, definition, scope, is_system) + _get_workflow_values(wf_spec, definition, scope, namespace, is_system) ) -def _update_workflow(wf_spec, definition, scope, identifier=None): - values = _get_workflow_values(wf_spec, definition, scope) +def _update_workflow(wf_spec, definition, scope, identifier=None, + namespace=''): + values = _get_workflow_values(wf_spec, definition, scope, namespace) return db_api.update_workflow_definition( identifier if identifier else values['name'], - values + values, + namespace=namespace ) diff --git a/mistral/tests/resources/for_wf_namespace/lowest_level_wf.yaml b/mistral/tests/resources/for_wf_namespace/lowest_level_wf.yaml new file mode 100644 index 000000000..5d873f26f --- /dev/null +++ b/mistral/tests/resources/for_wf_namespace/lowest_level_wf.yaml @@ -0,0 +1,6 @@ +--- +version: '2.0' +lowest_level_wf: + tasks: + noop_task: + action: std.noop \ No newline at end of file diff --git a/mistral/tests/resources/for_wf_namespace/middle_wf.yaml b/mistral/tests/resources/for_wf_namespace/middle_wf.yaml new file mode 100644 index 000000000..e0cc2952f --- /dev/null +++ b/mistral/tests/resources/for_wf_namespace/middle_wf.yaml @@ -0,0 +1,6 @@ +--- +version: '2.0' +middle_wf: + tasks: + run_workflow_with_name_lowest_level_wf: + workflow: lowest_level_wf \ No newline at end of file diff --git a/mistral/tests/resources/for_wf_namespace/top_level_wf.yaml b/mistral/tests/resources/for_wf_namespace/top_level_wf.yaml new file mode 100644 index 000000000..2bedcb1ec --- /dev/null +++ b/mistral/tests/resources/for_wf_namespace/top_level_wf.yaml @@ -0,0 +1,6 @@ +--- +version: '2.0' +top_level_wf: + tasks: + run_workflow_with_name_middle_wf: + workflow: middle_wf \ No newline at end of file diff --git a/mistral/tests/unit/api/v2/test_executions.py b/mistral/tests/unit/api/v2/test_executions.py index 1bf6a43a1..16c748f53 100644 --- a/mistral/tests/unit/api/v2/test_executions.py +++ b/mistral/tests/unit/api/v2/test_executions.py @@ -468,6 +468,7 @@ class TestExecutionsController(base.APITest): f.assert_called_once_with( exec_dict['workflow_id'], + '', json.loads(exec_dict['input']), exec_dict['description'], **json.loads(exec_dict['params']) diff --git a/mistral/tests/unit/api/v2/test_members.py b/mistral/tests/unit/api/v2/test_members.py index 13f0fb5b1..5df6108e4 100644 --- a/mistral/tests/unit/api/v2/test_members.py +++ b/mistral/tests/unit/api/v2/test_members.py @@ -167,9 +167,7 @@ class TestMembersController(base.APITest): def test_get_memberships_nonexistent_wf(self, auth_mock): nonexistent_wf_id = uuidutils.generate_uuid() - resp = self.app.get( - '/v2/workflows/%s/members' % nonexistent_wf_id, - ) + resp = self.app.get('/v2/workflows/%s/members' % nonexistent_wf_id) self.assertEqual(200, resp.status_int) self.assertEqual(0, len(resp.json['members'])) diff --git a/mistral/tests/unit/api/v2/test_workflows.py b/mistral/tests/unit/api/v2/test_workflows.py index fc10367e8..dde85afc0 100644 --- a/mistral/tests/unit/api/v2/test_workflows.py +++ b/mistral/tests/unit/api/v2/test_workflows.py @@ -60,6 +60,26 @@ WF = { 'input': 'param1' } +WF_DB_WITHIN_ABC_NAMESPACE = models.WorkflowDefinition( + id='234560fe-162a-4060-a16a-a0d9eee9b408', + name='flow', + namespace='abc', + definition=WF_DEFINITION, + created_at=datetime.datetime(1970, 1, 1), + updated_at=datetime.datetime(1970, 1, 1), + spec={'input': ['param1']} +) + +WF_WITH_NAMESPACE = { + 'id': '234560fe-162a-4060-a16a-a0d9eee9b408', + 'name': 'flow', + 'namespace': 'abc', + 'definition': WF_DEFINITION, + 'created_at': '1970-01-01 00:00:00', + 'updated_at': '1970-01-01 00:00:00', + 'input': 'param1' +} + WF_DEFINITION_WITH_INPUT = """ --- version: '2.0' @@ -218,7 +238,8 @@ class TestWorkflowsController(base.APITest): update_mock.assert_called_once_with( UPDATED_WF_DEFINITION, scope='private', - identifier='123e4567-e89b-12d3-a456-426655440000' + identifier='123e4567-e89b-12d3-a456-426655440000', + namespace='' ) self.assertDictEqual(UPDATED_WF, resp.json) @@ -603,3 +624,45 @@ class TestWorkflowsController(base.APITest): self.assertEqual(200, resp.status_int) self.assertFalse(resp.json['valid']) self.assertIn("Invalid DSL", resp.json['error']) + + @mock.patch("mistral.services.workflows.update_workflows") + @mock.patch.object(db_api, "create_workflow_definition") + def test_workflow_within_namespace(self, mock_mtd, update_mock): + mock_mtd.return_value = WF_DB_WITHIN_ABC_NAMESPACE + + namespace = 'abc' + resp = self.app.post( + '/v2/workflows?namespace=%s' % namespace, + WF_DEFINITION, + headers={'Content-Type': 'text/plain'} + ) + + self.assertEqual(201, resp.status_int) + self.assertDictEqual({'workflows': [WF_WITH_NAMESPACE]}, resp.json) + + self.assertEqual(1, mock_mtd.call_count) + + spec = mock_mtd.call_args[0][0]['spec'] + + self.assertIsNotNone(spec) + self.assertEqual(WF_DB.name, spec['name']) + self.assertEqual(WF_DB_WITHIN_ABC_NAMESPACE.namespace, namespace) + + update_mock.return_value = [WF_DB_WITHIN_ABC_NAMESPACE] + + id_ = '234560fe-162a-4060-a16a-a0d9eee9b408' + + resp = self.app.put( + '/v2/workflows/%s?namespace=%s' % (id_, namespace), + WF_DEFINITION, + headers={'Content-Type': 'text/plain'} + ) + + self.assertEqual(200, resp.status_int) + update_mock.assert_called_once_with( + WF_DEFINITION, + scope='private', + identifier=id_, + namespace='abc' + ) + self.assertDictEqual(WF_WITH_NAMESPACE, resp.json) diff --git a/mistral/tests/unit/db/v2/test_sqlalchemy_db_api.py b/mistral/tests/unit/db/v2/test_sqlalchemy_db_api.py index 7008204c7..ffa48a3a5 100644 --- a/mistral/tests/unit/db/v2/test_sqlalchemy_db_api.py +++ b/mistral/tests/unit/db/v2/test_sqlalchemy_db_api.py @@ -373,7 +373,8 @@ WF_DEFINITIONS = [ 'scope': 'public', 'project_id': '1233', 'trust_id': '1234', - 'created_at': datetime.datetime(2016, 12, 1, 15, 0, 0) + 'created_at': datetime.datetime(2016, 12, 1, 15, 0, 0), + 'namespace': '' }, { 'name': 'my_wf2', @@ -383,7 +384,8 @@ WF_DEFINITIONS = [ 'scope': 'private', 'project_id': '1233', 'trust_id': '12345', - 'created_at': datetime.datetime(2016, 12, 1, 15, 1, 0) + 'created_at': datetime.datetime(2016, 12, 1, 15, 1, 0), + 'namespace': '' }, ] diff --git a/mistral/tests/unit/engine/test_action_context.py b/mistral/tests/unit/engine/test_action_context.py index 344996442..41ac61d82 100644 --- a/mistral/tests/unit/engine/test_action_context.py +++ b/mistral/tests/unit/engine/test_action_context.py @@ -60,7 +60,7 @@ class ActionContextTest(base.EngineTestCase): def test_action_context(self): wb_service.create_workbook_v2(WORKBOOK) - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1') self.await_workflow_success(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_action_defaults.py b/mistral/tests/unit/engine/test_action_defaults.py index cd68c398a..4cdb3466c 100644 --- a/mistral/tests/unit/engine/test_action_defaults.py +++ b/mistral/tests/unit/engine/test_action_defaults.py @@ -105,7 +105,7 @@ class ActionDefaultTest(base.EngineTestCase): def test_action_defaults_from_env(self): wf_service.create_workflows(WORKFLOW1) - wf_ex = self.engine.start_workflow('wf1', None, env=ENV) + wf_ex = self.engine.start_workflow('wf1', env=ENV) self.await_workflow_success(wf_ex.id) @@ -131,7 +131,7 @@ class ActionDefaultTest(base.EngineTestCase): def test_action_defaults_from_env_not_applied(self): wf_service.create_workflows(WORKFLOW2) - wf_ex = self.engine.start_workflow('wf2', None, env=ENV) + wf_ex = self.engine.start_workflow('wf2', env=ENV) self.await_workflow_success(wf_ex.id) @@ -167,6 +167,7 @@ class ActionDefaultTest(base.EngineTestCase): wf_ex = self.engine.start_workflow( 'wf1_with_items', + '', wf_input, env=ENV ) @@ -206,6 +207,7 @@ class ActionDefaultTest(base.EngineTestCase): wf_ex = self.engine.start_workflow( 'wf2_with_items', + '', wf_input, env=ENV ) diff --git a/mistral/tests/unit/engine/test_adhoc_actions.py b/mistral/tests/unit/engine/test_adhoc_actions.py index c46dda0b2..41ae39a8e 100644 --- a/mistral/tests/unit/engine/test_adhoc_actions.py +++ b/mistral/tests/unit/engine/test_adhoc_actions.py @@ -112,6 +112,7 @@ class AdhocActionsTest(base.EngineTestCase): def test_run_workflow_with_adhoc_action(self): wf_ex = self.engine.start_workflow( 'my_wb.wf1', + '', {'str1': 'a', 'str2': 'b'} ) @@ -131,6 +132,7 @@ class AdhocActionsTest(base.EngineTestCase): def test_run_adhoc_action_without_input_value(self): wf_ex = self.engine.start_workflow( 'my_wb.wf2', + '', {'str1': 'a', 'str2': 'b'} ) @@ -149,6 +151,7 @@ class AdhocActionsTest(base.EngineTestCase): def test_run_adhoc_action_without_sufficient_input_value(self): wf_ex = self.engine.start_workflow( 'my_wb.wf3', + '', {'str1': 'a', 'str2': 'b'} ) @@ -157,7 +160,7 @@ class AdhocActionsTest(base.EngineTestCase): def test_run_adhoc_action_with_env(self): wf_ex = self.engine.start_workflow( - 'my_wb.wf4', {'str1': 'a'}, env={'foo': 'bar'}) + 'my_wb.wf4', '', {'str1': 'a'}, env={'foo': 'bar'}) self.await_workflow_success(wf_ex.id) with db_api.transaction(): diff --git a/mistral/tests/unit/engine/test_commands.py b/mistral/tests/unit/engine/test_commands.py index 812231c1c..4f2aa8ed1 100644 --- a/mistral/tests/unit/engine/test_commands.py +++ b/mistral/tests/unit/engine/test_commands.py @@ -58,7 +58,7 @@ class SimpleEngineCommandsTest(base.EngineTestCase): wb_service.create_workbook_v2(WORKBOOK1) def test_fail(self): - wf_ex = self.engine.start_workflow('my_wb.wf', {'my_var': 1}) + wf_ex = self.engine.start_workflow('my_wb.wf', '', {'my_var': 1}) self.await_workflow_error(wf_ex.id) @@ -75,7 +75,7 @@ class SimpleEngineCommandsTest(base.EngineTestCase): ) def test_succeed(self): - wf_ex = self.engine.start_workflow('my_wb.wf', {'my_var': 2}) + wf_ex = self.engine.start_workflow('my_wb.wf', '', {'my_var': 2}) self.await_workflow_success(wf_ex.id) @@ -92,7 +92,7 @@ class SimpleEngineCommandsTest(base.EngineTestCase): ) def test_pause(self): - wf_ex = self.engine.start_workflow('my_wb.wf', {'my_var': 3}) + wf_ex = self.engine.start_workflow('my_wb.wf', '', {'my_var': 3}) self.await_workflow_paused(wf_ex.id) @@ -144,7 +144,7 @@ class SimpleEngineWorkflowLevelCommandsTest(base.EngineTestCase): wb_service.create_workbook_v2(WORKBOOK2) def test_fail(self): - wf_ex = self.engine.start_workflow('my_wb.wf', {'my_var': 1}) + wf_ex = self.engine.start_workflow('my_wb.wf', '', {'my_var': 1}) self.await_workflow_error(wf_ex.id) @@ -161,7 +161,7 @@ class SimpleEngineWorkflowLevelCommandsTest(base.EngineTestCase): ) def test_succeed(self): - wf_ex = self.engine.start_workflow('my_wb.wf', {'my_var': 2}) + wf_ex = self.engine.start_workflow('my_wb.wf', '', {'my_var': 2}) self.await_workflow_success(wf_ex.id) @@ -178,7 +178,7 @@ class SimpleEngineWorkflowLevelCommandsTest(base.EngineTestCase): ) def test_pause(self): - wf_ex = self.engine.start_workflow('my_wb.wf', {'my_var': 3}) + wf_ex = self.engine.start_workflow('my_wb.wf', '', {'my_var': 3}) self.await_workflow_paused(wf_ex.id) @@ -263,7 +263,7 @@ class OrderEngineCommandsTest(base.EngineTestCase): wb_service.create_workbook_v2(WORKBOOK3) def test_fail_first(self): - wf_ex = self.engine.start_workflow('my_wb.fail_first_wf', None) + wf_ex = self.engine.start_workflow('my_wb.fail_first_wf', '', None) self.await_workflow_error(wf_ex.id) @@ -280,7 +280,7 @@ class OrderEngineCommandsTest(base.EngineTestCase): ) def test_fail_second(self): - wf_ex = self.engine.start_workflow('my_wb.fail_second_wf', None) + wf_ex = self.engine.start_workflow('my_wb.fail_second_wf', '', None) self.await_workflow_error(wf_ex.id) @@ -301,7 +301,7 @@ class OrderEngineCommandsTest(base.EngineTestCase): self.await_workflow_error(wf_ex.id) def test_succeed_first(self): - wf_ex = self.engine.start_workflow('my_wb.succeed_first_wf', None) + wf_ex = self.engine.start_workflow('my_wb.succeed_first_wf', '', None) self.await_workflow_success(wf_ex.id) @@ -318,7 +318,7 @@ class OrderEngineCommandsTest(base.EngineTestCase): ) def test_succeed_second(self): - wf_ex = self.engine.start_workflow('my_wb.succeed_second_wf', None) + wf_ex = self.engine.start_workflow('my_wb.succeed_second_wf', '', None) self.await_workflow_success(wf_ex.id) @@ -371,7 +371,7 @@ class SimpleEngineCmdsWithMsgTest(base.EngineTestCase): wb_service.create_workbook_v2(WORKBOOK4) def test_fail(self): - wf_ex = self.engine.start_workflow('my_wb.wf', {'my_var': 1}) + wf_ex = self.engine.start_workflow('my_wb.wf', '', {'my_var': 1}) self.await_workflow_error(wf_ex.id) @@ -390,7 +390,7 @@ class SimpleEngineCmdsWithMsgTest(base.EngineTestCase): self.assertEqual('my_var value is 1', wf_ex.state_info) def test_succeed(self): - wf_ex = self.engine.start_workflow('my_wb.wf', {'my_var': 2}) + wf_ex = self.engine.start_workflow('my_wb.wf', '', {'my_var': 2}) self.await_workflow_success(wf_ex.id) @@ -409,7 +409,7 @@ class SimpleEngineCmdsWithMsgTest(base.EngineTestCase): self.assertEqual("my_var value is 2", wf_ex.state_info) def test_pause(self): - wf_ex = self.engine.start_workflow('my_wb.wf', {'my_var': 3}) + wf_ex = self.engine.start_workflow('my_wb.wf', '', {'my_var': 3}) self.await_workflow_paused(wf_ex.id) @@ -462,7 +462,7 @@ class SimpleEngineWorkflowLevelCmdsWithMsgTest(base.EngineTestCase): wb_service.create_workbook_v2(WORKBOOK5) def test_fail(self): - wf_ex = self.engine.start_workflow('my_wb.wf', {'my_var': 1}) + wf_ex = self.engine.start_workflow('my_wb.wf', '', {'my_var': 1}) self.await_workflow_error(wf_ex.id) @@ -481,7 +481,7 @@ class SimpleEngineWorkflowLevelCmdsWithMsgTest(base.EngineTestCase): self.assertEqual("my_var value is 1", wf_ex.state_info) def test_succeed(self): - wf_ex = self.engine.start_workflow('my_wb.wf', {'my_var': 2}) + wf_ex = self.engine.start_workflow('my_wb.wf', '', {'my_var': 2}) self.await_workflow_success(wf_ex.id) @@ -500,7 +500,7 @@ class SimpleEngineWorkflowLevelCmdsWithMsgTest(base.EngineTestCase): self.assertEqual("my_var value is 2", wf_ex.state_info) def test_pause(self): - wf_ex = self.engine.start_workflow('my_wb.wf', {'my_var': 3}) + wf_ex = self.engine.start_workflow('my_wb.wf', '', {'my_var': 3}) self.await_workflow_paused(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_dataflow.py b/mistral/tests/unit/engine/test_dataflow.py index 7026a075d..e64e58942 100644 --- a/mistral/tests/unit/engine/test_dataflow.py +++ b/mistral/tests/unit/engine/test_dataflow.py @@ -63,7 +63,7 @@ class DataFlowEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(linear_wf) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}, env={'from': 'Neo'}) + wf_ex = self.engine.start_workflow('wf', '', {}, env={'from': 'Neo'}) self.await_workflow_success(wf_ex.id) @@ -133,7 +133,7 @@ class DataFlowEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(linear_with_branches_wf) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}, env={'from': 'Neo'}) + wf_ex = self.engine.start_workflow('wf', '', {}, env={'from': 'Neo'}) self.await_workflow_success(wf_ex.id) @@ -208,7 +208,7 @@ class DataFlowEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(parallel_tasks_wf) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -286,7 +286,7 @@ class DataFlowEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(parallel_tasks_complex_wf) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -367,6 +367,7 @@ class DataFlowEngineTest(engine_test_base.EngineTestCase): # Start workflow. wf_ex = self.engine.start_workflow( 'wf', + '', {}, env={'from': 'Neo'} ) @@ -425,6 +426,7 @@ class DataFlowEngineTest(engine_test_base.EngineTestCase): # Start workflow. wf_ex = self.engine.start_workflow( 'wf', + '', {}, env={'from': 'Neo'} ) @@ -482,7 +484,7 @@ class DataFlowEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(linear_wf) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -517,7 +519,7 @@ class DataFlowEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(linear_wf) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -557,7 +559,7 @@ class DataFlowEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(wf) # Start workflow. - wf_ex = self.engine.start_workflow('wf1_with_items', {}) + wf_ex = self.engine.start_workflow('wf1_with_items', '', {}) self.await_workflow_success(wf_ex.id) @@ -595,7 +597,7 @@ class DataFlowEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(wf_def) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -655,7 +657,7 @@ class DataFlowEngineTest(engine_test_base.EngineTestCase): wb_service.create_workbook_v2(wb_def) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) self.await_workflow_error(wf_ex.id) @@ -701,7 +703,7 @@ class DataFlowEngineTest(engine_test_base.EngineTestCase): } # Start workflow. - wf_ex = self.engine.start_workflow('wf', wf_input) + wf_ex = self.engine.start_workflow('wf', '', wf_input) self.await_workflow_success(wf_ex.id) @@ -734,7 +736,7 @@ class DataFlowEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -773,7 +775,7 @@ class DataFlowEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -817,7 +819,7 @@ class DataFlowEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -858,7 +860,7 @@ class DataFlowEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -905,7 +907,7 @@ class DataFlowEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_default_engine.py b/mistral/tests/unit/engine/test_default_engine.py index 21cd79987..93fd21d8c 100644 --- a/mistral/tests/unit/engine/test_default_engine.py +++ b/mistral/tests/unit/engine/test_default_engine.py @@ -110,6 +110,7 @@ class DefaultEngineTest(base.DbTestCase): # Start workflow. wf_ex = self.engine.start_workflow( 'wb.wf', + '', wf_input, 'my execution', task_name='task2' @@ -154,6 +155,7 @@ class DefaultEngineTest(base.DbTestCase): # Start workflow. wf_ex = self.engine.start_workflow( 'wb.wf', + '', wf_input, task_name='task1' ) @@ -200,6 +202,7 @@ class DefaultEngineTest(base.DbTestCase): # Start workflow. wf_ex = self.engine.start_workflow( 'wb.wf', + '', wf_input, env=env, task_name='task2') @@ -221,6 +224,7 @@ class DefaultEngineTest(base.DbTestCase): # Start workflow. wf_ex = self.engine.start_workflow( 'wb.wf', + '', wf_input, env='test', task_name='task2' @@ -238,6 +242,7 @@ class DefaultEngineTest(base.DbTestCase): exc.InputException, self.engine.start_workflow, 'wb.wf', + '', { 'param1': '<% env().key1 %>', 'param2': 'some value' @@ -253,6 +258,7 @@ class DefaultEngineTest(base.DbTestCase): exc.InputException, self.engine.start_workflow, 'wb.wf', + '', { 'param1': '<% env().key1 %>', 'param2': 'some value' @@ -268,6 +274,7 @@ class DefaultEngineTest(base.DbTestCase): exc.InputException, self.engine.start_workflow, 'wb.wf', + '', None, task_name='task2' ) @@ -280,6 +287,7 @@ class DefaultEngineTest(base.DbTestCase): exc.InputException, self.engine.start_workflow, 'wb.wf', + '', { 'param1': 'Hey', 'param2': 'Hi', @@ -297,6 +305,7 @@ class DefaultEngineTest(base.DbTestCase): # Start workflow. wf_ex = self.engine.start_workflow( 'wb.wf', + '', wf_input, task_name='task2' ) @@ -410,6 +419,7 @@ class DefaultEngineTest(base.DbTestCase): # Start workflow. wf_ex = self.engine.start_workflow( 'wb.wf', + '', { 'param1': 'Hey', 'param2': 'Hi' @@ -432,6 +442,7 @@ class DefaultEngineTest(base.DbTestCase): # Start workflow. wf_ex = self.engine.start_workflow( 'wb.wf', + '', { 'param1': 'Hey', 'param2': 'Hi' @@ -453,6 +464,7 @@ class DefaultEngineTest(base.DbTestCase): def test_stop_workflow_bad_status(self): wf_ex = self.engine.start_workflow( 'wb.wf', + '', { 'param1': 'Hey', 'param2': 'Hi' diff --git a/mistral/tests/unit/engine/test_direct_workflow.py b/mistral/tests/unit/engine/test_direct_workflow.py index f08159309..988c153fb 100644 --- a/mistral/tests/unit/engine/test_direct_workflow.py +++ b/mistral/tests/unit/engine/test_direct_workflow.py @@ -32,7 +32,7 @@ class DirectWorkflowEngineTest(base.EngineTestCase): def _run_workflow(self, wf_text, expected_state=states.ERROR): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_state(wf_ex.id, expected_state) @@ -113,7 +113,7 @@ class DirectWorkflowEngineTest(base.EngineTestCase): """ wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -147,7 +147,7 @@ class DirectWorkflowEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -243,7 +243,7 @@ class DirectWorkflowEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', None) + wf_ex = self.engine.start_workflow('wf', '', None) self.assertIn( "Failed to find action [action_name=wrong.task]", @@ -406,7 +406,7 @@ class DirectWorkflowEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', None) + wf_ex = self.engine.start_workflow('wf', '', None) self.assertIn( "Can not evaluate YAQL expression [expression=wrong(yaql)", @@ -429,7 +429,7 @@ class DirectWorkflowEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {'var': 2}) + wf_ex = self.engine.start_workflow('wf', '', {'var': 2}) self.assertIn("Can not evaluate YAQL expression", wf_ex.state_info) self.assertEqual(states.ERROR, wf_ex.state) @@ -460,7 +460,7 @@ class DirectWorkflowEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -612,7 +612,7 @@ class DirectWorkflowEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) calls = db_api.get_delayed_calls() @@ -639,7 +639,7 @@ class DirectWorkflowEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) calls = db_api.get_delayed_calls() @@ -670,7 +670,7 @@ class DirectWorkflowEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -705,7 +705,7 @@ class DirectWorkflowEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_direct_workflow_rerun.py b/mistral/tests/unit/engine/test_direct_workflow_rerun.py index e1b9f9e22..a0ac0a107 100644 --- a/mistral/tests/unit/engine/test_direct_workflow_rerun.py +++ b/mistral/tests/unit/engine/test_direct_workflow_rerun.py @@ -224,7 +224,7 @@ class DirectWorkflowRerunTest(base.EngineTestCase): wb_service.create_workbook_v2(SIMPLE_WORKBOOK) # Run workflow and fail task. - wf_ex = self.engine.start_workflow('wb1.wf1', {}) + wf_ex = self.engine.start_workflow('wb1.wf1', '', {}) self.await_workflow_error(wf_ex.id) @@ -326,7 +326,7 @@ class DirectWorkflowRerunTest(base.EngineTestCase): } # Run workflow and fail task. - wf_ex = self.engine.start_workflow('wb1.wf1', {}, env=env) + wf_ex = self.engine.start_workflow('wb1.wf1', '', {}, env=env) self.await_workflow_error(wf_ex.id) @@ -472,7 +472,7 @@ class DirectWorkflowRerunTest(base.EngineTestCase): wb_service.create_workbook_v2(SIMPLE_WORKBOOK) # Run workflow and fail task. - wf_ex = self.engine.start_workflow('wb1.wf1', {}) + wf_ex = self.engine.start_workflow('wb1.wf1', '', {}) self.await_workflow_error(wf_ex.id) @@ -526,7 +526,7 @@ class DirectWorkflowRerunTest(base.EngineTestCase): wb_service.create_workbook_v2(WITH_ITEMS_WORKBOOK) # Run workflow and fail task. - wf_ex = self.engine.start_workflow('wb3.wf1', {}) + wf_ex = self.engine.start_workflow('wb3.wf1', '', {}) self.await_workflow_error(wf_ex.id) @@ -618,7 +618,7 @@ class DirectWorkflowRerunTest(base.EngineTestCase): wb_service.create_workbook_v2(WITH_ITEMS_WORKBOOK_CONCURRENCY) # Run workflow and fail task. - wf_ex = self.engine.start_workflow('wb3.wf1', {}) + wf_ex = self.engine.start_workflow('wb3.wf1', '', {}) self.await_workflow_error(wf_ex.id) @@ -700,7 +700,7 @@ class DirectWorkflowRerunTest(base.EngineTestCase): env = {'var1': 'fee fi fo fum'} # Run workflow and fail task. - wf_ex = self.engine.start_workflow('wb3.wf1', {}, env=env) + wf_ex = self.engine.start_workflow('wb3.wf1', '', {}, env=env) self.await_workflow_error(wf_ex.id) @@ -806,7 +806,7 @@ class DirectWorkflowRerunTest(base.EngineTestCase): wb_service.create_workbook_v2(JOIN_WORKBOOK) # Run workflow and fail task. - wf_ex = self.engine.start_workflow('wb1.wf1', {}) + wf_ex = self.engine.start_workflow('wb1.wf1', '', {}) wf_ex = db_api.get_workflow_execution(wf_ex.id) @@ -905,7 +905,7 @@ class DirectWorkflowRerunTest(base.EngineTestCase): wb_service.create_workbook_v2(JOIN_WORKBOOK) # Run workflow and fail task. - wf_ex = self.engine.start_workflow('wb1.wf1', {}) + wf_ex = self.engine.start_workflow('wb1.wf1', '', {}) with db_api.transaction(): wf_ex = db_api.get_workflow_execution(wf_ex.id) @@ -1057,7 +1057,7 @@ class DirectWorkflowRerunTest(base.EngineTestCase): wb_service.create_workbook_v2(WITH_ITEMS_WORKBOOK) # Run workflow and fail task. - wf_ex = self.engine.start_workflow('wb3.wf1', {}) + wf_ex = self.engine.start_workflow('wb3.wf1', '', {}) self.await_workflow_error(wf_ex.id) @@ -1206,7 +1206,7 @@ class DirectWorkflowRerunTest(base.EngineTestCase): wb_service.create_workbook_v2(SUBFLOW_WORKBOOK) # Run workflow and fail task. - wf_ex = self.engine.start_workflow('wb1.wf1', {}) + wf_ex = self.engine.start_workflow('wb1.wf1', '', {}) self.await_workflow_error(wf_ex.id) @@ -1299,7 +1299,7 @@ class DirectWorkflowRerunTest(base.EngineTestCase): wb_service.create_workbook_v2(SUBFLOW_WORKBOOK) # Run workflow and fail task. - wf_ex = self.engine.start_workflow('wb1.wf1', {}) + wf_ex = self.engine.start_workflow('wb1.wf1', '', {}) self.await_workflow_error(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_direct_workflow_rerun_cancelled.py b/mistral/tests/unit/engine/test_direct_workflow_rerun_cancelled.py index 5240c6d59..9ba1353d5 100644 --- a/mistral/tests/unit/engine/test_direct_workflow_rerun_cancelled.py +++ b/mistral/tests/unit/engine/test_direct_workflow_rerun_cancelled.py @@ -65,7 +65,7 @@ class DirectWorkflowRerunCancelledTest(base.EngineTestCase): wb_service.create_workbook_v2(wb_def) - wf1_ex = self.engine.start_workflow('wb1.wf1', {}) + wf1_ex = self.engine.start_workflow('wb1.wf1', '', {}) self.await_workflow_state(wf1_ex.id, states.RUNNING) @@ -232,7 +232,7 @@ class DirectWorkflowRerunCancelledTest(base.EngineTestCase): wb_service.create_workbook_v2(wb_def) - wf1_ex = self.engine.start_workflow('wb1.wf1', {}) + wf1_ex = self.engine.start_workflow('wb1.wf1', '', {}) self.await_workflow_state(wf1_ex.id, states.RUNNING) @@ -402,7 +402,7 @@ class DirectWorkflowRerunCancelledTest(base.EngineTestCase): wb_service.create_workbook_v2(wb_def) - wf1_ex = self.engine.start_workflow('wb1.wf1', {}) + wf1_ex = self.engine.start_workflow('wb1.wf1', '', {}) self.await_workflow_state(wf1_ex.id, states.RUNNING) @@ -561,7 +561,7 @@ class DirectWorkflowRerunCancelledTest(base.EngineTestCase): wb_service.create_workbook_v2(wb_def) - wf1_ex = self.engine.start_workflow('wb1.wf1', {}) + wf1_ex = self.engine.start_workflow('wb1.wf1', '', {}) self.await_workflow_state(wf1_ex.id, states.RUNNING) diff --git a/mistral/tests/unit/engine/test_direct_workflow_with_cycles.py b/mistral/tests/unit/engine/test_direct_workflow_with_cycles.py index 77cd55324..661cb1351 100644 --- a/mistral/tests/unit/engine/test_direct_workflow_with_cycles.py +++ b/mistral/tests/unit/engine/test_direct_workflow_with_cycles.py @@ -58,7 +58,7 @@ class DirectWorkflowWithCyclesTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf') self.await_workflow_success(wf_ex.id) @@ -120,7 +120,7 @@ class DirectWorkflowWithCyclesTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -195,7 +195,7 @@ class DirectWorkflowWithCyclesTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_environment.py b/mistral/tests/unit/engine/test_environment.py index 78f1a0ffb..f4bb1640b 100644 --- a/mistral/tests/unit/engine/test_environment.py +++ b/mistral/tests/unit/engine/test_environment.py @@ -104,7 +104,7 @@ class EnvironmentTest(base.EngineTestCase): @mock.patch.object(r_exe.RemoteExecutor, 'run_action', MOCK_RUN_AT_TARGET) def _test_subworkflow(self, env): - wf2_ex = self.engine.start_workflow('my_wb.wf2', {}, env=env) + wf2_ex = self.engine.start_workflow('my_wb.wf2', '', {}, env=env) # Execution of 'wf2'. self.assertIsNotNone(wf2_ex) @@ -225,6 +225,7 @@ class EnvironmentTest(base.EngineTestCase): wf_ex = self.engine.start_workflow( 'wf', + '', {}, env=env, evaluate_env=True @@ -249,6 +250,7 @@ class EnvironmentTest(base.EngineTestCase): wf_ex = self.engine.start_workflow( 'wf', + '', {}, env=env, evaluate_env=False @@ -297,6 +299,7 @@ class EnvironmentTest(base.EngineTestCase): parent_wf_ex = self.engine.start_workflow( 'parent_wf', + '', {}, env=env, evaluate_env=False @@ -329,6 +332,7 @@ class EnvironmentTest(base.EngineTestCase): parent_wf_ex = self.engine.start_workflow( 'parent_wf', + '', {}, env=env, evaluate_env=True diff --git a/mistral/tests/unit/engine/test_error_handling.py b/mistral/tests/unit/engine/test_error_handling.py index 46ec536f3..4b53a51e3 100644 --- a/mistral/tests/unit/engine/test_error_handling.py +++ b/mistral/tests/unit/engine/test_error_handling.py @@ -62,6 +62,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): exc.InputException, self.engine.start_workflow, 'wf', + '', {'wrong_param': 'some_value'} ) @@ -87,7 +88,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.assertEqual(states.RUNNING, wf_ex.state) self.assertIsNotNone(db_api.get_workflow_execution(wf_ex.id)) @@ -118,7 +119,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -148,7 +149,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -206,7 +207,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -257,7 +258,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -309,7 +310,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -357,7 +358,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -398,7 +399,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -426,7 +427,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -453,7 +454,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -481,7 +482,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -510,7 +511,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -545,7 +546,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -584,7 +585,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wb_service.create_workbook_v2(wb_text) - wf_ex = self.engine.start_workflow('wb.wf', {}) + wf_ex = self.engine.start_workflow('wb.wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -620,7 +621,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -656,7 +657,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -687,7 +688,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -727,7 +728,7 @@ class ErrorHandlingEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_error_result.py b/mistral/tests/unit/engine/test_error_result.py index de4c7cf87..13c7877f3 100644 --- a/mistral/tests/unit/engine/test_error_result.py +++ b/mistral/tests/unit/engine/test_error_result.py @@ -83,6 +83,7 @@ class ErrorResultTest(base.EngineTestCase): # Start workflow. wf_ex = self.engine.start_workflow( 'wf', + '', { 'success_result': None, 'error_result': 2 @@ -116,6 +117,7 @@ class ErrorResultTest(base.EngineTestCase): # Start workflow. wf_ex = self.engine.start_workflow( 'wf', + '', { 'success_result': None, 'error_result': 3 @@ -149,6 +151,7 @@ class ErrorResultTest(base.EngineTestCase): # Start workflow. wf_ex = self.engine.start_workflow( 'wf', + '', { 'success_result': 'success', 'error_result': None diff --git a/mistral/tests/unit/engine/test_execution_fields_size_limitation.py b/mistral/tests/unit/engine/test_execution_fields_size_limitation.py index 4bcaa140a..1cfb61f0a 100644 --- a/mistral/tests/unit/engine/test_execution_fields_size_limitation.py +++ b/mistral/tests/unit/engine/test_execution_fields_size_limitation.py @@ -123,7 +123,7 @@ class ExecutionFieldsSizeLimitTest(base.EngineTestCase): wf_service.create_workflows(new_wf) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -137,6 +137,7 @@ class ExecutionFieldsSizeLimitTest(base.EngineTestCase): exc.SizeLimitExceededException, self.engine.start_workflow, 'wf', + '', {} ) @@ -153,6 +154,7 @@ class ExecutionFieldsSizeLimitTest(base.EngineTestCase): exc.SizeLimitExceededException, self.engine.start_workflow, 'wf', + '', {'workflow_input': ''.join('A' for _ in range(1024))} ) @@ -167,7 +169,7 @@ class ExecutionFieldsSizeLimitTest(base.EngineTestCase): wf_service.create_workflows(new_wf) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.assertEqual(states.ERROR, wf_ex.state) self.assertIn( @@ -181,6 +183,7 @@ class ExecutionFieldsSizeLimitTest(base.EngineTestCase): # Start workflow. wf_ex = self.engine.start_workflow( 'wf', + '', {'action_output_length': 1024} ) @@ -201,7 +204,7 @@ class ExecutionFieldsSizeLimitTest(base.EngineTestCase): wf_service.create_workflows(new_wf) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -234,6 +237,7 @@ class ExecutionFieldsSizeLimitTest(base.EngineTestCase): exc.SizeLimitExceededException, self.engine.start_workflow, 'wf', + '', {}, '', env={'param': long_string} @@ -257,6 +261,7 @@ class ExecutionFieldsSizeLimitTest(base.EngineTestCase): # Start workflow. wf_ex = self.engine.start_workflow( 'wf', + '', { 'action_output_length': 80000, 'action_output_dict': True, diff --git a/mistral/tests/unit/engine/test_javascript_action.py b/mistral/tests/unit/engine/test_javascript_action.py index 299c9c0b3..053a26ff6 100644 --- a/mistral/tests/unit/engine/test_javascript_action.py +++ b/mistral/tests/unit/engine/test_javascript_action.py @@ -69,7 +69,7 @@ class JavaScriptEngineTest(base.EngineTestCase): wb_service.create_workbook_v2(WORKBOOK) # Start workflow. - wf_ex = self.engine.start_workflow('test_js.js_test', {'num': 50}) + wf_ex = self.engine.start_workflow('test_js.js_test', '', {'num': 50}) self.await_workflow_success(wf_ex.id) @@ -88,7 +88,7 @@ class JavaScriptEngineTest(base.EngineTestCase): wb_service.create_workbook_v2(WORKBOOK) # Start workflow. - wf_ex = self.engine.start_workflow('test_js.js_test', {'num': 50}) + wf_ex = self.engine.start_workflow('test_js.js_test', '', {'num': 50}) self.await_workflow_success(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_join.py b/mistral/tests/unit/engine/test_join.py index bf153c5db..7f36c633c 100644 --- a/mistral/tests/unit/engine/test_join.py +++ b/mistral/tests/unit/engine/test_join.py @@ -47,7 +47,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -95,7 +95,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -148,7 +148,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -209,7 +209,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) def _num_of_tasks(): return len( @@ -290,7 +290,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -372,7 +372,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -449,7 +449,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -531,7 +531,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wfs_tasks_join_complex) # Start workflow. - wf_ex = self.engine.start_workflow('main', {}) + wf_ex = self.engine.start_workflow('main', '', {}) self.await_workflow_success(wf_ex.id) @@ -596,7 +596,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('main', {}) + wf_ex = self.engine.start_workflow('main', '', {}) self.await_workflow_success(wf_ex.id) @@ -655,7 +655,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('main', {}) + wf_ex = self.engine.start_workflow('main', '', {}) self.await_workflow_error(wf_ex.id) @@ -709,7 +709,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('test-join', {}) + wf_ex = self.engine.start_workflow('test-join', '', {}) self.await_workflow_success(wf_ex.id) @@ -741,7 +741,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -785,7 +785,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -818,7 +818,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -851,7 +851,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) tasks = db_api.get_task_executions(workflow_execution_id=wf_ex.id) @@ -909,7 +909,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) tasks = db_api.get_task_executions(workflow_execution_id=wf_ex.id) @@ -975,7 +975,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -1037,7 +1037,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -1061,7 +1061,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -1119,7 +1119,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -1195,7 +1195,7 @@ class JoinEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_lookup_utils.py b/mistral/tests/unit/engine/test_lookup_utils.py index 720d8331c..862474afd 100644 --- a/mistral/tests/unit/engine/test_lookup_utils.py +++ b/mistral/tests/unit/engine/test_lookup_utils.py @@ -52,7 +52,7 @@ class LookupUtilsTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_paused(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_noop_task.py b/mistral/tests/unit/engine/test_noop_task.py index 77388e070..e7606e6e8 100644 --- a/mistral/tests/unit/engine/test_noop_task.py +++ b/mistral/tests/unit/engine/test_noop_task.py @@ -78,7 +78,7 @@ class NoopTaskEngineTest(base.EngineTestCase): wf_service.create_workflows(WF) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {'num1': 1, 'num2': 1}) + wf_ex = self.engine.start_workflow('wf', '', {'num1': 1, 'num2': 1}) self.await_workflow_success(wf_ex.id) @@ -107,7 +107,7 @@ class NoopTaskEngineTest(base.EngineTestCase): wf_service.create_workflows(WF) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {'num1': 1, 'num2': 2}) + wf_ex = self.engine.start_workflow('wf', '', {'num1': 1, 'num2': 2}) self.await_workflow_success(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_policies.py b/mistral/tests/unit/engine/test_policies.py index 94352b966..650f1ee04 100644 --- a/mistral/tests/unit/engine/test_policies.py +++ b/mistral/tests/unit/engine/test_policies.py @@ -423,7 +423,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(WAIT_BEFORE_WB) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) with db_api.transaction(): # Note: We need to reread execution to access related tasks. @@ -443,7 +443,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(WAIT_BEFORE_FROM_VAR) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {'wait_before': 1}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {'wait_before': 1}) with db_api.transaction(): # Note: We need to reread execution to access related tasks. @@ -471,7 +471,7 @@ class PoliciesTest(base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -488,7 +488,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(WAIT_AFTER_WB) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) with db_api.transaction(): # Note: We need to reread execution to access related tasks. @@ -506,7 +506,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(WAIT_AFTER_FROM_VAR) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {'wait_after': 2}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {'wait_after': 2}) with db_api.transaction(): # Note: We need to reread execution to access related tasks. @@ -531,7 +531,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(RETRY_WB) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) with db_api.transaction(): # Note: We need to reread execution to access related tasks. @@ -561,7 +561,11 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(RETRY_WB_FROM_VAR) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {'count': 3, 'delay': 1}) + wf_ex = self.engine.start_workflow( + 'wb.wf1', + '', + {'count': 3, 'delay': 1} + ) with db_api.transaction(): # Note: We need to reread execution to access related tasks. @@ -606,7 +610,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(retry_wb) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) with db_api.transaction(): # Note: We need to reread execution to access related tasks. @@ -649,7 +653,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(retry_wb) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) with db_api.transaction(): # Note: We need to reread execution to access related tasks. @@ -692,7 +696,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(retry_wb) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) with db_api.transaction(): # Note: We need to reread execution to access related tasks. @@ -736,7 +740,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(retry_wb) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) with db_api.transaction(): # Note: We need to reread execution to access related tasks. @@ -777,7 +781,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(retry_wb) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) with db_api.transaction(): # Note: We need to reread execution to access related tasks. @@ -816,7 +820,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(retry_wb) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) with db_api.transaction(): # Note: We need to reread execution to access related tasks. @@ -862,7 +866,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(retry_wb) # Start workflow. - wf_ex = self.engine.start_workflow('wb.main', {}) + wf_ex = self.engine.start_workflow('wb.main', '', {}) with db_api.transaction(): # Note: We need to reread execution to access related tasks. @@ -908,7 +912,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(retry_wb) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) with db_api.transaction(): # Note: We need to reread execution to access related tasks. @@ -961,7 +965,7 @@ class PoliciesTest(base.EngineTestCase): """ wf_service.create_workflows(retry_wf) - wf_ex = self.engine.start_workflow('wf1', {}) + wf_ex = self.engine.start_workflow('wf1', '', {}) self.await_workflow_success(wf_ex.id) @@ -984,7 +988,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(TIMEOUT_WB) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) with db_api.transaction(): # Note: We need to reread execution to access related tasks. @@ -1009,7 +1013,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(TIMEOUT_WB2) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) with db_api.transaction(): # Note: We need to reread execution to access related tasks. @@ -1036,7 +1040,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(TIMEOUT_FROM_VAR) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {'timeout': 1}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {'timeout': 1}) with db_api.transaction(): # Note: We need to reread execution to access related tasks. @@ -1055,7 +1059,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(PAUSE_BEFORE_WB) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) with db_api.transaction(): wf_ex = db_api.get_workflow_execution(wf_ex.id) @@ -1096,7 +1100,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(PAUSE_BEFORE_DELAY_WB) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) with db_api.transaction(): wf_ex = db_api.get_workflow_execution(wf_ex.id) @@ -1148,7 +1152,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(CONCURRENCY_WB) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) self.await_workflow_success(wf_ex.id) @@ -1166,7 +1170,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(CONCURRENCY_WB_FROM_VAR) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {'concurrency': 4}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {'concurrency': 4}) with db_api.transaction(): wf_ex = db_api.get_workflow_execution(wf_ex.id) @@ -1194,7 +1198,7 @@ class PoliciesTest(base.EngineTestCase): wb_service.create_workbook_v2(wb) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {'wait_before': '1'}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {'wait_before': '1'}) self.assertIn( 'Invalid data type in WaitBeforePolicy', @@ -1219,7 +1223,7 @@ class PoliciesTest(base.EngineTestCase): wf_service.create_workflows(wf_delayed_state) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_profiler.py b/mistral/tests/unit/engine/test_profiler.py index 67ebb92bf..3c9a92fd4 100644 --- a/mistral/tests/unit/engine/test_profiler.py +++ b/mistral/tests/unit/engine/test_profiler.py @@ -64,7 +64,7 @@ class EngineProfilerTest(base.EngineTestCase): self.ctx_serializer.deserialize_context(ctx) - wf_ex = self.engine_client.start_workflow('wf', {}) + wf_ex = self.engine_client.start_workflow('wf', '', {}) self.assertIsNotNone(wf_ex) self.assertEqual(states.RUNNING, wf_ex['state']) @@ -87,7 +87,7 @@ class EngineProfilerTest(base.EngineTestCase): self.ctx_serializer.deserialize_context({}) - wf_ex = self.engine_client.start_workflow('wf', {}) + wf_ex = self.engine_client.start_workflow('wf', '', {}) self.assertIsNotNone(wf_ex) self.assertEqual(states.RUNNING, wf_ex['state']) diff --git a/mistral/tests/unit/engine/test_race_condition.py b/mistral/tests/unit/engine/test_race_condition.py index 70e7d0180..557780c43 100644 --- a/mistral/tests/unit/engine/test_race_condition.py +++ b/mistral/tests/unit/engine/test_race_condition.py @@ -141,7 +141,7 @@ class EngineActionRaceConditionTest(base.EngineTestCase): self.block_action() - wf_ex = self.engine.start_workflow('wf', None) + wf_ex = self.engine.start_workflow('wf', '', None) with db_api.transaction(): wf_ex = db_api.get_workflow_execution(wf_ex.id) @@ -183,7 +183,7 @@ class EngineActionRaceConditionTest(base.EngineTestCase): self.block_action() - wf_ex = self.engine.start_workflow('wf', None) + wf_ex = self.engine.start_workflow('wf', '', None) wf_ex = db_api.get_workflow_execution(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_reverse_workflow.py b/mistral/tests/unit/engine/test_reverse_workflow.py index 5d12ba806..ba5cf368d 100644 --- a/mistral/tests/unit/engine/test_reverse_workflow.py +++ b/mistral/tests/unit/engine/test_reverse_workflow.py @@ -72,6 +72,7 @@ class ReverseWorkflowEngineTest(base.EngineTestCase): wf_ex = self.engine.start_workflow( 'my_wb.wf1', + '', wf_input, task_name='task1' ) @@ -79,7 +80,10 @@ class ReverseWorkflowEngineTest(base.EngineTestCase): # Execution 1. self.assertIsNotNone(wf_ex) self.assertDictEqual(wf_input, wf_ex.input) - self.assertDictEqual({'task_name': 'task1'}, wf_ex.params) + self.assertDictEqual( + {'task_name': 'task1', 'namespace': ''}, + wf_ex.params + ) # Wait till workflow 'wf1' is completed. self.await_workflow_success(wf_ex.id) @@ -105,6 +109,7 @@ class ReverseWorkflowEngineTest(base.EngineTestCase): wf_ex = self.engine.start_workflow( 'my_wb.wf1', + '', wf_input, task_name='task2' ) @@ -112,7 +117,10 @@ class ReverseWorkflowEngineTest(base.EngineTestCase): # Execution 1. self.assertIsNotNone(wf_ex) self.assertDictEqual(wf_input, wf_ex.input) - self.assertDictEqual({'task_name': 'task2'}, wf_ex.params) + self.assertDictEqual( + {'task_name': 'task2', 'namespace': ''}, + wf_ex.params + ) # Wait till workflow 'wf1' is completed. self.await_workflow_success(wf_ex.id) @@ -146,6 +154,7 @@ class ReverseWorkflowEngineTest(base.EngineTestCase): wf_ex = self.engine.start_workflow( 'my_wb.wf1', + '', wf_input, task_name='task4' ) diff --git a/mistral/tests/unit/engine/test_reverse_workflow_rerun.py b/mistral/tests/unit/engine/test_reverse_workflow_rerun.py index f76ee439e..df22bf44c 100644 --- a/mistral/tests/unit/engine/test_reverse_workflow_rerun.py +++ b/mistral/tests/unit/engine/test_reverse_workflow_rerun.py @@ -88,7 +88,7 @@ class ReverseWorkflowRerunTest(base.EngineTestCase): wb_service.create_workbook_v2(SIMPLE_WORKBOOK) # Run workflow and fail task. - wf_ex = self.engine.start_workflow('wb1.wf1', {}, task_name='t3') + wf_ex = self.engine.start_workflow('wb1.wf1', '', {}, task_name='t3') self.await_workflow_error(wf_ex.id) @@ -200,6 +200,7 @@ class ReverseWorkflowRerunTest(base.EngineTestCase): # Run workflow and fail task. wf_ex = self.engine.start_workflow( 'wb1.wf1', + '', {}, task_name='t3', env=env @@ -340,7 +341,7 @@ class ReverseWorkflowRerunTest(base.EngineTestCase): wb_service.create_workbook_v2(SIMPLE_WORKBOOK) # Run workflow and fail task. - wf_ex = self.engine.start_workflow('wb1.wf1', {}, task_name='t3') + wf_ex = self.engine.start_workflow('wb1.wf1', '', {}, task_name='t3') self.await_workflow_error(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_reverse_workflow_rerun_cancelled.py b/mistral/tests/unit/engine/test_reverse_workflow_rerun_cancelled.py index 49002a303..34f127b35 100644 --- a/mistral/tests/unit/engine/test_reverse_workflow_rerun_cancelled.py +++ b/mistral/tests/unit/engine/test_reverse_workflow_rerun_cancelled.py @@ -63,7 +63,7 @@ class ReverseWorkflowRerunCancelledTest(base.EngineTestCase): wb_service.create_workbook_v2(wb_def) - wf1_ex = self.engine.start_workflow('wb1.wf1', {}, task_name='t3') + wf1_ex = self.engine.start_workflow('wb1.wf1', '', {}, task_name='t3') self.await_workflow_state(wf1_ex.id, states.RUNNING) diff --git a/mistral/tests/unit/engine/test_safe_rerun.py b/mistral/tests/unit/engine/test_safe_rerun.py index 5934d8a32..57baa5b67 100644 --- a/mistral/tests/unit/engine/test_safe_rerun.py +++ b/mistral/tests/unit/engine/test_safe_rerun.py @@ -72,7 +72,7 @@ class TestSafeRerun(base.EngineTestCase): # to true. wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -118,7 +118,7 @@ class TestSafeRerun(base.EngineTestCase): # to true. wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -153,7 +153,7 @@ class TestSafeRerun(base.EngineTestCase): """ wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_state_info.py b/mistral/tests/unit/engine/test_state_info.py index f92a62acb..08ca2aaab 100644 --- a/mistral/tests/unit/engine/test_state_info.py +++ b/mistral/tests/unit/engine/test_state_info.py @@ -46,7 +46,7 @@ class ExecutionStateInfoTest(base.EngineTestCase): wf_service.create_workflows(workflow) # Start workflow. - wf_ex = self.engine.start_workflow('test_wf', {}) + wf_ex = self.engine.start_workflow('test_wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -70,7 +70,7 @@ class ExecutionStateInfoTest(base.EngineTestCase): wf_service.create_workflows(workflow) # Start workflow. - wf_ex = self.engine.start_workflow('test_wf', {}) + wf_ex = self.engine.start_workflow('test_wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -96,7 +96,7 @@ class ExecutionStateInfoTest(base.EngineTestCase): wf_service.create_workflows(workflow) # Start workflow. - wf_ex = self.engine.start_workflow('test_wf', {}) + wf_ex = self.engine.start_workflow('test_wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -131,7 +131,7 @@ class ExecutionStateInfoTest(base.EngineTestCase): wf_service.create_workflows(workflow) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_subworkflows.py b/mistral/tests/unit/engine/test_subworkflows.py index 48fb9a916..99b31aca3 100644 --- a/mistral/tests/unit/engine/test_subworkflows.py +++ b/mistral/tests/unit/engine/test_subworkflows.py @@ -105,7 +105,7 @@ class SubworkflowsTest(base.EngineTestCase): wb_service.create_workbook_v2(WB2) def test_subworkflow_success(self): - wf2_ex = self.engine.start_workflow('wb1.wf2', None) + wf2_ex = self.engine.start_workflow('wb1.wf2', '', None) project_id = auth_context.ctx().project_id @@ -113,7 +113,7 @@ class SubworkflowsTest(base.EngineTestCase): self.assertEqual(project_id, wf2_ex.project_id) self.assertIsNotNone(wf2_ex) self.assertDictEqual({}, wf2_ex.input) - self.assertDictEqual({}, wf2_ex.params) + self.assertDictEqual({'namespace': ''}, wf2_ex.params) self._await(lambda: len(db_api.get_workflow_executions()) == 2, 0.5, 5) @@ -187,7 +187,7 @@ class SubworkflowsTest(base.EngineTestCase): @mock.patch.object(std_actions.EchoAction, 'run', mock.MagicMock(side_effect=exc.ActionException)) def test_subworkflow_error(self): - self.engine.start_workflow('wb1.wf2', None) + self.engine.start_workflow('wb1.wf2', '', None) self._await(lambda: len(db_api.get_workflow_executions()) == 2, 0.5, 5) @@ -205,7 +205,7 @@ class SubworkflowsTest(base.EngineTestCase): self.await_workflow_error(wf2_ex.id) def test_subworkflow_yaql_error(self): - wf_ex = self.engine.start_workflow('wb2.wf1', None) + wf_ex = self.engine.start_workflow('wb2.wf1', '', None) self.await_workflow_error(wf_ex.id) @@ -227,12 +227,15 @@ class SubworkflowsTest(base.EngineTestCase): def test_subworkflow_environment_inheritance(self): env = {'key1': 'abc'} - wf2_ex = self.engine.start_workflow('wb1.wf2', None, env=env) + wf2_ex = self.engine.start_workflow('wb1.wf2', '', None, env=env) # Execution of 'wf2'. self.assertIsNotNone(wf2_ex) self.assertDictEqual({}, wf2_ex.input) - self.assertDictEqual({'env': env}, wf2_ex.params) + self.assertDictEqual( + {'env': env, 'namespace': ''}, + wf2_ex.params + ) self._await(lambda: len(db_api.get_workflow_executions()) == 2, 0.5, 5) diff --git a/mistral/tests/unit/engine/test_task_cancel.py b/mistral/tests/unit/engine/test_task_cancel.py index edf9a9eef..66eb563a2 100644 --- a/mistral/tests/unit/engine/test_task_cancel.py +++ b/mistral/tests/unit/engine/test_task_cancel.py @@ -52,7 +52,7 @@ class TaskCancelTest(base.EngineTestCase): wf_service.create_workflows(workflow) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_state(wf_ex.id, states.RUNNING) @@ -143,7 +143,7 @@ class TaskCancelTest(base.EngineTestCase): wb_service.create_workbook_v2(workbook) - wf_ex = self.engine.start_workflow('wb.wf', {}) + wf_ex = self.engine.start_workflow('wb.wf', '', {}) self.await_workflow_state(wf_ex.id, states.RUNNING) @@ -219,7 +219,7 @@ class TaskCancelTest(base.EngineTestCase): wf_service.create_workflows(workflow) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_state(wf_ex.id, states.RUNNING) @@ -308,7 +308,7 @@ class TaskCancelTest(base.EngineTestCase): wb_service.create_workbook_v2(wb_def) - wf1_ex = self.engine.start_workflow('wb1.wf1', {}) + wf1_ex = self.engine.start_workflow('wb1.wf1', '', {}) self.await_workflow_state(wf1_ex.id, states.RUNNING) diff --git a/mistral/tests/unit/engine/test_task_defaults.py b/mistral/tests/unit/engine/test_task_defaults.py index 62e43597d..d2ec6840b 100644 --- a/mistral/tests/unit/engine/test_task_defaults.py +++ b/mistral/tests/unit/engine/test_task_defaults.py @@ -63,7 +63,7 @@ class TaskDefaultsDirectWorkflowEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -106,7 +106,7 @@ class TaskDefaultsReverseWorkflowEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}, task_name='task2') + wf_ex = self.engine.start_workflow('wf', '', {}, task_name='task2') self.await_workflow_error(wf_ex.id) @@ -150,7 +150,7 @@ class TaskDefaultsReverseWorkflowEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}, task_name='task2') + wf_ex = self.engine.start_workflow('wf', '', {}, task_name='task2') self.await_workflow_error(wf_ex.id) @@ -188,7 +188,7 @@ class TaskDefaultsReverseWorkflowEngineTest(base.EngineTestCase): time_before = dt.datetime.now() # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}, task_name='task1') + wf_ex = self.engine.start_workflow('wf', '', {}, task_name='task1') self.await_workflow_success(wf_ex.id) @@ -233,7 +233,7 @@ class TaskDefaultsReverseWorkflowEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}, task_name='task2') + wf_ex = self.engine.start_workflow('wf', '', {}, task_name='task2') self.await_workflow_success(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_task_publish.py b/mistral/tests/unit/engine/test_task_publish.py index 04700fc28..66828c649 100644 --- a/mistral/tests/unit/engine/test_task_publish.py +++ b/mistral/tests/unit/engine/test_task_publish.py @@ -67,7 +67,7 @@ class TaskPublishTest(base.EngineTestCase): wb_service.create_workbook_v2(SIMPLE_WORKBOOK) # Run workflow and fail task. - wf_ex = self.engine.start_workflow('wb1.wf1', {}) + wf_ex = self.engine.start_workflow('wb1.wf1', '', {}) self.await_workflow_error(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_tasks_function.py b/mistral/tests/unit/engine/test_tasks_function.py index 57ab7589f..fabe86718 100644 --- a/mistral/tests/unit/engine/test_tasks_function.py +++ b/mistral/tests/unit/engine/test_tasks_function.py @@ -217,11 +217,11 @@ class TasksFunctionTest(base.EngineTestCase): def test_tasks_function(self): wb_service.create_workbook_v2(WORKBOOK_WITH_EXPRESSIONS) # Start helping workflow executions. - wf1_ex = self.engine.start_workflow('wb.wf1_top_lvl', {}) - wf2_ex = self.engine.start_workflow('wb.wf2_top_lvl', {}) - wf3_ex = self.engine.start_workflow('wb.wf3_top_lvl', {}) - wf4_ex = self.engine.start_workflow('wb.wf4_top_lvl', {}) - wf5_ex = self.engine.start_workflow('wb.wf5_top_lvl', {}) + wf1_ex = self.engine.start_workflow('wb.wf1_top_lvl', '', {}) + wf2_ex = self.engine.start_workflow('wb.wf2_top_lvl', '', {}) + wf3_ex = self.engine.start_workflow('wb.wf3_top_lvl', '', {}) + wf4_ex = self.engine.start_workflow('wb.wf4_top_lvl', '', {}) + wf5_ex = self.engine.start_workflow('wb.wf5_top_lvl', '', {}) self.await_workflow_success(wf1_ex.id) self.await_workflow_success(wf2_ex.id) @@ -232,6 +232,7 @@ class TasksFunctionTest(base.EngineTestCase): # Start test workflow execution execution = self.engine.start_workflow( 'wb.test_tasks_function', + '', {"wf1_wx_id": wf1_ex.id, "wf2_wx_id": wf2_ex.id, "wf3_wx_id": wf3_ex.id, diff --git a/mistral/tests/unit/engine/test_with_items.py b/mistral/tests/unit/engine/test_with_items.py index 885778c5a..af1c1db1b 100644 --- a/mistral/tests/unit/engine/test_with_items.py +++ b/mistral/tests/unit/engine/test_with_items.py @@ -185,7 +185,7 @@ class WithItemsEngineTest(base.EngineTestCase): wb_service.create_workbook_v2(WB) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf', WF_INPUT) + wf_ex = self.engine.start_workflow('wb.wf', '', WF_INPUT) self.await_workflow_success(wf_ex.id) @@ -241,7 +241,7 @@ class WithItemsEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -267,7 +267,7 @@ class WithItemsEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -315,7 +315,7 @@ class WithItemsEngineTest(base.EngineTestCase): wb_service.create_workbook_v2(wb_text) # Start workflow. - wf_ex = self.engine.start_workflow('wb1.wf', {}) + wf_ex = self.engine.start_workflow('wb1.wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -332,7 +332,7 @@ class WithItemsEngineTest(base.EngineTestCase): wf_input.update({'greeting': 'Hello'}) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf', wf_input) + wf_ex = self.engine.start_workflow('wb.wf', '', wf_input) self.await_workflow_success(wf_ex.id) @@ -360,7 +360,7 @@ class WithItemsEngineTest(base.EngineTestCase): wf_input = {'arrayI': ['a', 'b', 'c'], 'arrayJ': [1, 2, 3]} # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf', wf_input) + wf_ex = self.engine.start_workflow('wb.wf', '', wf_input) self.await_workflow_success(wf_ex.id) @@ -389,7 +389,7 @@ class WithItemsEngineTest(base.EngineTestCase): wb_service.create_workbook_v2(WB_ACTION_CONTEXT) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf', WF_INPUT_URLS) + wf_ex = self.engine.start_workflow('wb.wf', '', WF_INPUT_URLS) with db_api.transaction(): wf_ex = db_api.get_workflow_execution(wf_ex.id) @@ -454,7 +454,7 @@ class WithItemsEngineTest(base.EngineTestCase): # Start workflow. wf_input = {'names_info': []} - wf_ex = self.engine.start_workflow('wb1.with_items', wf_input) + wf_ex = self.engine.start_workflow('wb1.with_items', '', wf_input) self.await_workflow_success(wf_ex.id) @@ -490,7 +490,7 @@ class WithItemsEngineTest(base.EngineTestCase): wb_service.create_workbook_v2(wb_text) # Start workflow. - wf_ex = self.engine.start_workflow('wb1.with_items', {}) + wf_ex = self.engine.start_workflow('wb1.with_items', '', {}) self.await_workflow_success(wf_ex.id) @@ -559,7 +559,7 @@ class WithItemsEngineTest(base.EngineTestCase): wb_service.create_workbook_v2(wb_text) # Start workflow. - wf_ex = self.engine.start_workflow('wb1.with_items', {}) + wf_ex = self.engine.start_workflow('wb1.with_items', '', {}) self.await_workflow_success(wf_ex.id) @@ -584,7 +584,7 @@ class WithItemsEngineTest(base.EngineTestCase): wb_service.create_workbook_v2(WB) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf', WF_INPUT_ONE_ITEM) + wf_ex = self.engine.start_workflow('wb.wf', '', WF_INPUT_ONE_ITEM) self.await_workflow_success(wf_ex.id) @@ -627,7 +627,7 @@ class WithItemsEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_with_concurrency_1) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) with db_api.transaction(): wf_ex = db_api.get_workflow_execution(wf_ex.id) @@ -720,7 +720,7 @@ class WithItemsEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {'concurrency': 2}) + wf_ex = self.engine.start_workflow('wf', '', {'concurrency': 2}) self.await_workflow_success(wf_ex.id) @@ -762,7 +762,7 @@ class WithItemsEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_with_concurrency_yaql) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {'concurrency': '2'}) + wf_ex = self.engine.start_workflow('wf', '', {'concurrency': '2'}) self.assertIn( 'Invalid data type in ConcurrencyPolicy', @@ -790,7 +790,7 @@ class WithItemsEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_with_concurrency_2) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) with db_api.transaction(): wf_ex = db_api.get_workflow_execution(wf_ex.id) @@ -902,7 +902,7 @@ class WithItemsEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_with_concurrency_2_fail) # Start workflow. - wf_ex = self.engine.start_workflow('concurrency_test_fail', {}) + wf_ex = self.engine.start_workflow('concurrency_test_fail', '', {}) self.await_workflow_success(wf_ex.id) @@ -943,7 +943,7 @@ class WithItemsEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_with_concurrency_3) # Start workflow. - wf_ex = self.engine.start_workflow('concurrency_test', {}) + wf_ex = self.engine.start_workflow('concurrency_test', '', {}) with db_api.transaction(): wf_ex = db_api.get_workflow_execution(wf_ex.id) @@ -1037,7 +1037,7 @@ class WithItemsEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_definition) # Start workflow. - wf_ex = self.engine.start_workflow('concurrency_test', {}) + wf_ex = self.engine.start_workflow('concurrency_test', '', {}) self.await_workflow_success(wf_ex.id) @@ -1079,7 +1079,7 @@ class WithItemsEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('with_items_retry', {}) + wf_ex = self.engine.start_workflow('with_items_retry', '', {}) self.await_workflow_success(wf_ex.id) @@ -1124,7 +1124,7 @@ class WithItemsEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -1159,7 +1159,12 @@ class WithItemsEngineTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {}, env={'name': 'Mistral'}) + wf_ex = self.engine.start_workflow( + 'wf', + '', + {}, + env={'name': 'Mistral'} + ) self.await_workflow_success(wf_ex.id) @@ -1209,7 +1214,7 @@ class WithItemsEngineTest(base.EngineTestCase): wb_service.create_workbook_v2(wb_text) # Start workflow. - wf_ex = self.engine.start_workflow('wb1.with_items', {}) + wf_ex = self.engine.start_workflow('wb1.with_items', '', {}) self.await_workflow_success(wf_ex.id) @@ -1279,7 +1284,7 @@ class WithItemsEngineTest(base.EngineTestCase): # Start workflow. names = ["Peter", "Susan", "Edmund", "Lucy", "Aslan", "Caspian"] - wf_ex = self.engine.start_workflow('wb1.main', {'names': names}) + wf_ex = self.engine.start_workflow('wb1.main', '', {'names': names}) self.await_workflow_success(wf_ex.id) @@ -1349,7 +1354,7 @@ class WithItemsEngineTest(base.EngineTestCase): wb_service.create_workbook_v2(wb_text) # Start workflow. - wf_ex = self.engine.start_workflow('test.with_items_default_bug', {}) + wf_ex = self.engine.start_workflow('test.with_items_default_bug') self.await_workflow_success(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_workflow_cancel.py b/mistral/tests/unit/engine/test_workflow_cancel.py index bc9ebdf26..ea9e9abb1 100644 --- a/mistral/tests/unit/engine/test_workflow_cancel.py +++ b/mistral/tests/unit/engine/test_workflow_cancel.py @@ -40,7 +40,7 @@ class WorkflowCancelTest(base.EngineTestCase): wf_service.create_workflows(workflow) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.engine.stop_workflow( wf_ex.id, @@ -85,7 +85,7 @@ class WorkflowCancelTest(base.EngineTestCase): wf = wf_service.create_workflows(workflow)[0] - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) with db_api.transaction(): db_api.delete_workflow_definition(wf.id) @@ -117,7 +117,7 @@ class WorkflowCancelTest(base.EngineTestCase): wf_service.create_workflows(workflow) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.engine.pause_workflow(wf_ex.id) @@ -168,7 +168,7 @@ class WorkflowCancelTest(base.EngineTestCase): wf_service.create_workflows(workflow) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -218,7 +218,7 @@ class WorkflowCancelTest(base.EngineTestCase): wb_service.create_workbook_v2(workbook) - wf_ex = self.engine.start_workflow('wb.wf', {}) + wf_ex = self.engine.start_workflow('wb.wf', '', {}) self.engine.stop_workflow( wf_ex.id, @@ -284,7 +284,7 @@ class WorkflowCancelTest(base.EngineTestCase): wb_service.create_workbook_v2(workbook) - self.engine.start_workflow('wb.wf', {}) + self.engine.start_workflow('wb.wf', '', {}) with db_api.transaction(): wf_execs = db_api.get_workflow_executions() @@ -351,7 +351,7 @@ class WorkflowCancelTest(base.EngineTestCase): """ wb_service.create_workbook_v2(workbook) - wf_ex = self.engine.start_workflow('wb.wf', {}) + wf_ex = self.engine.start_workflow('wb.wf', '', {}) self.engine.stop_workflow( wf_ex.id, @@ -421,7 +421,7 @@ class WorkflowCancelTest(base.EngineTestCase): wb_service.create_workbook_v2(workbook) - self.engine.start_workflow('wb.wf', {}) + self.engine.start_workflow('wb.wf', '', {}) with db_api.transaction(): wf_execs = db_api.get_workflow_executions() @@ -500,7 +500,7 @@ class WorkflowCancelTest(base.EngineTestCase): wb_service.create_workbook_v2(workbook) - self.engine.start_workflow('wb.wf', {}) + self.engine.start_workflow('wb.wf', '', {}) with db_api.transaction(): wf_execs = db_api.get_workflow_executions() @@ -585,7 +585,7 @@ class WorkflowCancelTest(base.EngineTestCase): wb_service.create_workbook_v2(workbook) - self.engine.start_workflow('wb.wf', {}) + self.engine.start_workflow('wb.wf', '', {}) with db_api.transaction(): wf_execs = db_api.get_workflow_executions() diff --git a/mistral/tests/unit/engine/test_workflow_resume.py b/mistral/tests/unit/engine/test_workflow_resume.py index 4c8a860b5..59efa0701 100644 --- a/mistral/tests/unit/engine/test_workflow_resume.py +++ b/mistral/tests/unit/engine/test_workflow_resume.py @@ -195,7 +195,7 @@ class WorkflowResumeTest(base.EngineTestCase): wb_service.create_workbook_v2(RESUME_WORKBOOK) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) self.await_workflow_paused(wf_ex.id) @@ -230,6 +230,7 @@ class WorkflowResumeTest(base.EngineTestCase): # Start workflow. wf_ex = self.engine.start_workflow( 'resume_reverse.wf', + '', {}, task_name='task2' ) @@ -265,7 +266,7 @@ class WorkflowResumeTest(base.EngineTestCase): wb_service.create_workbook_v2(WORKBOOK_TWO_BRANCHES) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) self.await_workflow_paused(wf_ex.id) @@ -295,7 +296,7 @@ class WorkflowResumeTest(base.EngineTestCase): wb_service.create_workbook_v2(WORKBOOK_TWO_START_TASKS) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) self.await_workflow_paused(wf_ex.id) @@ -332,7 +333,7 @@ class WorkflowResumeTest(base.EngineTestCase): wb_service.create_workbook_v2(WORKBOOK_DIFFERENT_TASK_STATES) # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) self.await_workflow_paused(wf_ex.id) @@ -381,7 +382,7 @@ class WorkflowResumeTest(base.EngineTestCase): # Start and pause workflow. wb_service.create_workbook_v2(WORKBOOK_DIFFERENT_TASK_STATES) - wf_ex = self.engine.start_workflow('wb.wf1', {}) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}) self.await_workflow_paused(wf_ex.id) @@ -413,7 +414,7 @@ class WorkflowResumeTest(base.EngineTestCase): } # Start workflow. - wf_ex = self.engine.start_workflow('wb.wf1', {}, env=env) + wf_ex = self.engine.start_workflow('wb.wf1', '', {}, env=env) self.await_workflow_paused(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_workflow_stop.py b/mistral/tests/unit/engine/test_workflow_stop.py index 118dee6e7..cd9b4ec8a 100644 --- a/mistral/tests/unit/engine/test_workflow_stop.py +++ b/mistral/tests/unit/engine/test_workflow_stop.py @@ -39,7 +39,7 @@ class WorkflowStopTest(base.EngineTestCase): """ wf_service.create_workflows(WORKFLOW) - self.exec_id = self.engine.start_workflow('wf', {}).id + self.exec_id = self.engine.start_workflow('wf', '', {}).id def test_stop_failed(self): self.engine.stop_workflow(self.exec_id, states.SUCCESS, "Force stop") diff --git a/mistral/tests/unit/engine/test_workflow_variables.py b/mistral/tests/unit/engine/test_workflow_variables.py index 9cb54e51e..365423df5 100644 --- a/mistral/tests/unit/engine/test_workflow_variables.py +++ b/mistral/tests/unit/engine/test_workflow_variables.py @@ -51,7 +51,7 @@ class WorkflowVariablesTest(base.EngineTestCase): wf_service.create_workflows(wf_text) # Start workflow. - wf_ex = self.engine.start_workflow('wf', {'param2': 'Renat'}) + wf_ex = self.engine.start_workflow('wf', '', {'param2': 'Renat'}) self.await_workflow_success(wf_ex.id) diff --git a/mistral/tests/unit/engine/test_yaql_functions.py b/mistral/tests/unit/engine/test_yaql_functions.py index 5434018b4..c1157e172 100644 --- a/mistral/tests/unit/engine/test_yaql_functions.py +++ b/mistral/tests/unit/engine/test_yaql_functions.py @@ -62,7 +62,7 @@ class YAQLFunctionsEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -130,7 +130,7 @@ class YAQLFunctionsEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -165,7 +165,7 @@ class YAQLFunctionsEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -198,7 +198,7 @@ class YAQLFunctionsEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -243,7 +243,7 @@ class YAQLFunctionsEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_error(wf_ex.id) @@ -275,7 +275,7 @@ class YAQLFunctionsEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -300,7 +300,7 @@ class YAQLFunctionsEngineTest(engine_test_base.EngineTestCase): wf_service.create_workflows(wf_text) - wf_ex = self.engine.start_workflow('wf', {}) + wf_ex = self.engine.start_workflow('wf', '', {}) self.await_workflow_success(wf_ex.id) @@ -337,6 +337,7 @@ class YAQLFunctionsEngineTest(engine_test_base.EngineTestCase): wf_ex = self.engine.start_workflow( 'wf', + '', {'k1': 'v1'}, param1='blablabla' ) @@ -369,7 +370,10 @@ class YAQLFunctionsEngineTest(engine_test_base.EngineTestCase): execution['input'] ) - self.assertDictEqual({'param1': 'blablabla'}, execution['params']) + self.assertDictEqual( + {'param1': 'blablabla', 'namespace': ''}, + execution['params'] + ) self.assertEqual( wf_ex.created_at.isoformat(' '), diff --git a/mistral/tests/unit/executors/test_local_executor.py b/mistral/tests/unit/executors/test_local_executor.py index 130bb0c99..c10d0ff6f 100644 --- a/mistral/tests/unit/executors/test_local_executor.py +++ b/mistral/tests/unit/executors/test_local_executor.py @@ -87,7 +87,7 @@ class LocalExecutorTestCase(base.ExecutorTestCase): """ wb_svc.create_workbook_v2(wb_def) - wf_ex = self.engine.start_workflow('wb1.wf1', {}) + wf_ex = self.engine.start_workflow('wb1.wf1', '', {}) self.await_workflow_success(wf_ex.id) with db_api.transaction(): @@ -144,7 +144,7 @@ class LocalExecutorTestCase(base.ExecutorTestCase): """ wb_svc.create_workbook_v2(wb_def) - wf_ex = self.engine.start_workflow('wb1.wf1', {}) + wf_ex = self.engine.start_workflow('wb1.wf1', '', {}) self.await_workflow_success(wf_ex.id) with db_api.transaction(): diff --git a/mistral_tempest_tests/services/base.py b/mistral_tempest_tests/services/base.py index a69817e5a..8f42b6589 100644 --- a/mistral_tempest_tests/services/base.py +++ b/mistral_tempest_tests/services/base.py @@ -72,8 +72,8 @@ class MistralClientBase(rest_client.RestClient): self.action_executions = [] self.event_triggers = [] - def get_list_obj(self, name): - resp, body = self.get(name) + def get_list_obj(self, url_path): + resp, body = self.get(url_path) return resp, json.loads(body) diff --git a/mistral_tempest_tests/services/v2/mistral_client.py b/mistral_tempest_tests/services/v2/mistral_client.py index f9022caa0..096161690 100644 --- a/mistral_tempest_tests/services/v2/mistral_client.py +++ b/mistral_tempest_tests/services/v2/mistral_client.py @@ -24,21 +24,30 @@ CONF = config.CONF class MistralClientV2(base.MistralClientBase): - def post_request(self, url, file_name): + def post_request(self, url_path, file_name): headers = {"headers": "Content-Type:text/plain"} - return self.post(url, base.get_resource(file_name), headers=headers) + return self.post( + url_path, + base.get_resource(file_name), + headers=headers + ) - def post_json(self, url, obj, extra_headers={}): + def get_request(self, url_path): + headers = {"headers": "Content-Type:application/json"} + + return self.get(url_path, headers=headers) + + def post_json(self, url_path, obj, extra_headers={}): headers = {"Content-Type": "application/json"} headers = dict(headers, **extra_headers) - return self.post(url, json.dumps(obj), headers=headers) + return self.post(url_path, json.dumps(obj), headers=headers) - def update_request(self, url, file_name): + def update_request(self, url_path, file_name): headers = {"headers": "Content-Type:text/plain"} resp, body = self.put( - url, + url_path, base.get_resource(file_name), headers=headers ) @@ -64,26 +73,61 @@ class MistralClientV2(base.MistralClientBase): return resp, json.loads(body) - def create_workflow(self, yaml_file, scope=None): + def create_workflow(self, yaml_file, scope=None, namespace=None): + url_path = 'workflows?' + if scope: - resp, body = self.post_request('workflows?scope=public', yaml_file) - else: - resp, body = self.post_request('workflows', yaml_file) + url_path += 'scope=public&' + + if namespace: + url_path += 'namespace=' + namespace + + resp, body = self.post_request(url_path, yaml_file) for wf in json.loads(body)['workflows']: - self.workflows.append(wf['name']) + identifier = wf['id'] if namespace else wf['name'] + self.workflows.append(identifier) return resp, json.loads(body) + def get_workflow(self, wf_identifier, namespace=None): + + url_path = 'workflows/' + wf_identifier + if namespace: + url_path += 'namespace=' + namespace + + resp, body = self.get_request(url_path) + + return resp, json.loads(body) + + def update_workflow(self, file_name, namespace=None): + url_path = "workflows?" + + if namespace: + url_path += 'namespace=' + namespace + + return self.update_request(url_path, file_name=file_name) + def get_action_execution(self, action_execution_id): return self.get('action_executions/%s' % action_execution_id) - def create_execution(self, identifier, wf_input=None, params=None): + def get_action_executions(self, task_id=None): + url_path = 'action_executions' + if task_id: + url_path += '?task_execution_id=%s' % task_id + + return self.get_list_obj(url_path) + + def create_execution(self, identifier, wf_namespace=None, wf_input=None, + params=None): if uuidutils.is_uuid_like(identifier): body = {"workflow_id": "%s" % identifier} else: body = {"workflow_name": "%s" % identifier} + if wf_namespace: + body.update({'workflow_namespace': wf_namespace}) + if wf_input: body.update({'input': json.dumps(wf_input)}) if params: @@ -100,6 +144,23 @@ class MistralClientV2(base.MistralClientBase): return resp, json.loads(body) + def get_execution(self, execution_id): + return self.get('executions/%s' % execution_id) + + def get_executions(self, task_id): + url_path = 'executions' + if task_id: + url_path += '?task_execution_id=%s' % task_id + + return self.get_list_obj(url_path) + + def get_tasks(self, execution_id=None): + url_path = 'tasks' + if execution_id: + url_path += '?workflow_execution_id=%s' % execution_id + + return self.get_list_obj(url_path) + def create_cron_trigger(self, name, wf_name, wf_input=None, pattern=None, first_time=None, count=None): post_body = { @@ -133,11 +194,8 @@ class MistralClientV2(base.MistralClientBase): return [t for t in all_tasks if t['workflow_name'] == wf_name] def create_action_execution(self, request_body, extra_headers={}): - resp, body = self.post_json( - 'action_executions', - request_body, - extra_headers - ) + resp, body = self.post_json('action_executions', request_body, + extra_headers) params = json.loads(request_body.get('params', '{}')) if params.get('save_result', False): diff --git a/mistral_tempest_tests/tests/api/v2/test_action_executions.py b/mistral_tempest_tests/tests/api/v2/test_action_executions.py index 779bab18d..d70f2cb1f 100644 --- a/mistral_tempest_tests/tests/api/v2/test_action_executions.py +++ b/mistral_tempest_tests/tests/api/v2/test_action_executions.py @@ -226,3 +226,31 @@ class ActionExecutionTestsV2(base.TestCase): self.assertEqual(201, resp.status) output = json.loads(body['output']) self.assertEqual(200, output['result']['status']) + + @decorators.idempotent_id('9438e195-031c-4502-b216-6d72941ec281') + @decorators.attr(type='sanity') + def test_action_execution_of_workflow_within_namespace(self): + + resp, body = self.client.create_workflow('wf_v2.yaml', namespace='abc') + wf_name = body['workflows'][0]['name'] + wf_namespace = body['workflows'][0]['namespace'] + self.assertEqual(201, resp.status) + resp, body = self.client.create_execution( + wf_name, + wf_namespace=wf_namespace + ) + self.assertEqual(201, resp.status) + resp, body = self.client.get_list_obj('tasks') + self.assertEqual(200, resp.status) + task_id = body['tasks'][0]['id'] + + resp, body = self.client.get_list_obj( + 'action_executions?include_output=true&task_execution_id=%s' % + task_id) + + self.assertEqual(200, resp.status) + action_execution = body['action_executions'][0] + + self.assertEqual(200, resp.status) + action_execution = body['action_executions'][0] + self.assertEqual(wf_namespace, action_execution['workflow_namespace']) diff --git a/mistral_tempest_tests/tests/api/v2/test_actions.py b/mistral_tempest_tests/tests/api/v2/test_actions.py index 9406a8d1b..8e0e2a060 100644 --- a/mistral_tempest_tests/tests/api/v2/test_actions.py +++ b/mistral_tempest_tests/tests/api/v2/test_actions.py @@ -133,9 +133,7 @@ class ActionTestsV2(base.TestCase): resp, body = self.client.create_action('action_v2.yaml') self.assertEqual(201, resp.status) - resp, body = self.client.get_list_obj( - 'actions?is_system=False' - ) + resp, body = self.client.get_list_obj('actions?is_system=False') self.assertEqual(200, resp.status) self.assertNotEmpty(body['actions']) @@ -149,9 +147,7 @@ class ActionTestsV2(base.TestCase): resp, body = self.client.create_action('action_v2.yaml') self.assertEqual(201, resp.status) - resp, body = self.client.get_list_obj( - 'actions?is_system=neq:False' - ) + resp, body = self.client.get_list_obj('actions?is_system=neq:False') self.assertEqual(200, resp.status) self.assertNotEmpty(body['actions']) @@ -169,8 +165,7 @@ class ActionTestsV2(base.TestCase): _, body = self.client.get_object('actions', created_acts[0]) time = body['created_at'] resp, body = self.client.get_list_obj( - 'actions?created_at=in:' + time.replace(' ', '%20') - ) + 'actions?created_at=in:' + time.replace(' ', '%20')) self.assertEqual(200, resp.status) action_names = [action['name'] for action in body['actions']] diff --git a/mistral_tempest_tests/tests/api/v2/test_event_triggers.py b/mistral_tempest_tests/tests/api/v2/test_event_triggers.py index b0f1fd2ab..2adfbdbae 100644 --- a/mistral_tempest_tests/tests/api/v2/test_event_triggers.py +++ b/mistral_tempest_tests/tests/api/v2/test_event_triggers.py @@ -107,7 +107,7 @@ class EventTriggerTestsV2(base.TestCase): @decorators.attr(type='negative') @decorators.idempotent_id('56b90a90-9ff3-42f8-a9eb-04a77198710e') def test_get_nonexistent_event_trigger(self): - fake_id = '123e4567-e89b-12d3-a456-426655440000' + fake_id = '3771c152-d1a7-4a82-8a50-c79d122012dc' self.assertRaises(exceptions.NotFound, self.client.get_object, diff --git a/mistral_tempest_tests/tests/api/v2/test_executions.py b/mistral_tempest_tests/tests/api/v2/test_executions.py index 5be2792f0..e79753135 100644 --- a/mistral_tempest_tests/tests/api/v2/test_executions.py +++ b/mistral_tempest_tests/tests/api/v2/test_executions.py @@ -19,6 +19,8 @@ from tempest.lib import exceptions from mistral import utils from mistral_tempest_tests.tests import base +import json + class ExecutionTestsV2(base.TestCase): @@ -72,8 +74,7 @@ class ExecutionTestsV2(base.TestCase): self.assertIn(exec_id_2, [ex['id'] for ex in body['executions']]) resp, body = self.client.get_list_obj( - 'executions?limit=1&sort_keys=workflow_name&sort_dirs=asc' - ) + 'executions?limit=1&sort_keys=workflow_name&sort_dirs=asc') self.assertEqual(200, resp.status) self.assertEqual(1, len(body['executions'])) @@ -127,8 +128,8 @@ class ExecutionTestsV2(base.TestCase): def test_create_execution_for_reverse_wf(self): resp, body = self.client.create_execution( self.reverse_wf['name'], - {self.reverse_wf['input']: "Bye"}, - {"task_name": "goodbye"}) + wf_input={self.reverse_wf['input']: "Bye"}, + params={"task_name": "goodbye"}) exec_id = body['id'] self.assertEqual(201, resp.status) @@ -327,3 +328,91 @@ class ExecutionTestsV2(base.TestCase): 'executions', exec_id ) + + @decorators.idempotent_id('a882876b-7565-4f7f-9714-d99032ffaabb') + @decorators.attr(type='sanity') + def test_workflow_execution_of_nested_workflows_within_namespace(self): + low_wf = 'for_wf_namespace/lowest_level_wf.yaml' + middle_wf = 'for_wf_namespace/middle_wf.yaml' + top_wf = 'for_wf_namespace/top_level_wf.yaml' + + resp, wf = self.client.create_workflow(low_wf) + self.assertEqual(201, resp.status) + + namespace = 'abc' + resp, wf = self.client.create_workflow(low_wf, namespace=namespace) + self.assertEqual(201, resp.status) + + resp, wf = self.client.create_workflow(middle_wf) + self.assertEqual(201, resp.status) + + resp, wf = self.client.create_workflow(top_wf) + self.assertEqual(201, resp.status) + + resp, wf = self.client.create_workflow(top_wf, namespace=namespace) + self.assertEqual(201, resp.status) + + wf_name = wf['workflows'][0]['name'] + resp, top_execution = self.client.create_execution(wf_name, namespace) + + self.assertEqual(201, resp.status) + self.assertEqual('RUNNING', top_execution['state']) + self.assertEqual(wf_name, top_execution['workflow_name']) + self.assertEqual(wf_name, top_execution['workflow_name']) + self.assertEqual(namespace, top_execution['workflow_namespace']) + + self.client.wait_execution(top_execution, target_state='SUCCESS') + + self.assertEqual( + namespace, + json.loads(top_execution['params'])['namespace'] + ) + + resp, tasks = self.client.get_tasks(top_execution['id']) + top_task = tasks['tasks'][0] + + self.assertEqual(wf_name, top_task['workflow_name']) + self.assertEqual(namespace, top_task['workflow_namespace']) + + resp, executions = self.client.get_executions(top_task['id']) + middle_execution = executions['executions'][0] + + self.assertEqual('middle_wf', middle_execution['workflow_name']) + self.assertEqual('', middle_execution['workflow_namespace']) + + self.assertEqual( + namespace, + json.loads(middle_execution['params'])['namespace'] + ) + + resp, tasks = self.client.get_tasks(middle_execution['id']) + middle_task = tasks['tasks'][0] + + self.assertEqual('middle_wf', middle_task['workflow_name']) + self.assertEqual('', middle_task['workflow_namespace']) + + resp, executions = self.client.get_executions(middle_task['id']) + lowest_execution = executions['executions'][0] + + self.assertEqual('lowest_level_wf', lowest_execution['workflow_name']) + self.assertEqual(namespace, lowest_execution['workflow_namespace']) + + self.assertEqual( + namespace, + json.loads(lowest_execution['params'])['namespace'] + ) + + resp, tasks = self.client.get_tasks(lowest_execution['id']) + lowest_task = tasks['tasks'][0] + + self.assertEqual('lowest_level_wf', lowest_task['workflow_name']) + self.assertEqual(namespace, lowest_task['workflow_namespace']) + + resp, action_executions = self.client.get_action_executions( + lowest_task['id'] + ) + + action_execution = action_executions['action_executions'][0] + + self.assertEqual('lowest_level_wf', action_execution['workflow_name']) + self.assertEqual(namespace, action_execution['workflow_namespace']) diff --git a/mistral_tempest_tests/tests/api/v2/test_tasks.py b/mistral_tempest_tests/tests/api/v2/test_tasks.py index 2931b97d7..7527824b9 100644 --- a/mistral_tempest_tests/tests/api/v2/test_tasks.py +++ b/mistral_tempest_tests/tests/api/v2/test_tasks.py @@ -63,8 +63,7 @@ class TasksTestsV2(base.TestCase): @decorators.idempotent_id('3230d694-40fd-4094-ad12-024f40a21b94') def test_get_tasks_of_execution(self): resp, body = self.client.get_list_obj( - 'tasks?workflow_execution_id=%s' % self.execution_id - ) + 'tasks?workflow_execution_id=%s' % self.execution_id) self.assertEqual(200, resp.status) self.assertEqual( diff --git a/mistral_tempest_tests/tests/api/v2/test_workflows.py b/mistral_tempest_tests/tests/api/v2/test_workflows.py index 3307f8adf..f9bc6cd6c 100644 --- a/mistral_tempest_tests/tests/api/v2/test_workflows.py +++ b/mistral_tempest_tests/tests/api/v2/test_workflows.py @@ -242,6 +242,58 @@ class WorkflowTestsV2(base.TestCase): self.assertEqual(200, resp.status) self.assertEqual(name, body['workflows'][0]['name']) + @decorators.attr(type='sanity') + @decorators.idempotent_id('42f5d135-a2b8-4a31-8135-c5ce8c5f1ed5') + def test_workflow_within_namespace(self): + self.useFixture(lockutils.LockFixture('mistral-workflow')) + + namespace = 'abc' + resp, body = self.client.create_workflow( + 'single_wf.yaml', + namespace=namespace + ) + name = body['workflows'][0]['name'] + id = body['workflows'][0]['id'] + + self.assertEqual(201, resp.status) + self.assertEqual(name, body['workflows'][0]['name']) + + resp, body = self.client.get_workflow( + id + ) + + self.assertEqual(namespace, body['namespace']) + + resp, body = self.client.update_workflow('single_wf.yaml', namespace) + + self.assertEqual(200, resp.status) + self.assertEqual(name, body['workflows'][0]['name']) + self.assertEqual(namespace, body['workflows'][0]['namespace']) + + namespace = 'abc2' + resp, body = self.client.create_workflow( + 'single_wf.yaml', + namespace=namespace + ) + name = body['workflows'][0]['name'] + id = body['workflows'][0]['id'] + + self.assertEqual(201, resp.status) + self.assertEqual(name, body['workflows'][0]['name']) + + resp, body = self.client.get_workflow(id) + + self.assertEqual(namespace, body['namespace']) + + self.assertRaises(exceptions.NotFound, self.client.get_workflow, name) + + self.client.create_workflow( + 'single_wf.yaml' + ) + + resp, body = self.client.get_workflow(id) + self.assertEqual(200, resp.status) + @decorators.attr(type='sanity') @decorators.idempotent_id('02bc1fc3-c31a-4e37-bb3d-eda46818505c') def test_get_workflow_definition(self): @@ -280,6 +332,15 @@ class WorkflowTestsV2(base.TestCase): self.assertRaises(exceptions.NotFound, self.client.get_object, 'workflows', 'nonexist') + exception = self.assertRaises( + exceptions.NotFound, + self.client.get_workflow, + 'nonexist_wf', + 'nonexist_namespace' + ) + self.assertIn('nonexist_wf', str(exception)) + self.assertIn('nonexist_namespace', str(exception)) + @decorators.attr(type='negative') @decorators.idempotent_id('6b917213-7f11-423a-8fe0-55795dcf0fb2') def test_double_create_workflows(self):