Convert parser tests that need nested stacks to unit tests
Part of blueprint decouple-nested Change-Id: Id64d88104ac11601beac95cf5792f814cad388c8
This commit is contained in:
@@ -27,7 +27,6 @@ from heat.common import context
|
||||
from heat.common import exception
|
||||
from heat.common import heat_keystoneclient as hkc
|
||||
from heat.common import template_format
|
||||
from heat.common import urlfetch
|
||||
import heat.db.api as db_api
|
||||
from heat.engine.cfn import functions as cfn_funcs
|
||||
from heat.engine.cfn import template as cfn_t
|
||||
@@ -1047,75 +1046,71 @@ class StackTest(common.HeatTestCase):
|
||||
status_reason='blarg')
|
||||
self.assertEqual(1, stack.total_resources())
|
||||
|
||||
def _setup_nested(self, name):
|
||||
nested_tpl = ('{"HeatTemplateFormatVersion" : "2012-12-12",'
|
||||
'"Resources":{'
|
||||
'"A": {"Type": "GenericResourceType"},'
|
||||
'"B": {"Type": "GenericResourceType"}}}')
|
||||
tpl = {'HeatTemplateFormatVersion': "2012-12-12",
|
||||
'Resources':
|
||||
{'A': {'Type': 'AWS::CloudFormation::Stack',
|
||||
'Properties':
|
||||
{'TemplateURL': 'http://server.test/nested.json'}},
|
||||
'B': {'Type': 'GenericResourceType'}}}
|
||||
self.m.StubOutWithMock(urlfetch, 'get')
|
||||
urlfetch.get('http://server.test/nested.json').AndReturn(nested_tpl)
|
||||
self.m.ReplayAll()
|
||||
self.stack = parser.Stack(self.ctx, 'test_stack', parser.Template(tpl),
|
||||
status_reason=name)
|
||||
self.stack.store()
|
||||
self.stack.create()
|
||||
|
||||
def test_total_resources_nested(self):
|
||||
self._setup_nested('zyzzyx')
|
||||
self.assertEqual(4, self.stack.total_resources())
|
||||
self.assertIsNotNone(self.stack['A'].nested())
|
||||
self.assertEqual(
|
||||
2, self.stack['A'].nested().total_resources())
|
||||
self.assertEqual(
|
||||
4,
|
||||
self.stack['A'].nested().root_stack.total_resources())
|
||||
tpl = {'HeatTemplateFormatVersion': '2012-12-12',
|
||||
'Resources':
|
||||
{'A': {'Type': 'GenericResourceType'}}}
|
||||
stack = parser.Stack(self.ctx, 'test_stack', parser.Template(tpl),
|
||||
status_reason='blarg')
|
||||
|
||||
stack['A'].nested = mock.Mock()
|
||||
stack['A'].nested.return_value.total_resources.return_value = 3
|
||||
self.assertEqual(4, stack.total_resources())
|
||||
|
||||
def test_iter_resources(self):
|
||||
self._setup_nested('iter_resources')
|
||||
nested_stack = self.stack['A'].nested()
|
||||
resource_generator = self.stack.iter_resources()
|
||||
tpl = {'HeatTemplateFormatVersion': '2012-12-12',
|
||||
'Resources':
|
||||
{'A': {'Type': 'GenericResourceType'},
|
||||
'B': {'Type': 'GenericResourceType'}}}
|
||||
stack = parser.Stack(self.ctx, 'test_stack', parser.Template(tpl),
|
||||
status_reason='blarg')
|
||||
|
||||
def get_more(nested_depth=0):
|
||||
yield 'X'
|
||||
yield 'Y'
|
||||
yield 'Z'
|
||||
|
||||
stack['A'].nested = mock.MagicMock()
|
||||
stack['A'].nested.return_value.iter_resources.side_effect = get_more
|
||||
|
||||
resource_generator = stack.iter_resources()
|
||||
self.assertIsNot(resource_generator, list)
|
||||
|
||||
first_level_resources = list(resource_generator)
|
||||
self.assertEqual(2, len(first_level_resources))
|
||||
self.assertIn(self.stack['A'], first_level_resources)
|
||||
self.assertIn(self.stack['B'], first_level_resources)
|
||||
all_resources = list(stack.iter_resources(1))
|
||||
self.assertEqual(5, len(all_resources))
|
||||
|
||||
all_resources = list(self.stack.iter_resources(1))
|
||||
self.assertIn(self.stack['A'], first_level_resources)
|
||||
self.assertIn(self.stack['B'], first_level_resources)
|
||||
self.assertIn(nested_stack['A'], all_resources)
|
||||
self.assertIn(nested_stack['B'], all_resources)
|
||||
def test_root_stack_no_parent(self):
|
||||
tpl = {'HeatTemplateFormatVersion': '2012-12-12',
|
||||
'Resources':
|
||||
{'A': {'Type': 'GenericResourceType'}}}
|
||||
stack = parser.Stack(self.ctx, 'test_stack', parser.Template(tpl),
|
||||
status_reason='blarg')
|
||||
|
||||
def test_root_stack(self):
|
||||
self._setup_nested('toor')
|
||||
self.assertEqual(self.stack, self.stack.root_stack)
|
||||
self.assertIsNotNone(self.stack['A'].nested())
|
||||
self.assertEqual(
|
||||
self.stack, self.stack['A'].nested().root_stack)
|
||||
self.assertEqual(stack, stack.root_stack)
|
||||
|
||||
def test_nested_stack_abandon(self):
|
||||
self._setup_nested('nestedstack')
|
||||
ret = self.stack.prepare_abandon()
|
||||
self.assertIsNotNone(self.stack['A'].nested())
|
||||
self.assertEqual(
|
||||
self.stack, self.stack['A'].nested().root_stack)
|
||||
def test_root_stack_parent_no_stack(self):
|
||||
tpl = {'HeatTemplateFormatVersion': '2012-12-12',
|
||||
'Resources':
|
||||
{'A': {'Type': 'GenericResourceType'}}}
|
||||
stack = parser.Stack(self.ctx, 'test_stack', parser.Template(tpl),
|
||||
status_reason='blarg')
|
||||
|
||||
keys = ['name', 'id', 'action', 'status', 'template', 'resources',
|
||||
'project_id', 'stack_user_project_id', 'environment']
|
||||
stack.parent_resource = mock.Mock()
|
||||
stack.parent_resource.stack = None
|
||||
self.assertEqual(stack, stack.root_stack)
|
||||
|
||||
self.assertEqual(len(keys), len(ret))
|
||||
nested_stack_data = ret['resources']['A']
|
||||
self.assertEqual(len(keys), len(nested_stack_data))
|
||||
for key in keys:
|
||||
self.assertIn(key, ret)
|
||||
self.assertIn(key, nested_stack_data)
|
||||
def test_root_stack_with_parent(self):
|
||||
tpl = {'HeatTemplateFormatVersion': '2012-12-12',
|
||||
'Resources':
|
||||
{'A': {'Type': 'GenericResourceType'}}}
|
||||
stack = parser.Stack(self.ctx, 'test_stack', parser.Template(tpl),
|
||||
status_reason='blarg')
|
||||
|
||||
stack.parent_resource = mock.Mock()
|
||||
stack.parent_resource.stack.root_stack = 'test value'
|
||||
self.assertEqual('test value', stack.root_stack)
|
||||
|
||||
def test_load_parent_resource(self):
|
||||
self.stack = parser.Stack(self.ctx, 'load_parent_resource',
|
||||
@@ -1851,12 +1846,17 @@ class StackTest(common.HeatTestCase):
|
||||
self.m.VerifyAll()
|
||||
|
||||
def _get_stack_to_check(self, name):
|
||||
tpl = {"HeatTemplateFormatVersion": "2012-12-12",
|
||||
"Resources": {
|
||||
"A": {"Type": "GenericResourceType"},
|
||||
"B": {"Type": "GenericResourceType"}}}
|
||||
self.stack = parser.Stack(self.ctx, name, parser.Template(tpl),
|
||||
status_reason=name)
|
||||
self.stack.store()
|
||||
|
||||
def _mock_check(res):
|
||||
res.handle_check = mock.Mock()
|
||||
if hasattr(res, 'nested'):
|
||||
[_mock_check(r) for r in res.nested().resources.values()]
|
||||
|
||||
self._setup_nested(name)
|
||||
[_mock_check(res) for res in self.stack.resources.values()]
|
||||
return self.stack
|
||||
|
||||
@@ -1870,18 +1870,6 @@ class StackTest(common.HeatTestCase):
|
||||
for res in stack.resources.values()]
|
||||
self.assertNotIn('not fully supported', stack.status_reason)
|
||||
|
||||
def test_check_nested_stack(self):
|
||||
def _mock_check(res):
|
||||
res.handle_check = mock.Mock()
|
||||
|
||||
self._setup_nested('check-nested-stack')
|
||||
nested = self.stack['A'].nested()
|
||||
[_mock_check(res) for res in nested.resources.values()]
|
||||
self.stack.check()
|
||||
|
||||
[self.assertTrue(res.handle_check.called)
|
||||
for res in nested.resources.values()]
|
||||
|
||||
def test_check_not_supported(self):
|
||||
stack = self._get_stack_to_check('check-not-supported')
|
||||
del stack['B'].handle_check
|
||||
|
||||
@@ -189,6 +189,14 @@ class StackResourceTest(common.HeatTestCase):
|
||||
preview = self.parent_resource.preview()
|
||||
self.assertIsInstance(preview, stack_resource.StackResource)
|
||||
|
||||
def test_nested_stack_abandon(self):
|
||||
nest = mock.MagicMock()
|
||||
self.parent_resource.nested = nest
|
||||
nest.return_value.prepare_abandon.return_value = {'X': 'Y'}
|
||||
ret = self.parent_resource.prepare_abandon()
|
||||
nest.return_value.prepare_abandon.assert_called_once_with()
|
||||
self.assertEqual({'X': 'Y'}, ret)
|
||||
|
||||
def test_implementation_signature(self):
|
||||
self.parent_resource.child_template = mock.Mock(
|
||||
return_value=self.simple_template)
|
||||
|
||||
@@ -420,3 +420,56 @@ Outputs:
|
||||
self.assert_resource_is_a_stack(stack_identifier, 'the_nested')
|
||||
stack = self.client.stacks.get(stack_identifier)
|
||||
self.assertEqual('goopie', self._stack_output(stack, 'value'))
|
||||
|
||||
|
||||
class TemplateResourceCheckTest(test.HeatIntegrationTest):
|
||||
"""Prove that we can do template resource check."""
|
||||
|
||||
main_template = '''
|
||||
HeatTemplateFormatVersion: '2012-12-12'
|
||||
Resources:
|
||||
the_nested:
|
||||
Type: the.yaml
|
||||
Properties:
|
||||
one: my_name
|
||||
Outputs:
|
||||
identifier:
|
||||
Value: {Ref: the_nested}
|
||||
value:
|
||||
Value: {'Fn::GetAtt': [the_nested, the_str]}
|
||||
'''
|
||||
|
||||
nested_templ = '''
|
||||
HeatTemplateFormatVersion: '2012-12-12'
|
||||
Parameters:
|
||||
one:
|
||||
Default: foo
|
||||
Type: String
|
||||
Resources:
|
||||
RealRandom:
|
||||
Type: OS::Heat::RandomString
|
||||
Properties:
|
||||
salt: {Ref: one}
|
||||
Outputs:
|
||||
the_str:
|
||||
Value: {'Fn::GetAtt': [RealRandom, value]}
|
||||
'''
|
||||
|
||||
def setUp(self):
|
||||
super(TemplateResourceCheckTest, self).setUp()
|
||||
self.client = self.orchestration_client
|
||||
|
||||
def test_check(self):
|
||||
stack_name = self._stack_rand_name()
|
||||
self.client.stacks.create(
|
||||
stack_name=stack_name,
|
||||
template=self.main_template,
|
||||
files={'the.yaml': self.nested_templ},
|
||||
disable_rollback=True,
|
||||
)
|
||||
stack = self.client.stacks.get(stack_name)
|
||||
stack_identifier = '%s/%s' % (stack_name, stack.id)
|
||||
self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')
|
||||
|
||||
self.client.actions.check(stack_id=stack_identifier)
|
||||
self._wait_for_stack_status(stack_identifier, 'CHECK_COMPLETE')
|
||||
|
||||
Reference in New Issue
Block a user