# Note we disable rollback for nested stacks, since they
# should be rolled back by the parent stack on failure
- self._nested = parser.Stack(self.context,
- self.physical_resource_name(),
- template,
- environment.Environment(user_params),
- timeout_mins=timeout_mins,
- disable_rollback=True,
- parent_resource=self)
-
+ nested = parser.Stack(self.context,
+ self.physical_resource_name(),
+ template,
+ environment.Environment(user_params),
+ timeout_mins=timeout_mins,
+ disable_rollback=True,
+ parent_resource=self)
+ nested.validate()
+ self._nested = nested
nested_id = self._nested.store(self.stack)
self.resource_id_set(nested_id)
timeout_mins=timeout_mins,
disable_rollback=True,
parent_resource=self)
+ stack.validate()
return self._nested.update(stack)
def delete_nested(self):
self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state)
return rsrc
- def _stub_create(self, num):
+ def _stub_validate(self):
+ self.m.StubOutWithMock(parser.Stack, 'validate')
+ parser.Stack.validate().MultipleTimes()
+ def _stub_create(self, num):
+ self._stub_validate()
self.m.StubOutWithMock(instance.Instance, 'handle_create')
self.m.StubOutWithMock(instance.Instance, 'check_create_complete')
cookie = object()
t = template_format.parse(as_template)
stack = utils.parse_stack(t, params=self.params)
+ self._stub_validate()
self.m.StubOutWithMock(instance.Instance, 'handle_create')
self.m.StubOutWithMock(instance.Instance, 'check_create_complete')
instance.Instance.handle_create().AndRaise(Exception)
# reduce to 1
self._stub_lb_reload(1)
+ self._stub_validate()
self._stub_meta_expected(now, 'ChangeInCapacity : -2')
self.m.ReplayAll()
rsrc.adjust(-2)
# set to 2
self._stub_lb_reload(2)
+ self._stub_validate()
self._stub_meta_expected(now, 'ExactCapacity : 2')
self.m.ReplayAll()
rsrc.adjust(2, 'ExactCapacity')
self.m.StubOutWithMock(instance.Instance, 'handle_create')
instance.Instance.handle_create().AndRaise(Exception)
self._stub_lb_reload(1, unset=False, nochange=True)
+ self._stub_validate()
self.m.ReplayAll()
rsrc.adjust(1)
# reduce by 50%
self._stub_lb_reload(1)
self._stub_meta_expected(now, 'PercentChangeInCapacity : -50')
+ self._stub_validate()
self.m.ReplayAll()
rsrc.adjust(-50, 'PercentChangeInCapacity')
self.assertEqual(['WebServerGroup-0'],
# reduce by 50%
self._stub_lb_reload(1)
+ self._stub_validate()
self._stub_meta_expected(now, 'PercentChangeInCapacity : -50')
self.m.ReplayAll()
rsrc.adjust(-50, 'PercentChangeInCapacity')
# reduce by 50%
self._stub_lb_reload(1)
+ self._stub_validate()
self._stub_meta_expected(now, 'PercentChangeInCapacity : -50')
self.m.ReplayAll()
rsrc.adjust(-50, 'PercentChangeInCapacity')
# reduce by 50%
self._stub_lb_reload(1)
self._stub_meta_expected(now, 'PercentChangeInCapacity : -50')
+ self._stub_validate()
self.m.ReplayAll()
rsrc.adjust(-50, 'PercentChangeInCapacity')
self.assertEqual(['WebServerGroup-0'],
# Scale down one
self._stub_lb_reload(1)
+ self._stub_validate()
self._stub_meta_expected(now, 'ChangeInCapacity : -1', 2)
self.m.StubOutWithMock(asc.ScalingPolicy, 'keystone')
from heat.engine import resource
from heat.engine import resources
from heat.engine import scheduler
+from heat.engine import parser
from heat.tests.common import HeatTestCase
from heat.tests import utils
:param instance_class: The resource class to expect to be created
instead of instance.Instance.
"""
+ self.m.StubOutWithMock(parser.Stack, 'validate')
+ parser.Stack.validate()
self.m.StubOutWithMock(instance_class, 'handle_create')
self.m.StubOutWithMock(instance_class, 'check_create_complete')
cookie = object()
+
for x in range(num):
instance_class.handle_create().AndReturn(cookie)
instance_class.check_create_complete(cookie).AndReturn(False)
self.m.StubOutWithMock(instance.Instance, 'handle_create')
not_found = exception.ImageNotFound(image_name='bla')
instance.Instance.handle_create().AndRaise(not_found)
+ self.m.StubOutWithMock(parser.Stack, 'validate')
+ parser.Stack.validate()
self.m.ReplayAll()
from heat.tests import generic_resource as generic_rsrc
from heat.tests import utils
+
ws_res_snippet = {"Type": "some_magic_type",
"metadata": {
"key": "value",
"some": "more stuff"}}
-wp_template = '''
+param_template = '''
{
- "AWSTemplateFormatVersion" : "2010-09-09",
- "Description" : "WordPress",
"Parameters" : {
"KeyName" : {
"Description" : "KeyName",
},
"Resources" : {
"WebServer": {
- "Type": "AWS::EC2::Instance",
- "metadata": {"Fn::ResourceFacade": "Metadata"},
- "Properties": {
- "ImageId" : "F17-x86_64-gold",
- "InstanceType" : "m1.large",
- "KeyName" : "test",
- "UserData" : "wordpress"
- }
+ "Type": "GenericResource",
+ "Properties": {}
}
}
}
'''
-generic_template = '''
+simple_template = '''
{
- "AWSTemplateFormatVersion" : "2010-09-09",
- "Description" : "WordPress",
"Parameters" : {},
"Resources" : {
"WebServer": {
self.parent_resource = MyStackResource('test',
ws_res_snippet,
self.parent_stack)
- self.templ = template_format.parse(wp_template)
- self.generic_template = template_format.parse(generic_template)
+ self.templ = template_format.parse(param_template)
+ self.simple_template = template_format.parse(simple_template)
@utils.stack_delete_after
def test_create_with_template_ok(self):
self.assertEqual(self.templ, self.stack.t.t)
self.assertEqual(self.stack.id, self.parent_resource.resource_id)
+ @utils.stack_delete_after
+ def test_create_with_template_validates(self):
+ """
+ Creating a stack with a template validates the created stack, so that
+ an invalid template will cause an error to be raised.
+ """
+ # Make a parameter key with the same name as the resource to cause a
+ # simple validation error
+ template = self.simple_template.copy()
+ template['Parameters']['WebServer'] = {'Type': 'String'}
+ self.assertRaises(
+ exception.StackValidationFailed,
+ self.parent_resource.create_with_template,
+ template, {'WebServer': 'foo'})
+
+ @utils.stack_delete_after
+ def test_update_with_template_validates(self):
+ """Updating a stack with a template validates the created stack."""
+ create_result = self.parent_resource.create_with_template(
+ self.simple_template, {})
+ while not create_result.step():
+ pass
+
+ template = self.simple_template.copy()
+ template['Parameters']['WebServer'] = {'Type': 'String'}
+ self.assertRaises(
+ exception.StackValidationFailed,
+ self.parent_resource.update_with_template,
+ template, {'WebServer': 'foo'})
+
@utils.stack_delete_after
def test_update_with_template_ok(self):
"""
given template and user parameters.
"""
create_result = self.parent_resource.create_with_template(
- self.generic_template, {})
+ self.simple_template, {})
while not create_result.step():
pass
self.stack = self.parent_resource.nested()
- new_templ = self.generic_template.copy()
+ new_templ = self.simple_template.copy()
inst_snippet = new_templ["Resources"]["WebServer"].copy()
new_templ["Resources"]["WebServer2"] = inst_snippet
update_result = self.parent_resource.update_with_template(