From 026cb4a76e3c90b3a58d8f4fcec0fb205b04ce61 Mon Sep 17 00:00:00 2001 From: James Slagle Date: Thu, 27 Apr 2017 15:16:07 -0400 Subject: [PATCH] Handle failed actions The result of syncrhonously called Mistral actions wasn't being checked to see if the action passed or failed. The result is now checked and if the action has failed, an exception will be raised. Change-Id: I95ae8c98fec94cf91f3f209b593f6c1815729fd4 Closes-Bug: #1686811 --- ...andle-failed-actions-cac0abd02ed67a51.yaml | 5 +++++ tripleoclient/exceptions.py | 9 ++++++++ tripleoclient/tests/workflows/test_base.py | 22 +++++++++++++++++++ tripleoclient/workflows/base.py | 6 ++++- 4 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 releasenotes/notes/handle-failed-actions-cac0abd02ed67a51.yaml diff --git a/releasenotes/notes/handle-failed-actions-cac0abd02ed67a51.yaml b/releasenotes/notes/handle-failed-actions-cac0abd02ed67a51.yaml new file mode 100644 index 000000000..7765f889c --- /dev/null +++ b/releasenotes/notes/handle-failed-actions-cac0abd02ed67a51.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - The result of Mistral actions will now be checked, and if they've failed, + an exception will be raised. See + https://bugs.launchpad.net/tripleo/+bug/1686811 diff --git a/tripleoclient/exceptions.py b/tripleoclient/exceptions.py index 58f08742d..a87988fcc 100644 --- a/tripleoclient/exceptions.py +++ b/tripleoclient/exceptions.py @@ -78,3 +78,12 @@ class PlanCreationError(Exception): class PlanExportError(Exception): """Plan export failed""" + + +class WorkflowActionError(Exception): + """Workflow action failed""" + msg_format = "Action {} execution failed: {}" + + def __init__(self, message, action='', output=''): + message = message.format(action, output) + super(WorkflowActionError, self).__init__(message) diff --git a/tripleoclient/tests/workflows/test_base.py b/tripleoclient/tests/workflows/test_base.py index c2961336a..c1248b313 100644 --- a/tripleoclient/tests/workflows/test_base.py +++ b/tripleoclient/tests/workflows/test_base.py @@ -58,3 +58,25 @@ class TestBaseWorkflows(utils.TestCommand): self.assertTrue(mistral.executions.get.called) websocket.wait_for_messages.assert_called_with(timeout=None) + + def test_call_action_success(self): + mistral = mock.Mock() + action = 'test-action' + + result = mock.Mock() + result.output = '{"result":"test-result"}' + mistral.action_executions.create = mock.Mock(return_value=result) + + self.assertEqual(base.call_action(mistral, action), "test-result") + + def test_call_action_fail(self): + mistral = mock.Mock() + action = 'test-action' + + result = mock.Mock() + result.output = '{"result":"test-result"}' + result.state = 'ERROR' + mistral.action_executions.create = mock.Mock(return_value=result) + + self.assertRaises(exceptions.WorkflowActionError, + base.call_action, mistral, action) diff --git a/tripleoclient/workflows/base.py b/tripleoclient/workflows/base.py index 7f91796b5..7592a69fc 100644 --- a/tripleoclient/workflows/base.py +++ b/tripleoclient/workflows/base.py @@ -25,7 +25,11 @@ def call_action(workflow_client, action, **input_): save_result=True, run_sync=True) # Parse the JSON output. Mistral client should do this for us really. - return json.loads(result.output)['result'] + output = json.loads(result.output)['result'] + + if result.state == 'ERROR': + raise exceptions.WorkflowActionError(action, output) + return output def start_workflow(workflow_client, identifier, workflow_input):