diff --git a/mistralclient/api/v2/executions.py b/mistralclient/api/v2/executions.py index 5ac87b35..bafe87d6 100644 --- a/mistralclient/api/v2/executions.py +++ b/mistralclient/api/v2/executions.py @@ -15,6 +15,7 @@ import json +from oslo_utils import uuidutils import six from mistralclient.api import base @@ -30,15 +31,19 @@ class Execution(base.Resource): class ExecutionManager(base.ResourceManager): resource_class = Execution - def create(self, workflow_name, workflow_input=None, description='', + def create(self, workflow_identifier, workflow_input=None, description='', **params): - self._ensure_not_empty(workflow_name=workflow_name) + self._ensure_not_empty(workflow_identifier=workflow_identifier) data = { - 'workflow_name': workflow_name, 'description': description } + if uuidutils.is_uuid_like(workflow_identifier): + data.update({'workflow_id': workflow_identifier}) + else: + data.update({'workflow_name': workflow_identifier}) + if workflow_input: if isinstance(workflow_input, six.string_types): data.update({'input': workflow_input}) @@ -50,15 +55,6 @@ class ExecutionManager(base.ResourceManager): return self._create('/executions', data) - def create_reverse_workflow(self, workflow_name, workflow_input, - task_name, **params): - params.update({'task_name': task_name}) - - return self.create(workflow_name, workflow_input, **params) - - def create_direct_workflow(self, workflow_name, workflow_input, **params): - return self.create(workflow_name, workflow_input, **params) - def update(self, id, state, description=None, env=None): data = {} diff --git a/mistralclient/commands/v2/executions.py b/mistralclient/commands/v2/executions.py index 77209d24..5c1bc807 100644 --- a/mistralclient/commands/v2/executions.py +++ b/mistralclient/commands/v2/executions.py @@ -35,7 +35,8 @@ def format_list(execution=None): def format(execution=None, lister=False): columns = ( 'ID', - 'Workflow', + 'Workflow ID', + 'Workflow name', 'Description', 'Task Execution ID', 'State', @@ -51,6 +52,7 @@ def format(execution=None, lister=False): data = ( execution.id, + execution.workflow_id, execution.workflow_name, execution.description, execution.task_execution_id or '', @@ -141,8 +143,9 @@ class Create(show.ShowOne): parser = super(Create, self).get_parser(prog_name) parser.add_argument( - 'workflow_name', - help='Workflow name' + 'workflow_identifier', + help='Workflow ID or name. Workflow name will be deprecated since' + 'Mitaka.' ) parser.add_argument( 'workflow_input', @@ -184,7 +187,7 @@ class Create(show.ShowOne): mistral_client = self.app.client_manager.workflow_engine execution = mistral_client.executions.create( - parsed_args.workflow_name, + parsed_args.workflow_identifier, wf_input, parsed_args.description, **params diff --git a/mistralclient/tests/functional/cli/v2/cli_tests_v2.py b/mistralclient/tests/functional/cli/v2/cli_tests_v2.py index 6c949f6a..cb28b98f 100644 --- a/mistralclient/tests/functional/cli/v2/cli_tests_v2.py +++ b/mistralclient/tests/functional/cli/v2/cli_tests_v2.py @@ -50,7 +50,8 @@ class SimpleMistralCLITests(base.MistralCLIAuth): self.mistral('execution-list')) self.assertTableStruct( executions, - ['ID', 'Workflow', 'State', 'Created at', 'Updated at'] + ['ID', 'Workflow name', 'Workflow ID', 'State', 'Created at', + 'Updated at'] ) def test_tasks_list(self): @@ -413,17 +414,19 @@ class ExecutionCLITests(base_v2.MistralClientTestBase): exec_id = self.get_value_of_field(execution, 'ID') self.assertTableStruct(execution, ['Field', 'Value']) - wf = self.get_value_of_field(execution, 'Workflow') + wf_name = self.get_value_of_field(execution, 'Workflow name') + wf_id = self.get_value_of_field(execution, 'Workflow ID') created_at = self.get_value_of_field(execution, 'Created at') description = self.get_value_of_field(execution, 'Description') - self.assertEqual(self.direct_wf['Name'], wf) + self.assertEqual(self.direct_wf['Name'], wf_name) + self.assertIsNotNone(wf_id) self.assertIsNotNone(created_at) self.assertEqual("execution test", description) execs = self.mistral_admin('execution-list') self.assertIn(exec_id, [ex['ID'] for ex in execs]) - self.assertIn(wf, [ex['Workflow'] for ex in execs]) + self.assertIn(wf_name, [ex['Workflow name'] for ex in execs]) self.mistral_admin('execution-delete', params=exec_id) @@ -471,10 +474,12 @@ class ExecutionCLITests(base_v2.MistralClientTestBase): 'execution-get', params='{0}'.format(exec_id)) gotten_id = self.get_value_of_field(execution, 'ID') - wf = self.get_value_of_field(execution, 'Workflow') + wf_name = self.get_value_of_field(execution, 'Workflow name') + wf_id = self.get_value_of_field(execution, 'Workflow ID') + self.assertIsNotNone(wf_id) self.assertEqual(exec_id, gotten_id) - self.assertEqual(self.direct_wf['Name'], wf) + self.assertEqual(self.direct_wf['Name'], wf_name) def test_execution_get_input(self): execution = self.execution_create(self.direct_wf['Name']) diff --git a/mistralclient/tests/unit/v2/test_cli_executions.py b/mistralclient/tests/unit/v2/test_cli_executions.py index 2babeea4..f9c0647c 100644 --- a/mistralclient/tests/unit/v2/test_cli_executions.py +++ b/mistralclient/tests/unit/v2/test_cli_executions.py @@ -26,6 +26,7 @@ EXEC = executions.Execution( mock, { 'id': '123', + 'workflow_id': '123e4567-e89b-12d3-a456-426655440000', 'workflow_name': 'some', 'description': '', 'state': 'RUNNING', @@ -40,6 +41,7 @@ SUB_WF_EXEC = executions.Execution( mock, { 'id': '456', + 'workflow_id': '123e4567-e89b-12d3-a456-426655440000', 'workflow_name': 'some_sub_wf', 'description': '', 'state': 'RUNNING', @@ -50,8 +52,28 @@ SUB_WF_EXEC = executions.Execution( } ) -EX_RESULT = ('123', 'some', '', '', 'RUNNING', None, '1', '1') -SUB_WF_EX_RESULT = ('456', 'some_sub_wf', '', 'abc', 'RUNNING', None, '1', '1') +EX_RESULT = ( + '123', + '123e4567-e89b-12d3-a456-426655440000', + 'some', + '', + '', + 'RUNNING', + None, + '1', + '1' +) +SUB_WF_EX_RESULT = ( + '456', + '123e4567-e89b-12d3-a456-426655440000', + 'some_sub_wf', + '', + 'abc', + 'RUNNING', + None, + '1', + '1' +) class TestCLIExecutionsV2(base.BaseCommandTest): diff --git a/mistralclient/tests/unit/v2/test_executions.py b/mistralclient/tests/unit/v2/test_executions.py index 431ec17f..93b00c8b 100644 --- a/mistralclient/tests/unit/v2/test_executions.py +++ b/mistralclient/tests/unit/v2/test_executions.py @@ -24,6 +24,7 @@ from mistralclient.tests.unit.v2 import base EXEC = { 'id': "123", + 'workflow_id': '123e4567-e89b-12d3-a456-426655440000', 'workflow_name': 'my_wf', 'description': '', 'state': 'RUNNING', @@ -37,6 +38,7 @@ EXEC = { SUB_WF_EXEC = { 'id': "456", + 'workflow_id': '123e4567-e89b-12d3-a456-426655440000', 'workflow_name': 'my_sub_wf', 'task_execution_id': "abc", 'description': '', @@ -69,12 +71,36 @@ class TestExecutionsV2(base.BaseClientV2Test): self.assertIsNotNone(ex) - self.assertEqual( + self.assertDictEqual( executions.Execution(self.executions, EXEC).to_dict(), ex.to_dict() ) - mock.assert_called_once_with(URL_TEMPLATE, json.dumps(body)) + self.assertEqual(URL_TEMPLATE, mock.call_args[0][0]) + self.assertDictEqual(body, json.loads(mock.call_args[0][1])) + + def test_create_with_workflow_id(self): + mock = self.mock_http_post(content=EXEC) + body = { + 'workflow_id': EXEC['workflow_id'], + 'description': '', + 'input': json.dumps(EXEC['input']), + } + + ex = self.executions.create( + EXEC['workflow_id'], + EXEC['input'] + ) + + self.assertIsNotNone(ex) + + self.assertDictEqual( + executions.Execution(self.executions, EXEC).to_dict(), + ex.to_dict() + ) + + self.assertEqual(URL_TEMPLATE, mock.call_args[0][0]) + self.assertDictEqual(body, json.loads(mock.call_args[0][1])) @unittest2.expectedFailure def test_create_failure1(self): @@ -99,15 +125,13 @@ class TestExecutionsV2(base.BaseClientV2Test): self.assertIsNotNone(ex) - self.assertEqual( + self.assertDictEqual( executions.Execution(self.executions, EXEC).to_dict(), ex.to_dict() ) - mock.assert_called_once_with( - URL_TEMPLATE_ID % EXEC['id'], - json.dumps(body) - ) + self.assertEqual(URL_TEMPLATE_ID % EXEC['id'], mock.call_args[0][0]) + self.assertDictEqual(body, json.loads(mock.call_args[0][1])) def test_update_env(self): mock = self.mock_http_put(content=EXEC) @@ -126,15 +150,13 @@ class TestExecutionsV2(base.BaseClientV2Test): self.assertIsNotNone(ex) - self.assertEqual( + self.assertDictEqual( executions.Execution(self.executions, EXEC).to_dict(), ex.to_dict() ) - mock.assert_called_once_with( - URL_TEMPLATE_ID % EXEC['id'], - json.dumps(body) - ) + self.assertEqual(URL_TEMPLATE_ID % EXEC['id'], mock.call_args[0][0]) + self.assertDictEqual(body, json.loads(mock.call_args[0][1])) def test_list(self): mock = self.mock_http_get(content={'executions': [EXEC, SUB_WF_EXEC]}) @@ -143,12 +165,12 @@ class TestExecutionsV2(base.BaseClientV2Test): self.assertEqual(2, len(execution_list)) - self.assertEqual( + self.assertDictEqual( executions.Execution(self.executions, EXEC).to_dict(), execution_list[0].to_dict() ) - self.assertEqual( + self.assertDictEqual( executions.Execution(self.executions, SUB_WF_EXEC).to_dict(), execution_list[1].to_dict() ) @@ -178,7 +200,7 @@ class TestExecutionsV2(base.BaseClientV2Test): ex = self.executions.get(EXEC['id']) - self.assertEqual( + self.assertDictEqual( executions.Execution(self.executions, EXEC).to_dict(), ex.to_dict() ) @@ -190,7 +212,7 @@ class TestExecutionsV2(base.BaseClientV2Test): ex = self.executions.get(SUB_WF_EXEC['id']) - self.assertEqual( + self.assertDictEqual( executions.Execution(self.executions, SUB_WF_EXEC).to_dict(), ex.to_dict() )