heat/heat/tests/test_grouputils.py

259 lines
9.0 KiB
Python

#
# 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
import six
from heat.common import grouputils
from heat.common import identifier
from heat.common import template_format
from heat.rpc import client as rpc_client
from heat.tests import common
from heat.tests import utils
nested_stack = '''
heat_template_version: 2013-05-23
resources:
r0:
type: OverwrittenFnGetRefIdType
r1:
type: OverwrittenFnGetRefIdType
'''
class GroupUtilsTest(common.HeatTestCase):
def test_non_nested_resource(self):
group = mock.Mock()
group.nested_identifier.return_value = None
group.nested.return_value = None
self.assertEqual(0, grouputils.get_size(group))
self.assertEqual([], grouputils.get_members(group))
self.assertEqual([], grouputils.get_member_refids(group))
self.assertEqual([], grouputils.get_member_names(group))
def test_normal_group(self):
group = mock.Mock()
t = template_format.parse(nested_stack)
stack = utils.parse_stack(t)
group.nested.return_value = stack
# member list (sorted)
members = [r for r in six.itervalues(stack)]
expected = sorted(members, key=lambda r: (r.created_time, r.name))
actual = grouputils.get_members(group)
self.assertEqual(expected, actual)
# refids
actual_ids = grouputils.get_member_refids(group)
self.assertEqual(['ID-r0', 'ID-r1'], actual_ids)
def test_group_with_failed_members(self):
group = mock.Mock()
t = template_format.parse(nested_stack)
stack = utils.parse_stack(t)
self.patchobject(group, 'nested', return_value=stack)
# Just failed for whatever reason
rsrc_err = stack.resources['r0']
rsrc_err.status = rsrc_err.FAILED
rsrc_ok = stack.resources['r1']
self.assertEqual([rsrc_ok], grouputils.get_members(group))
self.assertEqual(['ID-r1'], grouputils.get_member_refids(group))
class GroupInspectorTest(common.HeatTestCase):
resources = [
{
'updated_time': '2018-01-01T12:00',
'creation_time': '2018-01-01T02:00',
'resource_name': 'A',
'physical_resource_id': 'a',
'resource_action': 'UPDATE',
'resource_status': 'COMPLETE',
'resource_status_reason': 'resource changed',
'resource_type': 'OS::Heat::Test',
'resource_id': 'aaaaaaaa',
'stack_identity': 'bar',
'stack_name': 'nested_test',
'required_by': [],
'parent_resource': 'stack_resource',
},
{
'updated_time': '2018-01-01T10:00',
'creation_time': '2018-01-01T03:00',
'resource_name': 'E',
'physical_resource_id': 'e',
'resource_action': 'UPDATE',
'resource_status': 'FAILED',
'resource_status_reason': 'reasons',
'resource_type': 'OS::Heat::Test',
'resource_id': 'eeeeeeee',
'stack_identity': 'bar',
'stack_name': 'nested_test',
'required_by': [],
'parent_resource': 'stack_resource',
},
{
'updated_time': '2018-01-01T11:00',
'creation_time': '2018-01-01T03:00',
'resource_name': 'B',
'physical_resource_id': 'b',
'resource_action': 'UPDATE',
'resource_status': 'FAILED',
'resource_status_reason': 'reasons',
'resource_type': 'OS::Heat::Test',
'resource_id': 'bbbbbbbb',
'stack_identity': 'bar',
'stack_name': 'nested_test',
'required_by': [],
'parent_resource': 'stack_resource',
},
{
'updated_time': '2018-01-01T13:00',
'creation_time': '2018-01-01T01:00',
'resource_name': 'C',
'physical_resource_id': 'c',
'resource_action': 'UPDATE',
'resource_status': 'COMPLETE',
'resource_status_reason': 'resource changed',
'resource_type': 'OS::Heat::Test',
'resource_id': 'cccccccc',
'stack_identity': 'bar',
'stack_name': 'nested_test',
'required_by': [],
'parent_resource': 'stack_resource',
},
{
'updated_time': '2018-01-01T04:00',
'creation_time': '2018-01-01T04:00',
'resource_name': 'F',
'physical_resource_id': 'f',
'resource_action': 'CREATE',
'resource_status': 'COMPLETE',
'resource_status_reason': 'resource changed',
'resource_type': 'OS::Heat::Test',
'resource_id': 'ffffffff',
'stack_identity': 'bar',
'stack_name': 'nested_test',
'required_by': [],
'parent_resource': 'stack_resource',
},
{
'updated_time': '2018-01-01T04:00',
'creation_time': '2018-01-01T04:00',
'resource_name': 'D',
'physical_resource_id': 'd',
'resource_action': 'CREATE',
'resource_status': 'COMPLETE',
'resource_status_reason': 'resource changed',
'resource_type': 'OS::Heat::Test',
'resource_id': 'dddddddd',
'stack_identity': 'bar',
'stack_name': 'nested_test',
'required_by': [],
'parent_resource': 'stack_resource',
},
]
template = {
'heat_template_version': 'newton',
'resources': {
'A': {
'type': 'OS::Heat::TestResource',
},
},
}
def setUp(self):
super(GroupInspectorTest, self).setUp()
self.ctx = mock.Mock()
self.rpc_client = mock.Mock(spec=rpc_client.EngineClient)
self.identity = identifier.HeatIdentifier('foo', 'nested_test', 'bar')
self.list_rsrcs = self.rpc_client.list_stack_resources
self.get_tmpl = self.rpc_client.get_template
self.insp = grouputils.GroupInspector(self.ctx, self.rpc_client,
self.identity)
def test_no_identity(self):
self.insp = grouputils.GroupInspector(self.ctx, self.rpc_client, None)
self.assertEqual(0, self.insp.size(include_failed=True))
self.assertEqual([], list(self.insp.member_names(include_failed=True)))
self.assertIsNone(self.insp.template())
self.list_rsrcs.assert_not_called()
self.get_tmpl.assert_not_called()
def test_size_include_failed(self):
self.list_rsrcs.return_value = self.resources
self.assertEqual(6, self.insp.size(include_failed=True))
self.list_rsrcs.assert_called_once_with(self.ctx, dict(self.identity))
def test_size_exclude_failed(self):
self.list_rsrcs.return_value = self.resources
self.assertEqual(4, self.insp.size(include_failed=False))
self.list_rsrcs.assert_called_once_with(self.ctx, dict(self.identity))
def test_member_names_include_failed(self):
self.list_rsrcs.return_value = self.resources
self.assertEqual(['B', 'E', 'C', 'A', 'D', 'F'],
list(self.insp.member_names(include_failed=True)))
self.list_rsrcs.assert_called_once_with(self.ctx, dict(self.identity))
def test_member_names_exclude_failed(self):
self.list_rsrcs.return_value = self.resources
self.assertEqual(['C', 'A', 'D', 'F'],
list(self.insp.member_names(include_failed=False)))
self.list_rsrcs.assert_called_once_with(self.ctx, dict(self.identity))
def test_list_rsrc_caching(self):
self.list_rsrcs.return_value = self.resources
self.insp.size(include_failed=False)
list(self.insp.member_names(include_failed=True))
self.insp.size(include_failed=True)
list(self.insp.member_names(include_failed=False))
self.list_rsrcs.assert_called_once_with(self.ctx, dict(self.identity))
self.get_tmpl.assert_not_called()
def test_get_template(self):
self.get_tmpl.return_value = self.template
tmpl = self.insp.template()
self.assertEqual(self.template, tmpl.t)
self.get_tmpl.assert_called_once_with(self.ctx, dict(self.identity))
def test_get_tmpl_caching(self):
self.get_tmpl.return_value = self.template
self.insp.template()
self.insp.template()
self.get_tmpl.assert_called_once_with(self.ctx, dict(self.identity))
self.list_rsrcs.assert_not_called()