Create and run a workflow within a namespace
Add --namespace flag to workflow and execution operations. Also Add Namespace and Workflow namespace to the tables the users gets after some cli calls. Partially-Implements: blueprint create-and-run-workflows-within-a-namespace Change-Id: Ieb7302870520f5491e94a9bf6759082e2aa4a450
This commit is contained in:
parent
6d638a31dd
commit
db428c0858
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
version: '2.0'
|
||||
|
||||
async_wf:
|
||||
type: direct
|
||||
tasks:
|
||||
async_task:
|
||||
action: std.async_noop
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
version: '2.0'
|
||||
|
||||
lowest_level_wf:
|
||||
type: direct
|
||||
tasks:
|
||||
hello:
|
||||
action: std.noop
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
version: '2.0'
|
||||
|
||||
middle_wf:
|
||||
type: direct
|
||||
tasks:
|
||||
hello:
|
||||
workflow: lowest_level_wf
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
version: '2.0'
|
||||
|
||||
top_level_wf:
|
||||
type: direct
|
||||
tasks:
|
||||
hello:
|
||||
workflow: middle_wf
|
|
@ -31,8 +31,8 @@ class Execution(base.Resource):
|
|||
class ExecutionManager(base.ResourceManager):
|
||||
resource_class = Execution
|
||||
|
||||
def create(self, workflow_identifier, workflow_input=None, description='',
|
||||
**params):
|
||||
def create(self, workflow_identifier, namespace='', workflow_input=None,
|
||||
description='', **params):
|
||||
self._ensure_not_empty(workflow_identifier=workflow_identifier)
|
||||
|
||||
data = {
|
||||
|
@ -44,6 +44,9 @@ class ExecutionManager(base.ResourceManager):
|
|||
else:
|
||||
data.update({'workflow_name': workflow_identifier})
|
||||
|
||||
if namespace:
|
||||
data.update({'workflow_namespace': namespace})
|
||||
|
||||
if workflow_input:
|
||||
if isinstance(workflow_input, six.string_types):
|
||||
data.update({'input': workflow_input})
|
||||
|
|
|
@ -29,7 +29,7 @@ class Workflow(base.Resource):
|
|||
class WorkflowManager(base.ResourceManager):
|
||||
resource_class = Workflow
|
||||
|
||||
def create(self, definition, scope='private'):
|
||||
def create(self, definition, namespace='', scope='private'):
|
||||
self._ensure_not_empty(definition=definition)
|
||||
|
||||
# If the specified definition is actually a file, read in the
|
||||
|
@ -37,7 +37,7 @@ class WorkflowManager(base.ResourceManager):
|
|||
definition = utils.get_contents_if_file(definition)
|
||||
|
||||
resp = self.http_client.post(
|
||||
'/workflows?scope=%s' % scope,
|
||||
'/workflows?scope=%s&namespace=%s' % (scope, namespace),
|
||||
definition,
|
||||
headers={'content-type': 'text/plain'}
|
||||
)
|
||||
|
@ -48,7 +48,7 @@ class WorkflowManager(base.ResourceManager):
|
|||
return [self.resource_class(self, resource_data)
|
||||
for resource_data in base.extract_json(resp, 'workflows')]
|
||||
|
||||
def update(self, definition, scope='private', id=None):
|
||||
def update(self, definition, namespace='', scope='private', id=None):
|
||||
self._ensure_not_empty(definition=definition)
|
||||
|
||||
url_pre = ('/workflows/%s' % id) if id else '/workflows'
|
||||
|
@ -58,7 +58,7 @@ class WorkflowManager(base.ResourceManager):
|
|||
definition = utils.get_contents_if_file(definition)
|
||||
|
||||
resp = self.http_client.put(
|
||||
'%s?scope=%s' % (url_pre, scope),
|
||||
'%s?namespace=%s&scope=%s' % (url_pre, namespace, scope),
|
||||
definition,
|
||||
headers={'content-type': 'text/plain'}
|
||||
)
|
||||
|
@ -72,10 +72,13 @@ class WorkflowManager(base.ResourceManager):
|
|||
return [self.resource_class(self, resource_data)
|
||||
for resource_data in base.extract_json(resp, 'workflows')]
|
||||
|
||||
def list(self, marker='', limit=None, sort_keys='', sort_dirs='',
|
||||
**filters):
|
||||
def list(self, namespace='', marker='', limit=None, sort_keys='',
|
||||
sort_dirs='', **filters):
|
||||
qparams = {}
|
||||
|
||||
if namespace:
|
||||
qparams['namespace'] = namespace
|
||||
|
||||
if marker:
|
||||
qparams['marker'] = marker
|
||||
|
||||
|
@ -99,15 +102,22 @@ class WorkflowManager(base.ResourceManager):
|
|||
response_key='workflows',
|
||||
)
|
||||
|
||||
def get(self, identifier):
|
||||
def get(self, identifier, namespace=''):
|
||||
self._ensure_not_empty(identifier=identifier)
|
||||
|
||||
return self._get('/workflows/%s' % identifier)
|
||||
return self._get(
|
||||
'/workflows/%s?namespace=%s' % (identifier, namespace)
|
||||
)
|
||||
|
||||
def delete(self, identifier):
|
||||
def delete(self, identifier, namespace=None):
|
||||
self._ensure_not_empty(identifier=identifier)
|
||||
|
||||
self._delete('/workflows/%s' % identifier)
|
||||
path = '/workflows/%s' % identifier
|
||||
|
||||
if namespace:
|
||||
path = path + '?namespace=%s' % namespace
|
||||
|
||||
self._delete(path)
|
||||
|
||||
def validate(self, definition):
|
||||
self._ensure_not_empty(definition=definition)
|
||||
|
|
|
@ -30,6 +30,7 @@ def format_list(action_ex=None):
|
|||
'ID',
|
||||
'Name',
|
||||
'Workflow name',
|
||||
'Workflow namespace',
|
||||
'Task name',
|
||||
'Task ID',
|
||||
'State',
|
||||
|
@ -43,6 +44,7 @@ def format_list(action_ex=None):
|
|||
action_ex.id,
|
||||
action_ex.name,
|
||||
action_ex.workflow_name,
|
||||
action_ex.workflow_namespace,
|
||||
action_ex.task_name if hasattr(action_ex, 'task_name') else None,
|
||||
action_ex.task_execution_id,
|
||||
action_ex.state,
|
||||
|
@ -61,6 +63,7 @@ def format(action_ex=None):
|
|||
'ID',
|
||||
'Name',
|
||||
'Workflow name',
|
||||
'Workflow namespace',
|
||||
'Task name',
|
||||
'Task ID',
|
||||
'State',
|
||||
|
@ -75,6 +78,7 @@ def format(action_ex=None):
|
|||
action_ex.id,
|
||||
action_ex.name,
|
||||
action_ex.workflow_name,
|
||||
action_ex.workflow_namespace,
|
||||
action_ex.task_name if hasattr(action_ex, 'task_name') else None,
|
||||
action_ex.task_execution_id,
|
||||
action_ex.state,
|
||||
|
|
|
@ -38,6 +38,7 @@ def format(execution=None, lister=False):
|
|||
'ID',
|
||||
'Workflow ID',
|
||||
'Workflow name',
|
||||
'Workflow namespace',
|
||||
'Description',
|
||||
'Task Execution ID',
|
||||
'State',
|
||||
|
@ -55,6 +56,7 @@ def format(execution=None, lister=False):
|
|||
execution.id,
|
||||
execution.workflow_id,
|
||||
execution.workflow_name,
|
||||
execution.workflow_namespace,
|
||||
execution.description,
|
||||
execution.task_execution_id or '<none>',
|
||||
execution.state,
|
||||
|
@ -174,6 +176,12 @@ class Create(command.ShowOne):
|
|||
help='Workflow ID or name. Workflow name will be deprecated since '
|
||||
'Mitaka.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--namespace',
|
||||
nargs='?',
|
||||
default='',
|
||||
help="Workflow namespace."
|
||||
)
|
||||
parser.add_argument(
|
||||
'workflow_input',
|
||||
nargs='?',
|
||||
|
@ -209,6 +217,7 @@ class Create(command.ShowOne):
|
|||
|
||||
execution = mistral_client.executions.create(
|
||||
parsed_args.workflow_identifier,
|
||||
parsed_args.namespace,
|
||||
wf_input,
|
||||
parsed_args.description,
|
||||
**params
|
||||
|
|
|
@ -32,6 +32,7 @@ class TaskFormatter(object):
|
|||
('id', 'ID'),
|
||||
('name', 'Name'),
|
||||
('workflow_name', 'Workflow name'),
|
||||
('workflow_namespace', 'Workflow namespace'),
|
||||
('workflow_execution_id', 'Execution ID'),
|
||||
('state', 'State'),
|
||||
('state_info', 'State info'),
|
||||
|
@ -56,6 +57,7 @@ class TaskFormatter(object):
|
|||
task.id,
|
||||
task.name,
|
||||
task.workflow_name,
|
||||
task.workflow_namespace,
|
||||
task.workflow_execution_id,
|
||||
task.state,
|
||||
state_info,
|
||||
|
|
|
@ -30,6 +30,7 @@ def format(workflow=None, lister=False):
|
|||
columns = (
|
||||
'ID',
|
||||
'Name',
|
||||
'Namespace',
|
||||
'Project ID',
|
||||
'Tags',
|
||||
'Input',
|
||||
|
@ -43,6 +44,7 @@ def format(workflow=None, lister=False):
|
|||
data = (
|
||||
workflow.id,
|
||||
workflow.name,
|
||||
workflow.namespace,
|
||||
workflow.project_id,
|
||||
base.wrap(', '.join(tags)) or '<none>',
|
||||
workflow.input if not lister else base.cut(workflow.input),
|
||||
|
@ -113,6 +115,12 @@ class Create(base.MistralLister):
|
|||
type=argparse.FileType('r'),
|
||||
help='Workflow definition file.'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--namespace',
|
||||
nargs='?',
|
||||
default='',
|
||||
help="Namespace to create the workflow within.",
|
||||
)
|
||||
parser.add_argument(
|
||||
'--public',
|
||||
action='store_true',
|
||||
|
@ -135,6 +143,7 @@ class Create(base.MistralLister):
|
|||
|
||||
return mistral_client.workflows.create(
|
||||
parsed_args.definition.read(),
|
||||
namespace=parsed_args.namespace,
|
||||
scope=scope
|
||||
)
|
||||
|
||||
|
@ -151,12 +160,21 @@ class Delete(command.Command):
|
|||
help='Name or ID of workflow(s).'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--namespace',
|
||||
nargs='?',
|
||||
default=None,
|
||||
help="Parent task execution ID associated with workflow "
|
||||
"execution list.",
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
def take_action(self, parsed_args):
|
||||
mistral_client = self.app.client_manager.workflow_engine
|
||||
utils.do_action_on_many(
|
||||
lambda s: mistral_client.workflows.delete(s),
|
||||
lambda s: mistral_client.workflows.delete(s,
|
||||
parsed_args.namespace),
|
||||
parsed_args.workflow,
|
||||
"Request to delete workflow %s has been accepted.",
|
||||
"Unable to delete the specified workflow(s)."
|
||||
|
@ -174,7 +192,17 @@ class Update(base.MistralLister):
|
|||
type=argparse.FileType('r'),
|
||||
help='Workflow definition'
|
||||
)
|
||||
|
||||
parser.add_argument('--id', help='Workflow ID.')
|
||||
|
||||
parser.add_argument(
|
||||
'--namespace',
|
||||
nargs='?',
|
||||
default='',
|
||||
help="Parent task execution ID associated with workflow "
|
||||
"execution list.",
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--public',
|
||||
action='store_true',
|
||||
|
@ -193,7 +221,8 @@ class Update(base.MistralLister):
|
|||
return mistral_client.workflows.update(
|
||||
parsed_args.definition.read(),
|
||||
scope=scope,
|
||||
id=parsed_args.id
|
||||
id=parsed_args.id,
|
||||
namespace=parsed_args.namespace
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -54,6 +54,22 @@ class MistralClientTestBase(base.MistralCLIAuth, base.MistralCLIAltAuth):
|
|||
cls.wf_wrapping_wf = os.path.relpath(
|
||||
'functionaltests/resources/v2/wf_wrapping_wf_v2.yaml', os.getcwd()
|
||||
)
|
||||
cls.top_level_wf = os.path.relpath(
|
||||
'functionaltests/resources/v2/for_namespaces/top_level_wf.yaml',
|
||||
os.getcwd()
|
||||
)
|
||||
cls.middle_wf = os.path.relpath(
|
||||
'functionaltests/resources/v2/for_namespaces/middle_wf.yaml',
|
||||
os.getcwd()
|
||||
)
|
||||
cls.lowest_level_wf = os.path.relpath(
|
||||
'functionaltests/resources/v2/for_namespaces/lowest_level_wf.yaml',
|
||||
os.getcwd()
|
||||
)
|
||||
cls.async_wf_def = os.path.relpath(
|
||||
'functionaltests/resources/v2/async.yaml',
|
||||
os.getcwd()
|
||||
)
|
||||
|
||||
cls.act_def = os.path.relpath(
|
||||
'functionaltests/resources/v2/action_v2.yaml', os.getcwd()
|
||||
|
@ -120,12 +136,16 @@ class MistralClientTestBase(base.MistralCLIAuth, base.MistralCLIAltAuth):
|
|||
|
||||
return wb
|
||||
|
||||
def workflow_create(self, wf_def, admin=True, scope='private'):
|
||||
def workflow_create(self, wf_def, namespace='', admin=True,
|
||||
scope='private'):
|
||||
params = '{0}'.format(wf_def)
|
||||
|
||||
if scope == 'public':
|
||||
params += ' --public'
|
||||
|
||||
if namespace:
|
||||
params += " --namespace " + namespace
|
||||
|
||||
wf = self.mistral_cli(
|
||||
admin,
|
||||
'workflow-create',
|
||||
|
|
|
@ -256,6 +256,35 @@ class WorkflowCLITests(base_v2.MistralClientTestBase):
|
|||
for wf in wf_names:
|
||||
self.assertNotIn(wf, [workflow['Name'] for workflow in wfs])
|
||||
|
||||
def test_workflow_within_namespace_create_delete(self):
|
||||
params = self.wf_def + ' --namespace abcdef'
|
||||
init_wfs = self.mistral_admin('workflow-create', params=params)
|
||||
|
||||
wf_names = [wf['Name'] for wf in init_wfs]
|
||||
|
||||
self.assertTableStruct(init_wfs, ['Name', 'Created at', 'Updated at'])
|
||||
|
||||
wfs = self.mistral_admin('workflow-list')
|
||||
self.assertIn(wf_names[0], [workflow['Name'] for workflow in wfs])
|
||||
|
||||
for wf_name in wf_names:
|
||||
self.mistral_admin(
|
||||
'workflow-delete',
|
||||
params=wf_name+' --namespace abcdef'
|
||||
)
|
||||
|
||||
wfs = self.mistral_admin('workflow-list')
|
||||
for wf in wf_names:
|
||||
self.assertNotIn(wf, [workflow['Name'] for workflow in wfs])
|
||||
|
||||
init_wfs = self.mistral_admin('workflow-create', params=params)
|
||||
wf_ids = [wf['ID'] for wf in init_wfs]
|
||||
for wf_id in wf_ids:
|
||||
self.mistral_admin('workflow-delete', params=wf_id)
|
||||
|
||||
for wf in wf_names:
|
||||
self.assertNotIn(wf, [workflow['Name'] for workflow in wfs])
|
||||
|
||||
def test_create_wf_with_tags(self):
|
||||
init_wfs = self.workflow_create(self.wf_def)
|
||||
wf_name = init_wfs[1]['Name']
|
||||
|
@ -357,6 +386,96 @@ class WorkflowCLITests(base_v2.MistralClientTestBase):
|
|||
updated_wf_info['Updated at']
|
||||
)
|
||||
|
||||
def test_workflow_update_within_namespace(self):
|
||||
namespace = 'abc'
|
||||
wf = self.workflow_create(self.wf_def, namespace=namespace)
|
||||
|
||||
wf_name = wf[0]['Name']
|
||||
wf_id = wf[0]['ID']
|
||||
wf_namespace = wf[0]['Namespace']
|
||||
created_wf_info = self.get_item_info(
|
||||
get_from=wf,
|
||||
get_by='Name',
|
||||
value=wf_name
|
||||
)
|
||||
|
||||
# Update a workflow with definition unchanged.
|
||||
upd_wf = self.mistral_admin(
|
||||
'workflow-update',
|
||||
params='{0} --namespace {1}'.format(self.wf_def, namespace)
|
||||
)
|
||||
|
||||
self.assertTableStruct(upd_wf, ['Name', 'Created at', 'Updated at'])
|
||||
|
||||
updated_wf_info = self.get_item_info(
|
||||
get_from=upd_wf,
|
||||
get_by='Name',
|
||||
value=wf_name
|
||||
)
|
||||
|
||||
self.assertEqual(wf_name, upd_wf[0]['Name'])
|
||||
self.assertEqual(namespace, wf_namespace)
|
||||
self.assertEqual(wf_namespace, upd_wf[0]['Namespace'])
|
||||
self.assertEqual(
|
||||
created_wf_info['Created at'].split(".")[0],
|
||||
updated_wf_info['Created at']
|
||||
)
|
||||
self.assertEqual(
|
||||
created_wf_info['Updated at'],
|
||||
updated_wf_info['Updated at']
|
||||
)
|
||||
|
||||
# Update a workflow with definition changed.
|
||||
upd_wf = self.mistral_admin(
|
||||
'workflow-update',
|
||||
params='{0} --namespace {1}'.format(
|
||||
self.wf_with_delay_def,
|
||||
namespace
|
||||
)
|
||||
)
|
||||
|
||||
self.assertTableStruct(upd_wf, ['Name', 'Created at', 'Updated at'])
|
||||
|
||||
updated_wf_info = self.get_item_info(
|
||||
get_from=upd_wf,
|
||||
get_by='Name',
|
||||
value=wf_name
|
||||
)
|
||||
|
||||
self.assertEqual(wf_name, upd_wf[0]['Name'])
|
||||
self.assertEqual(
|
||||
created_wf_info['Created at'].split(".")[0],
|
||||
updated_wf_info['Created at']
|
||||
)
|
||||
self.assertNotEqual(
|
||||
created_wf_info['Updated at'],
|
||||
updated_wf_info['Updated at']
|
||||
)
|
||||
|
||||
# Update a workflow with uuid.
|
||||
upd_wf = self.mistral_admin(
|
||||
'workflow-update',
|
||||
params='{0} --id {1}'.format(self.wf_with_delay_def, wf_id)
|
||||
)
|
||||
|
||||
self.assertTableStruct(upd_wf, ['Name', 'Created at', 'Updated at'])
|
||||
|
||||
updated_wf_info = self.get_item_info(
|
||||
get_from=upd_wf,
|
||||
get_by='ID',
|
||||
value=wf_id
|
||||
)
|
||||
|
||||
self.assertEqual(wf_name, upd_wf[0]['Name'])
|
||||
self.assertEqual(
|
||||
created_wf_info['Created at'].split(".")[0],
|
||||
updated_wf_info['Created at']
|
||||
)
|
||||
self.assertNotEqual(
|
||||
created_wf_info['Updated at'],
|
||||
updated_wf_info['Updated at']
|
||||
)
|
||||
|
||||
def test_workflow_update_truncate_input(self):
|
||||
input_value = "very_long_input_parameter_name_that_should_be_truncated"
|
||||
|
||||
|
@ -476,6 +595,7 @@ class ExecutionCLITests(base_v2.MistralClientTestBase):
|
|||
super(ExecutionCLITests, self).setUp()
|
||||
|
||||
wfs = self.workflow_create(self.wf_def)
|
||||
self.async_wf = self.workflow_create(self.async_wf_def)[0]
|
||||
|
||||
self.direct_wf = wfs[0]
|
||||
self.reverse_wf = wfs[1]
|
||||
|
@ -483,7 +603,64 @@ class ExecutionCLITests(base_v2.MistralClientTestBase):
|
|||
self.create_file('input', '{\n "farewell": "Bye"\n}\n')
|
||||
self.create_file('task_name', '{\n "task_name": "goodbye"\n}\n')
|
||||
|
||||
def test_execution_by_id_of_workflow_within_namespace(self):
|
||||
namespace = 'abc'
|
||||
|
||||
wfs = self.workflow_create(self.lowest_level_wf, namespace=namespace)
|
||||
|
||||
wf_def_name = wfs[0]['Name']
|
||||
wf_id = wfs[0]['ID']
|
||||
|
||||
execution = self.execution_create(wf_id)
|
||||
|
||||
self.assertTableStruct(execution, ['Field', 'Value'])
|
||||
|
||||
wf_name = self.get_field_value(execution, 'Workflow name')
|
||||
wf_namespace = self.get_field_value(execution, 'Workflow namespace')
|
||||
wf_id = self.get_field_value(execution, 'Workflow ID')
|
||||
|
||||
self.assertEqual(wf_def_name, wf_name)
|
||||
self.assertEqual(namespace, wf_namespace)
|
||||
self.assertIsNotNone(wf_id)
|
||||
|
||||
def test_execution_within_namespace_create_delete(self):
|
||||
namespace = 'abc'
|
||||
|
||||
self.workflow_create(self.lowest_level_wf)
|
||||
self.workflow_create(self.lowest_level_wf, namespace=namespace)
|
||||
self.workflow_create(self.middle_wf, namespace=namespace)
|
||||
self.workflow_create(self.top_level_wf)
|
||||
wfs = self.workflow_create(self.top_level_wf, namespace=namespace)
|
||||
|
||||
top_wf_name = wfs[0]['Name']
|
||||
execution = self.mistral_admin(
|
||||
'execution-create',
|
||||
params='{0} --namespace {1}'.format(top_wf_name, namespace)
|
||||
)
|
||||
exec_id = self.get_field_value(execution, 'ID')
|
||||
|
||||
self.assertTableStruct(execution, ['Field', 'Value'])
|
||||
|
||||
wf_name = self.get_field_value(execution, 'Workflow name')
|
||||
wf_namespace = self.get_field_value(execution, 'Workflow namespace')
|
||||
wf_id = self.get_field_value(execution, 'Workflow ID')
|
||||
created_at = self.get_field_value(execution, 'Created at')
|
||||
|
||||
self.assertEqual(top_wf_name, wf_name)
|
||||
self.assertEqual(namespace, wf_namespace)
|
||||
self.assertIsNotNone(wf_id)
|
||||
self.assertIsNotNone(created_at)
|
||||
|
||||
execs = self.mistral_admin('execution-list')
|
||||
|
||||
self.assertIn(exec_id, [ex['ID'] for ex in execs])
|
||||
self.assertIn(wf_name, [ex['Workflow name'] for ex in execs])
|
||||
self.assertIn(namespace, [ex['Workflow namespace'] for ex in execs])
|
||||
|
||||
self.mistral_admin('execution-delete', params=exec_id)
|
||||
|
||||
def test_execution_create_delete(self):
|
||||
|
||||
execution = self.mistral_admin(
|
||||
'execution-create',
|
||||
params='{0} -d "execution test"'.format(self.direct_wf['Name'])
|
||||
|
@ -522,7 +699,7 @@ class ExecutionCLITests(base_v2.MistralClientTestBase):
|
|||
self.assertTrue(result)
|
||||
|
||||
def test_execution_update(self):
|
||||
execution = self.execution_create(self.direct_wf['Name'])
|
||||
execution = self.execution_create(self.async_wf['Name'])
|
||||
|
||||
exec_id = self.get_field_value(execution, 'ID')
|
||||
status = self.get_field_value(execution, 'State')
|
||||
|
@ -917,9 +1094,41 @@ class TaskCLITests(base_v2.MistralClientTestBase):
|
|||
|
||||
fetched_task = self.mistral_admin('task-get', params=created_task_id)
|
||||
fetched_task_id = self.get_field_value(fetched_task, 'ID')
|
||||
fetched_task_wf_namespace = self.get_field_value(
|
||||
fetched_task,
|
||||
'Workflow namespace'
|
||||
)
|
||||
task_execution_id = self.get_field_value(fetched_task, 'Execution ID')
|
||||
|
||||
self.assertEqual(created_task_id, fetched_task_id)
|
||||
self.assertEqual('', fetched_task_wf_namespace)
|
||||
self.assertEqual(wf_ex_id, task_execution_id)
|
||||
|
||||
def test_task_get_list_within_namespace(self):
|
||||
namespace = 'aaa'
|
||||
self.workflow_create(self.wf_def, namespace=namespace)
|
||||
wf_ex = self.execution_create(
|
||||
self.direct_wf['Name'] + ' --namespace ' + namespace
|
||||
)
|
||||
|
||||
wf_ex_id = self.get_field_value(wf_ex, 'ID')
|
||||
|
||||
tasks = self.mistral_admin('task-list', params=wf_ex_id)
|
||||
|
||||
created_task_id = tasks[-1]['ID']
|
||||
created_wf_namespace = tasks[-1]['Workflow namespace']
|
||||
|
||||
fetched_task = self.mistral_admin('task-get', params=created_task_id)
|
||||
fetched_task_id = self.get_field_value(fetched_task, 'ID')
|
||||
fetched_task_wf_namespace = self.get_field_value(
|
||||
fetched_task,
|
||||
'Workflow namespace'
|
||||
)
|
||||
task_execution_id = self.get_field_value(fetched_task, 'Execution ID')
|
||||
|
||||
self.assertEqual(created_task_id, fetched_task_id)
|
||||
self.assertEqual(namespace, created_wf_namespace)
|
||||
self.assertEqual(created_wf_namespace, fetched_task_wf_namespace)
|
||||
self.assertEqual(wf_ex_id, task_execution_id)
|
||||
|
||||
def test_task_list_with_filter(self):
|
||||
|
@ -1377,6 +1586,39 @@ class ActionExecutionCLITests(base_v2.MistralClientTestBase):
|
|||
self.assertEqual(self.direct_wf['Name'], act_ex['Workflow name'])
|
||||
self.assertEqual('SUCCESS', act_ex['State'])
|
||||
|
||||
def test_act_execution_get_list_within_namespace(self):
|
||||
namespace = 'bbb'
|
||||
self.workflow_create(self.wf_def, namespace=namespace)
|
||||
wf_ex = self.execution_create(
|
||||
self.direct_wf['Name'] + ' --namespace ' + namespace
|
||||
)
|
||||
exec_id = self.get_field_value(wf_ex, 'ID')
|
||||
self.wait_execution_success(exec_id)
|
||||
task = self.mistral_admin('task-list', params=exec_id)[0]
|
||||
|
||||
act_ex_from_list = self.mistral_admin(
|
||||
'action-execution-list',
|
||||
params=task['ID']
|
||||
)[0]
|
||||
|
||||
act_ex = self.mistral_admin(
|
||||
'action-execution-get',
|
||||
params=act_ex_from_list['ID']
|
||||
)
|
||||
|
||||
wf_name = self.get_field_value(act_ex, 'Workflow name')
|
||||
wf_namespace = self.get_field_value(act_ex, 'Workflow namespace')
|
||||
status = self.get_field_value(act_ex, 'State')
|
||||
|
||||
self.assertEqual(
|
||||
act_ex_from_list['ID'],
|
||||
self.get_field_value(act_ex, 'ID')
|
||||
)
|
||||
self.assertEqual(self.direct_wf['Name'], wf_name)
|
||||
self.assertEqual('SUCCESS', status)
|
||||
self.assertEqual(namespace, wf_namespace)
|
||||
self.assertEqual(namespace, act_ex_from_list['Workflow namespace'])
|
||||
|
||||
def test_act_execution_create_delete(self):
|
||||
action_ex = self.mistral_admin(
|
||||
'run-action',
|
||||
|
|
|
@ -30,6 +30,7 @@ ACTION_EX_DICT = {
|
|||
'id': '123',
|
||||
'name': 'some',
|
||||
'workflow_name': 'thing',
|
||||
'workflow_namespace': '',
|
||||
'task_name': 'task1',
|
||||
'task_execution_id': "1-2-3-4",
|
||||
'state': 'RUNNING',
|
||||
|
@ -86,7 +87,7 @@ class TestCLIActionExecutions(base.BaseCommandTest):
|
|||
)
|
||||
|
||||
self.assertEqual(
|
||||
('123', 'some', 'thing', 'task1', '1-2-3-4', 'RUNNING',
|
||||
('123', 'some', 'thing', '', 'task1', '1-2-3-4', 'RUNNING',
|
||||
'RUNNING somehow.', True, '1', '1'),
|
||||
result[1]
|
||||
)
|
||||
|
@ -142,6 +143,7 @@ class TestCLIActionExecutions(base.BaseCommandTest):
|
|||
action_ex_dict['id'],
|
||||
action_ex_dict['name'],
|
||||
action_ex_dict['workflow_name'],
|
||||
action_ex_dict['workflow_namespace'],
|
||||
action_ex_dict['task_name'],
|
||||
action_ex_dict['task_execution_id'],
|
||||
action_ex_dict['state'],
|
||||
|
@ -178,7 +180,7 @@ class TestCLIActionExecutions(base.BaseCommandTest):
|
|||
result = self.call(action_ex_cmd.List)
|
||||
|
||||
self.assertEqual(
|
||||
[('123', 'some', 'thing', 'task1', '1-2-3-4', 'RUNNING', True,
|
||||
[('123', 'some', 'thing', '', 'task1', '1-2-3-4', 'RUNNING', True,
|
||||
'1', '1')],
|
||||
result[1]
|
||||
)
|
||||
|
@ -189,7 +191,7 @@ class TestCLIActionExecutions(base.BaseCommandTest):
|
|||
result = self.call(action_ex_cmd.Get, app_args=['id'])
|
||||
|
||||
self.assertEqual(
|
||||
('123', 'some', 'thing', 'task1', '1-2-3-4', 'RUNNING',
|
||||
('123', 'some', 'thing', '', 'task1', '1-2-3-4', 'RUNNING',
|
||||
'RUNNING somehow.', True, '1', '1'), result[1]
|
||||
)
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ EXEC = executions.Execution(
|
|||
'id': '123',
|
||||
'workflow_id': '123e4567-e89b-12d3-a456-426655440000',
|
||||
'workflow_name': 'some',
|
||||
'workflow_namespace': '',
|
||||
'description': '',
|
||||
'state': 'RUNNING',
|
||||
'state_info': None,
|
||||
|
@ -47,6 +48,7 @@ SUB_WF_EXEC = executions.Execution(
|
|||
'id': '456',
|
||||
'workflow_id': '123e4567-e89b-12d3-a456-426655440000',
|
||||
'workflow_name': 'some_sub_wf',
|
||||
'workflow_namespace': '',
|
||||
'description': '',
|
||||
'state': 'RUNNING',
|
||||
'state_info': None,
|
||||
|
@ -61,6 +63,7 @@ EX_RESULT = (
|
|||
'123e4567-e89b-12d3-a456-426655440000',
|
||||
'some',
|
||||
'',
|
||||
'',
|
||||
'<none>',
|
||||
'RUNNING',
|
||||
None,
|
||||
|
@ -73,6 +76,7 @@ SUB_WF_EX_RESULT = (
|
|||
'123e4567-e89b-12d3-a456-426655440000',
|
||||
'some_sub_wf',
|
||||
'',
|
||||
'',
|
||||
'abc',
|
||||
'RUNNING',
|
||||
None,
|
||||
|
@ -154,6 +158,7 @@ class TestCLIExecutionsV2(base.BaseCommandTest):
|
|||
'id': '123',
|
||||
'workflow_id': '123e4567-e89b-12d3-a456-426655440000',
|
||||
'workflow_name': 'some',
|
||||
'workflow_namespace': '',
|
||||
'description': '',
|
||||
'state': state,
|
||||
'state_info': None,
|
||||
|
@ -164,7 +169,7 @@ class TestCLIExecutionsV2(base.BaseCommandTest):
|
|||
)
|
||||
|
||||
ex_result = list(EX_RESULT)
|
||||
ex_result[5] = state
|
||||
ex_result[6] = state
|
||||
ex_result = tuple(ex_result)
|
||||
|
||||
result = self.call(
|
||||
|
|
|
@ -28,6 +28,7 @@ TASK_DICT = {
|
|||
'id': '123',
|
||||
'name': 'some',
|
||||
'workflow_name': 'thing',
|
||||
'workflow_namespace': '',
|
||||
'workflow_execution_id': '321',
|
||||
'state': 'RUNNING',
|
||||
'state_info': None,
|
||||
|
@ -48,7 +49,7 @@ TASK_WITH_RESULT = tasks.Task(mock, TASK_WITH_RESULT_DICT)
|
|||
TASK_WITH_PUBLISHED = tasks.Task(mock, TASK_WITH_PUBLISHED_DICT)
|
||||
|
||||
EXPECTED_TASK_RESULT = (
|
||||
'123', 'some', 'thing', '321', 'RUNNING', None, '1', '1'
|
||||
'123', 'some', 'thing', '', '321', 'RUNNING', None, '1', '1'
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ from mistralclient.tests.unit import base
|
|||
WORKFLOW_DICT = {
|
||||
'id': '1-2-3-4',
|
||||
'name': 'a',
|
||||
'namespace': '',
|
||||
'project_id': '12345',
|
||||
'tags': ['a', 'b'],
|
||||
'input': 'param',
|
||||
|
@ -55,7 +56,7 @@ class TestCLIWorkflowsV2(base.BaseCommandTest):
|
|||
result = self.call(workflow_cmd.Create, app_args=['1.txt'])
|
||||
|
||||
self.assertEqual(
|
||||
[('1-2-3-4', 'a', '12345', 'a, b', 'param', '1', '1')],
|
||||
[('1-2-3-4', 'a', '', '12345', 'a, b', 'param', '1', '1')],
|
||||
result[1]
|
||||
)
|
||||
|
||||
|
@ -69,7 +70,7 @@ class TestCLIWorkflowsV2(base.BaseCommandTest):
|
|||
)
|
||||
|
||||
self.assertEqual(
|
||||
[('1-2-3-4', 'a', '12345', 'a, b', 'param', '1', '1')],
|
||||
[('1-2-3-4', 'a', '', '12345', 'a, b', 'param', '1', '1')],
|
||||
result[1]
|
||||
)
|
||||
|
||||
|
@ -91,7 +92,7 @@ class TestCLIWorkflowsV2(base.BaseCommandTest):
|
|||
result = self.call(workflow_cmd.Create, app_args=['1.txt'])
|
||||
|
||||
self.assertEqual(
|
||||
[('1-2-3-4', 'a', '12345', 'a, b', cmd_base.cut(long_input),
|
||||
[('1-2-3-4', 'a', '', '12345', 'a, b', cmd_base.cut(long_input),
|
||||
'1', '1')],
|
||||
result[1]
|
||||
)
|
||||
|
@ -103,7 +104,7 @@ class TestCLIWorkflowsV2(base.BaseCommandTest):
|
|||
result = self.call(workflow_cmd.Update, app_args=['1.txt'])
|
||||
|
||||
self.assertEqual(
|
||||
[('1-2-3-4', 'a', '12345', 'a, b', 'param', '1', '1')],
|
||||
[('1-2-3-4', 'a', '', '12345', 'a, b', 'param', '1', '1')],
|
||||
result[1]
|
||||
)
|
||||
|
||||
|
@ -117,7 +118,7 @@ class TestCLIWorkflowsV2(base.BaseCommandTest):
|
|||
)
|
||||
|
||||
self.assertEqual(
|
||||
[('1-2-3-4', 'a', '12345', 'a, b', 'param', '1', '1')],
|
||||
[('1-2-3-4', 'a', '', '12345', 'a, b', 'param', '1', '1')],
|
||||
result[1]
|
||||
)
|
||||
|
||||
|
@ -136,7 +137,7 @@ class TestCLIWorkflowsV2(base.BaseCommandTest):
|
|||
)
|
||||
|
||||
self.assertEqual(
|
||||
[('1-2-3-4', 'a', '12345', 'a, b', 'param', '1', '1')],
|
||||
[('1-2-3-4', 'a', '', '12345', 'a, b', 'param', '1', '1')],
|
||||
result[1]
|
||||
)
|
||||
|
||||
|
@ -146,7 +147,7 @@ class TestCLIWorkflowsV2(base.BaseCommandTest):
|
|||
result = self.call(workflow_cmd.List)
|
||||
|
||||
self.assertEqual(
|
||||
[('1-2-3-4', 'a', '12345', 'a, b', 'param', '1', '1')],
|
||||
[('1-2-3-4', 'a', '', '12345', 'a, b', 'param', '1', '1')],
|
||||
result[1]
|
||||
)
|
||||
|
||||
|
@ -156,21 +157,21 @@ class TestCLIWorkflowsV2(base.BaseCommandTest):
|
|||
result = self.call(workflow_cmd.Get, app_args=['name'])
|
||||
|
||||
self.assertEqual(
|
||||
('1-2-3-4', 'a', '12345', 'a, b', 'param', '1', '1'),
|
||||
('1-2-3-4', 'a', '', '12345', 'a, b', 'param', '1', '1'),
|
||||
result[1]
|
||||
)
|
||||
|
||||
def test_delete(self):
|
||||
self.call(workflow_cmd.Delete, app_args=['name'])
|
||||
|
||||
self.client.workflows.delete.assert_called_once_with('name')
|
||||
self.client.workflows.delete.assert_called_once_with('name', None)
|
||||
|
||||
def test_delete_with_multi_names(self):
|
||||
self.call(workflow_cmd.Delete, app_args=['name1', 'name2'])
|
||||
|
||||
self.assertEqual(2, self.client.workflows.delete.call_count)
|
||||
self.assertEqual(
|
||||
[mock.call('name1'), mock.call('name2')],
|
||||
[mock.call('name1', None), mock.call('name2', None)],
|
||||
self.client.workflows.delete.call_args_list
|
||||
)
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ EXEC = {
|
|||
'id': "123",
|
||||
'workflow_id': '123e4567-e89b-12d3-a456-426655440000',
|
||||
'workflow_name': 'my_wf',
|
||||
'workflow_namespace': '',
|
||||
'description': '',
|
||||
'state': 'RUNNING',
|
||||
'input': {
|
||||
|
@ -39,6 +40,7 @@ SUB_WF_EXEC = {
|
|||
'id': "456",
|
||||
'workflow_id': '123e4567-e89b-12d3-a456-426655440000',
|
||||
'workflow_name': 'my_sub_wf',
|
||||
'workflow_namespace': '',
|
||||
'task_execution_id': "abc",
|
||||
'description': '',
|
||||
'state': 'RUNNING',
|
||||
|
@ -68,6 +70,7 @@ class TestExecutionsV2(base.BaseClientV2Test):
|
|||
|
||||
ex = self.executions.create(
|
||||
EXEC['workflow_name'],
|
||||
EXEC['workflow_namespace'],
|
||||
EXEC['input']
|
||||
)
|
||||
|
||||
|
@ -93,7 +96,7 @@ class TestExecutionsV2(base.BaseClientV2Test):
|
|||
|
||||
ex = self.executions.create(
|
||||
EXEC['workflow_id'],
|
||||
EXEC['input']
|
||||
workflow_input=EXEC['input']
|
||||
)
|
||||
|
||||
self.assertIsNotNone(ex)
|
||||
|
|
|
@ -106,7 +106,7 @@ class TestWorkflowsV2(base.BaseClientV2Test):
|
|||
|
||||
last_request = self.requests_mock.last_request
|
||||
|
||||
self.assertEqual('scope=private', last_request.query)
|
||||
self.assertEqual('namespace=&scope=private', last_request.query)
|
||||
self.assertEqual(WF_DEF, last_request.text)
|
||||
self.assertEqual('text/plain', last_request.headers['content-type'])
|
||||
|
||||
|
|
Loading…
Reference in New Issue