From 29e73e3fa1eb122ccfdbf822b028d2ea86ee4fd1 Mon Sep 17 00:00:00 2001 From: Hongbin Lu Date: Sun, 13 Dec 2015 12:28:56 -0500 Subject: [PATCH] Handle the case that stack has no "outputs" Object "stack" returned by Heat doesn't necessary have the "outputs" attribute. This could happen when a stack is in failure state. Magnum needs to handle this case robustly. Closes-Bug: #1525678 Change-Id: I288af63bd9e2704f9869f3eaf8d8d4c6495a7973 --- magnum/conductor/template_definition.py | 2 +- .../unit/conductor/test_template_definition.py | 14 ++++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/magnum/conductor/template_definition.py b/magnum/conductor/template_definition.py index 8a9550403b..25ef6c06b4 100644 --- a/magnum/conductor/template_definition.py +++ b/magnum/conductor/template_definition.py @@ -135,7 +135,7 @@ class OutputMapping(object): return self.heat_output == output_key def get_output_value(self, stack): - for output in stack.outputs: + for output in stack.to_dict().get('outputs', []): if output['output_key'] == self.heat_output: return output['output_value'] diff --git a/magnum/tests/unit/conductor/test_template_definition.py b/magnum/tests/unit/conductor/test_template_definition.py index b1a58553ea..e076b972ef 100644 --- a/magnum/tests/unit/conductor/test_template_definition.py +++ b/magnum/tests/unit/conductor/test_template_definition.py @@ -122,7 +122,7 @@ class TemplateDefinitionTestCase(base.TestCase): ] mock_stack = mock.MagicMock() - mock_stack.outputs = heat_outputs + mock_stack.to_dict.return_value = {'outputs': heat_outputs} output = tdef.OutputMapping('key1') value = output.get_output_value(mock_stack) @@ -136,6 +136,12 @@ class TemplateDefinitionTestCase(base.TestCase): value = output.get_output_value(mock_stack) self.assertIsNone(value) + # verify stack with no 'outputs' attribute + mock_stack.to_dict.return_value = {} + output = tdef.OutputMapping('key1') + value = output.get_output_value(mock_stack) + self.assertIsNone(value) + def test_add_output_with_mapping_type(self): definition = tdef.TemplateDefinition.get_template_definition( 'vm', @@ -315,7 +321,7 @@ class AtomicK8sTemplateDefinitionTestCase(base.TestCase): "output_key": 'api_address'}, ] mock_stack = mock.MagicMock() - mock_stack.outputs = outputs + mock_stack.to_dict.return_value = {'outputs': outputs} mock_bay = mock.MagicMock() mock_baymodel = mock.MagicMock() mock_baymodel.tls_disabled = tls @@ -477,7 +483,7 @@ class AtomicSwarmTemplateDefinitionTestCase(base.TestCase): "output_key": "swarm_nodes"}, ] mock_stack = mock.MagicMock() - mock_stack.outputs = outputs + mock_stack.to_dict.return_value = {'outputs': outputs} mock_bay = mock.MagicMock() mock_baymodel = mock.MagicMock() @@ -523,7 +529,7 @@ class UbuntuMesosTemplateDefinitionTestCase(base.TestCase): "output_key": "mesos_slaves"}, ] mock_stack = mock.MagicMock() - mock_stack.outputs = outputs + mock_stack.to_dict.return_value = {'outputs': outputs} mock_bay = mock.MagicMock() mock_baymodel = mock.MagicMock()