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:
Michal Gershenzon 2017-07-28 16:57:33 +00:00
parent 6d638a31dd
commit db428c0858
18 changed files with 396 additions and 33 deletions

View File

@ -0,0 +1,8 @@
---
version: '2.0'
async_wf:
type: direct
tasks:
async_task:
action: std.async_noop

View File

@ -0,0 +1,8 @@
---
version: '2.0'
lowest_level_wf:
type: direct
tasks:
hello:
action: std.noop

View File

@ -0,0 +1,8 @@
---
version: '2.0'
middle_wf:
type: direct
tasks:
hello:
workflow: lowest_level_wf

View File

@ -0,0 +1,8 @@
---
version: '2.0'
top_level_wf:
type: direct
tasks:
hello:
workflow: middle_wf

View File

@ -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})

View File

@ -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)

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -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
)

View File

@ -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',

View File

@ -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',

View File

@ -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]
)

View File

@ -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(

View File

@ -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'
)

View File

@ -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
)

View File

@ -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)

View File

@ -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'])