diff --git a/tripleoclient/exceptions.py b/tripleoclient/exceptions.py index ffa24910d..8e7538cbf 100644 --- a/tripleoclient/exceptions.py +++ b/tripleoclient/exceptions.py @@ -71,3 +71,7 @@ class PasswordFileNotFound(Exception): class RootDeviceDetectionError(Exception): """Failed to detect the root device""" + + +class PlanCreationError(Exception): + """Plan creation failed""" diff --git a/tripleoclient/tests/workflows/test_plan_management.py b/tripleoclient/tests/workflows/test_plan_management.py new file mode 100644 index 000000000..85c234c9a --- /dev/null +++ b/tripleoclient/tests/workflows/test_plan_management.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- + +# 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. + +import mock + +from openstackclient.tests import utils + +from tripleoclient import exceptions +from tripleoclient.workflows import plan_management + + +class TestPlanCreationWorkflows(utils.TestCommand): + + def setUp(self): + super(TestPlanCreationWorkflows, self).setUp() + + self.app.client_manager.workflow_engine = self.workflow = mock.Mock() + self.tripleoclient = mock.Mock() + self.websocket = mock.Mock() + self.websocket.__enter__ = lambda s: self.websocket + self.websocket.__exit__ = lambda s, *exc: None + self.tripleoclient.messaging_websocket.return_value = self.websocket + self.app.client_manager.tripleoclient = self.tripleoclient + + uuid4_patcher = mock.patch('uuid.uuid4', return_value="UUID4") + self.mock_uuid4 = uuid4_patcher.start() + self.addCleanup(self.mock_uuid4.stop) + + @mock.patch('tripleoclient.workflows.plan_management.tarball', + autospec=True) + def test_create_plan_from_templates_success(self, mock_tarball): + output = mock.Mock(output='{"result": ""}') + self.workflow.action_executions.create.return_value = output + self.websocket.wait_for_message.return_value = { + "status": "SUCCESS", + } + + plan_management.create_plan_from_templates( + self.app.client_manager, + 'test-overcloud', + '/tht-root/') + + self.workflow.action_executions.create.assert_called_once_with( + 'tripleo.plan.create_container', + {'container': 'test-overcloud'}) + + self.workflow.executions.create.assert_called_once_with( + 'tripleo.plan_management.v1.create_deployment_plan', + workflow_input={'queue_name': 'UUID4', + 'container': 'test-overcloud'}) + + @mock.patch('tripleoclient.workflows.plan_management.tarball', + autospec=True) + def test_create_plan_from_templates_container_error(self, mock_tarball): + error = mock.Mock(output='{"result": "Error"}') + self.workflow.action_executions.create.return_value = error + + self.assertRaises( + exceptions.PlanCreationError, + plan_management.create_plan_from_templates, + self.app.client_manager, + 'test-overcloud', + '/tht-root/') + + self.workflow.action_executions.create.assert_called_once_with( + 'tripleo.plan.create_container', + {'container': 'test-overcloud'}) + + self.workflow.executions.create.assert_not_called() diff --git a/tripleoclient/workflows/plan_management.py b/tripleoclient/workflows/plan_management.py index f6c2cf8a7..42c64a5cd 100644 --- a/tripleoclient/workflows/plan_management.py +++ b/tripleoclient/workflows/plan_management.py @@ -49,7 +49,6 @@ def create_default_plan(clients, **workflow_input): def _create_update_deployment_plan(clients, workflow, **workflow_input): - workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient queue_name = workflow_input['queue_name'] @@ -101,7 +100,13 @@ def create_plan_from_templates(clients, name, tht_root): swift_client = clients.tripleoclient.object_store print("Creating Swift container to store the plan") - create_container(workflow_client, container=name) + result = create_container(workflow_client, container=name) + if result: + # create_container returns 'None' on success and a string with + # the error message when failing. + raise exceptions.PlanCreationError( + "Unable to create plan. {}".format(result)) + print("Creating plan from template files in: {}".format(tht_root)) _upload_templates(swift_client, name, tht_root) create_deployment_plan(clients, container=name, @@ -111,7 +116,7 @@ def create_plan_from_templates(clients, name, tht_root): def update_plan_from_templates(clients, name, tht_root): swift_client = clients.tripleoclient.object_store - # TODO(dmatthews): Remvoing the exisitng plan files should probably be + # TODO(dmatthews): Removing the existing plan files should probably be # a Mistral action. print("Removing the current plan files") headers, objects = swift_client.get_container(name)