Add constraints to check whether image/keypair exists

Add constraints for "KeyName" and "ImageId" to check whether keypair/image
exists on "AWS::AutoScaling::LaunchConfiguration" resource.

Change-Id: I23dc126e621f3cfa7ca86b3a1c27dd949d3f5093
Closes-Bug: #1312564
This commit is contained in:
huangtianhua 2014-04-25 15:36:15 +08:00
parent a37e5e86a5
commit 7262d3a2c7
7 changed files with 152 additions and 85 deletions

View File

@ -771,7 +771,10 @@ class LaunchConfiguration(resource.Resource):
IMAGE_ID: properties.Schema( IMAGE_ID: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,
_('Glance image ID or name.'), _('Glance image ID or name.'),
required=True required=True,
constraints=[
constraints.CustomConstraint('glance.image')
]
), ),
INSTANCE_TYPE: properties.Schema( INSTANCE_TYPE: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,
@ -780,7 +783,10 @@ class LaunchConfiguration(resource.Resource):
), ),
KEY_NAME: properties.Schema( KEY_NAME: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,
_('Optional Nova keypair name.') _('Optional Nova keypair name.'),
constraints=[
constraints.CustomConstraint("nova.keypair")
]
), ),
USER_DATA: properties.Schema( USER_DATA: properties.Schema(
properties.Schema.STRING, properties.Schema.STRING,

View File

@ -25,9 +25,11 @@ import testscenarios
import testtools import testtools
from heat.common import messaging from heat.common import messaging
from heat.engine.clients.os import glance
from heat.engine.clients.os import keystone from heat.engine.clients.os import keystone
from heat.engine import environment from heat.engine import environment
from heat.engine import resources from heat.engine import resources
from heat.engine.resources import nova_keypair
from heat.engine import scheduler from heat.engine import scheduler
from heat.tests import fakes from heat.tests import fakes
from heat.tests import utils from heat.tests import utils
@ -126,3 +128,19 @@ class HeatTestCase(testscenarios.WithScenarios,
fkc = fake_client or fakes.FakeKeystoneClient(**kwargs) fkc = fake_client or fakes.FakeKeystoneClient(**kwargs)
client.return_value = fkc client.return_value = fkc
return fkc return fkc
def stub_KeypairConstraint_validate(self):
self.m.StubOutWithMock(nova_keypair.KeypairConstraint, 'validate')
nova_keypair.KeypairConstraint.validate(
mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(True)
def stub_ImageConstraint_validate(self, num=None):
self.m.StubOutWithMock(glance.ImageConstraint, 'validate')
if num is None:
glance.ImageConstraint.validate(
mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().\
AndReturn(True)
else:
for x in range(num):
glance.ImageConstraint.validate(
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(True)

View File

@ -22,7 +22,6 @@ import six
from heat.common import exception from heat.common import exception
from heat.common import short_id from heat.common import short_id
from heat.common import template_format from heat.common import template_format
from heat.engine.clients.os import glance
from heat.engine.notification import autoscaling as notification from heat.engine.notification import autoscaling as notification
from heat.engine import parser from heat.engine import parser
from heat.engine import resource from heat.engine import resource
@ -152,9 +151,7 @@ class AutoScalingTest(HeatTestCase):
def _stub_create(self, num, with_error=None): def _stub_create(self, num, with_error=None):
self.m.StubOutWithMock(instance.Instance, 'handle_create') self.m.StubOutWithMock(instance.Instance, 'handle_create')
self.m.StubOutWithMock(instance.Instance, 'check_create_complete') self.m.StubOutWithMock(instance.Instance, 'check_create_complete')
self.m.StubOutWithMock(glance.ImageConstraint, "validate") self.stub_ImageConstraint_validate()
glance.ImageConstraint.validate(
mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(True)
if with_error: if with_error:
instance.Instance.handle_create().AndRaise( instance.Instance.handle_create().AndRaise(
exception.Error(with_error)) exception.Error(with_error))
@ -166,12 +163,6 @@ class AutoScalingTest(HeatTestCase):
instance.Instance.check_create_complete( instance.Instance.check_create_complete(
cookie).MultipleTimes().AndReturn(True) cookie).MultipleTimes().AndReturn(True)
def _stub_image_validate(self, num=1):
self.m.StubOutWithMock(glance.ImageConstraint, "validate")
for x in range(num):
glance.ImageConstraint.validate(
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(True)
def _stub_delete(self, num): def _stub_delete(self, num):
self.m.StubOutWithMock(instance.Instance, 'handle_delete') self.m.StubOutWithMock(instance.Instance, 'handle_delete')
self.m.StubOutWithMock(instance.Instance, 'check_delete_complete') self.m.StubOutWithMock(instance.Instance, 'check_delete_complete')
@ -291,6 +282,7 @@ class AutoScalingTest(HeatTestCase):
properties['DesiredCapacity'] = '0' properties['DesiredCapacity'] = '0'
stack = utils.parse_stack(t, params=self.params) stack = utils.parse_stack(t, params=self.params)
self._stub_lb_reload(0) self._stub_lb_reload(0)
self.stub_ImageConstraint_validate()
self.m.ReplayAll() self.m.ReplayAll()
rsrc = self.create_scaling_group(t, stack, 'WebServerGroup') rsrc = self.create_scaling_group(t, stack, 'WebServerGroup')
self.assertIsNone(rsrc.FnGetAtt("InstanceList")) self.assertIsNone(rsrc.FnGetAtt("InstanceList"))
@ -554,9 +546,7 @@ class AutoScalingTest(HeatTestCase):
self.m.StubOutWithMock(instance.Instance, 'handle_create') self.m.StubOutWithMock(instance.Instance, 'handle_create')
self.m.StubOutWithMock(instance.Instance, 'check_create_complete') self.m.StubOutWithMock(instance.Instance, 'check_create_complete')
instance.Instance.handle_create().AndRaise(Exception) instance.Instance.handle_create().AndRaise(Exception)
self.m.StubOutWithMock(glance.ImageConstraint, "validate") self.stub_ImageConstraint_validate()
glance.ImageConstraint.validate(
mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(True)
self.m.ReplayAll() self.m.ReplayAll()
@ -883,7 +873,7 @@ class AutoScalingTest(HeatTestCase):
# reduce to 1 # reduce to 1
self._stub_lb_reload(1) self._stub_lb_reload(1)
self._stub_delete(2) self._stub_delete(2)
self._stub_image_validate() self.stub_ImageConstraint_validate(num=1)
self._stub_meta_expected(now, 'ChangeInCapacity : -2') self._stub_meta_expected(now, 'ChangeInCapacity : -2')
self._stub_scale_notification(adjust=-2, groupname=rsrc.FnGetRefId(), self._stub_scale_notification(adjust=-2, groupname=rsrc.FnGetRefId(),
start_capacity=3, end_capacity=1) start_capacity=3, end_capacity=1)
@ -904,7 +894,7 @@ class AutoScalingTest(HeatTestCase):
# set to 2 # set to 2
self._stub_lb_reload(2) self._stub_lb_reload(2)
self._stub_delete(1) self._stub_delete(1)
self._stub_image_validate(2) self.stub_ImageConstraint_validate(num=2)
self._stub_meta_expected(now, 'ExactCapacity : 2') self._stub_meta_expected(now, 'ExactCapacity : 2')
self._stub_scale_notification(adjust=2, groupname=rsrc.FnGetRefId(), self._stub_scale_notification(adjust=2, groupname=rsrc.FnGetRefId(),
adjust_type='ExactCapacity', adjust_type='ExactCapacity',
@ -970,7 +960,7 @@ class AutoScalingTest(HeatTestCase):
# lower below the min # lower below the min
self._stub_lb_reload(1) self._stub_lb_reload(1)
self._stub_delete(4) self._stub_delete(4)
self._stub_image_validate() self.stub_ImageConstraint_validate(num=1)
self._stub_meta_expected(now, 'ChangeInCapacity : -5') self._stub_meta_expected(now, 'ChangeInCapacity : -5')
self.m.ReplayAll() self.m.ReplayAll()
rsrc.adjust(-5) rsrc.adjust(-5)
@ -1005,7 +995,7 @@ class AutoScalingTest(HeatTestCase):
adjust = 'PercentChangeInCapacity : %d' % decrease adjust = 'PercentChangeInCapacity : %d' % decrease
self._stub_meta_expected(now, adjust) self._stub_meta_expected(now, adjust)
self._stub_delete(2 - lowest) self._stub_delete(2 - lowest)
self._stub_image_validate() self.stub_ImageConstraint_validate(num=1)
self.m.ReplayAll() self.m.ReplayAll()
rsrc.adjust(decrease, 'PercentChangeInCapacity') rsrc.adjust(decrease, 'PercentChangeInCapacity')
self.assertEqual(lowest, len(rsrc.get_instance_names())) self.assertEqual(lowest, len(rsrc.get_instance_names()))
@ -1050,7 +1040,7 @@ class AutoScalingTest(HeatTestCase):
# reduce by 50% # reduce by 50%
self._stub_lb_reload(1) self._stub_lb_reload(1)
self._stub_delete(1) self._stub_delete(1)
self._stub_image_validate() self.stub_ImageConstraint_validate(num=1)
self._stub_meta_expected(now, 'PercentChangeInCapacity : -50') self._stub_meta_expected(now, 'PercentChangeInCapacity : -50')
self.m.ReplayAll() self.m.ReplayAll()
rsrc.adjust(-50, 'PercentChangeInCapacity') rsrc.adjust(-50, 'PercentChangeInCapacity')
@ -1102,7 +1092,7 @@ class AutoScalingTest(HeatTestCase):
# reduce by 50% # reduce by 50%
self._stub_lb_reload(1) self._stub_lb_reload(1)
self._stub_delete(1) self._stub_delete(1)
self._stub_image_validate() self.stub_ImageConstraint_validate(num=1)
self._stub_meta_expected(now, 'PercentChangeInCapacity : -50') self._stub_meta_expected(now, 'PercentChangeInCapacity : -50')
self.m.ReplayAll() self.m.ReplayAll()
rsrc.adjust(-50, 'PercentChangeInCapacity') rsrc.adjust(-50, 'PercentChangeInCapacity')
@ -1157,7 +1147,7 @@ class AutoScalingTest(HeatTestCase):
self._stub_lb_reload(1) self._stub_lb_reload(1)
self._stub_meta_expected(now, 'PercentChangeInCapacity : -50') self._stub_meta_expected(now, 'PercentChangeInCapacity : -50')
self._stub_delete(1) self._stub_delete(1)
self._stub_image_validate() self.stub_ImageConstraint_validate(num=1)
self.m.ReplayAll() self.m.ReplayAll()
rsrc.adjust(-50, 'PercentChangeInCapacity') rsrc.adjust(-50, 'PercentChangeInCapacity')
self.assertEqual(1, len(rsrc.get_instance_names())) self.assertEqual(1, len(rsrc.get_instance_names()))
@ -1305,7 +1295,7 @@ class AutoScalingTest(HeatTestCase):
# Scale down one # Scale down one
self._stub_lb_reload(1) self._stub_lb_reload(1)
self._stub_delete(1) self._stub_delete(1)
self._stub_image_validate() self.stub_ImageConstraint_validate(num=1)
self._stub_meta_expected(now, 'ChangeInCapacity : -1', 2) self._stub_meta_expected(now, 'ChangeInCapacity : -1', 2)
self.m.ReplayAll() self.m.ReplayAll()
@ -1616,11 +1606,14 @@ class AutoScalingTest(HeatTestCase):
properties['VPCZoneIdentifier'] = ['xxxx', 'yyyy'] properties['VPCZoneIdentifier'] = ['xxxx', 'yyyy']
stack = utils.parse_stack(t, params=self.params) stack = utils.parse_stack(t, params=self.params)
self.stub_ImageConstraint_validate()
self.m.ReplayAll()
self.assertRaises(exception.NotSupported, self.assertRaises(exception.NotSupported,
self.create_scaling_group, t, self.create_scaling_group, t,
stack, 'WebServerGroup') stack, 'WebServerGroup')
self.m.VerifyAll()
def test_invalid_min_size(self): def test_invalid_min_size(self):
t = template_format.parse(as_template) t = template_format.parse(as_template)
properties = t['Resources']['WebServerGroup']['Properties'] properties = t['Resources']['WebServerGroup']['Properties']
@ -1629,12 +1622,16 @@ class AutoScalingTest(HeatTestCase):
stack = utils.parse_stack(t, params=self.params) stack = utils.parse_stack(t, params=self.params)
self.stub_ImageConstraint_validate()
self.m.ReplayAll()
e = self.assertRaises(exception.StackValidationFailed, e = self.assertRaises(exception.StackValidationFailed,
self.create_scaling_group, t, self.create_scaling_group, t,
stack, 'WebServerGroup') stack, 'WebServerGroup')
expected_msg = "The size of AutoScalingGroup can not be less than zero" expected_msg = "The size of AutoScalingGroup can not be less than zero"
self.assertEqual(expected_msg, six.text_type(e)) self.assertEqual(expected_msg, six.text_type(e))
self.m.VerifyAll()
def test_invalid_max_size(self): def test_invalid_max_size(self):
t = template_format.parse(as_template) t = template_format.parse(as_template)
@ -1644,12 +1641,16 @@ class AutoScalingTest(HeatTestCase):
stack = utils.parse_stack(t, params=self.params) stack = utils.parse_stack(t, params=self.params)
self.stub_ImageConstraint_validate()
self.m.ReplayAll()
e = self.assertRaises(exception.StackValidationFailed, e = self.assertRaises(exception.StackValidationFailed,
self.create_scaling_group, t, self.create_scaling_group, t,
stack, 'WebServerGroup') stack, 'WebServerGroup')
expected_msg = "MinSize can not be greater than MaxSize" expected_msg = "MinSize can not be greater than MaxSize"
self.assertEqual(expected_msg, six.text_type(e)) self.assertEqual(expected_msg, six.text_type(e))
self.m.VerifyAll()
def test_invalid_desiredcapacity(self): def test_invalid_desiredcapacity(self):
t = template_format.parse(as_template) t = template_format.parse(as_template)
@ -1659,13 +1660,16 @@ class AutoScalingTest(HeatTestCase):
properties['DesiredCapacity'] = '4' properties['DesiredCapacity'] = '4'
stack = utils.parse_stack(t, params=self.params) stack = utils.parse_stack(t, params=self.params)
self.stub_ImageConstraint_validate()
self.m.ReplayAll()
e = self.assertRaises(exception.StackValidationFailed, e = self.assertRaises(exception.StackValidationFailed,
self.create_scaling_group, t, self.create_scaling_group, t,
stack, 'WebServerGroup') stack, 'WebServerGroup')
expected_msg = "DesiredCapacity must be between MinSize and MaxSize" expected_msg = "DesiredCapacity must be between MinSize and MaxSize"
self.assertEqual(expected_msg, six.text_type(e)) self.assertEqual(expected_msg, six.text_type(e))
self.m.VerifyAll()
def test_invalid_desiredcapacity_zero(self): def test_invalid_desiredcapacity_zero(self):
t = template_format.parse(as_template) t = template_format.parse(as_template)
@ -1675,13 +1679,16 @@ class AutoScalingTest(HeatTestCase):
properties['DesiredCapacity'] = '0' properties['DesiredCapacity'] = '0'
stack = utils.parse_stack(t, params=self.params) stack = utils.parse_stack(t, params=self.params)
self.stub_ImageConstraint_validate()
self.m.ReplayAll()
e = self.assertRaises(exception.StackValidationFailed, e = self.assertRaises(exception.StackValidationFailed,
self.create_scaling_group, t, self.create_scaling_group, t,
stack, 'WebServerGroup') stack, 'WebServerGroup')
expected_msg = "DesiredCapacity must be between MinSize and MaxSize" expected_msg = "DesiredCapacity must be between MinSize and MaxSize"
self.assertEqual(expected_msg, six.text_type(e)) self.assertEqual(expected_msg, six.text_type(e))
self.m.VerifyAll()
def test_child_template_uses_min_size(self): def test_child_template_uses_min_size(self):
t = template_format.parse(as_template) t = template_format.parse(as_template)

View File

@ -20,7 +20,6 @@ from testtools.matchers import MatchesRegex
from heat.common import exception from heat.common import exception
from heat.common import template_format from heat.common import template_format
from heat.engine.clients.os import glance
from heat.engine.clients.os import nova from heat.engine.clients.os import nova
from heat.engine import function from heat.engine import function
from heat.engine.notification import stack as notification from heat.engine.notification import stack as notification
@ -210,22 +209,6 @@ class AutoScalingGroupTest(HeatTestCase):
cfg.CONF.set_default('heat_waitcondition_server_url', cfg.CONF.set_default('heat_waitcondition_server_url',
'http://127.0.0.1:8000/v1/waitcondition') 'http://127.0.0.1:8000/v1/waitcondition')
def _mock_get_image_id_success(self, imageId_input, imageId,
update_image=None):
self.m.StubOutWithMock(glance.GlanceClientPlugin, 'get_image_id')
# If update_image is None (create case), validation for initial image
# imageId_input will be invoked multiple times (for each server).
# If update_image is set (update case), validation of the old property
# values and new property values will be done, but the order is not
# deterministic. Therefore, using mox.IgnoreArg() for the update case.
if update_image is None:
glance.GlanceClientPlugin.get_image_id(imageId_input).\
MultipleTimes().AndReturn(imageId)
else:
glance.GlanceClientPlugin.get_image_id(mox.IgnoreArg()).\
MultipleTimes().AndReturn(imageId)
def _stub_validate(self): def _stub_validate(self):
self.m.StubOutWithMock(parser.Stack, 'validate') self.m.StubOutWithMock(parser.Stack, 'validate')
parser.Stack.validate().MultipleTimes() parser.Stack.validate().MultipleTimes()
@ -333,13 +316,22 @@ class AutoScalingGroupTest(HeatTestCase):
def test_parse_without_update_policy(self): def test_parse_without_update_policy(self):
tmpl = template_format.parse(asg_tmpl_without_updt_policy) tmpl = template_format.parse(asg_tmpl_without_updt_policy)
stack = utils.parse_stack(tmpl) stack = utils.parse_stack(tmpl)
self.stub_ImageConstraint_validate()
self.stub_KeypairConstraint_validate()
self.m.ReplayAll()
stack.validate() stack.validate()
grp = stack['WebServerGroup'] grp = stack['WebServerGroup']
self.assertFalse(grp.update_policy['AutoScalingRollingUpdate']) self.assertFalse(grp.update_policy['AutoScalingRollingUpdate'])
self.m.VerifyAll()
def test_parse_with_update_policy(self): def test_parse_with_update_policy(self):
tmpl = template_format.parse(asg_tmpl_with_updt_policy) tmpl = template_format.parse(asg_tmpl_with_updt_policy)
stack = utils.parse_stack(tmpl) stack = utils.parse_stack(tmpl)
self.stub_ImageConstraint_validate()
self.stub_KeypairConstraint_validate()
self.m.ReplayAll()
stack.validate() stack.validate()
tmpl_grp = tmpl['Resources']['WebServerGroup'] tmpl_grp = tmpl['Resources']['WebServerGroup']
tmpl_policy = tmpl_grp['UpdatePolicy']['AutoScalingRollingUpdate'] tmpl_policy = tmpl_grp['UpdatePolicy']['AutoScalingRollingUpdate']
@ -353,10 +345,15 @@ class AutoScalingGroupTest(HeatTestCase):
self.assertEqual(1, int(policy['MinInstancesInService'])) self.assertEqual(1, int(policy['MinInstancesInService']))
self.assertEqual(tmpl_batch_sz, int(policy['MaxBatchSize'])) self.assertEqual(tmpl_batch_sz, int(policy['MaxBatchSize']))
self.assertEqual('PT1S', policy['PauseTime']) self.assertEqual('PT1S', policy['PauseTime'])
self.m.VerifyAll()
def test_parse_with_default_update_policy(self): def test_parse_with_default_update_policy(self):
tmpl = template_format.parse(asg_tmpl_with_default_updt_policy) tmpl = template_format.parse(asg_tmpl_with_default_updt_policy)
stack = utils.parse_stack(tmpl) stack = utils.parse_stack(tmpl)
self.stub_ImageConstraint_validate()
self.stub_KeypairConstraint_validate()
self.m.ReplayAll()
stack.validate() stack.validate()
grp = stack['WebServerGroup'] grp = stack['WebServerGroup']
self.assertTrue(grp.update_policy) self.assertTrue(grp.update_policy)
@ -367,6 +364,7 @@ class AutoScalingGroupTest(HeatTestCase):
self.assertEqual(0, int(policy['MinInstancesInService'])) self.assertEqual(0, int(policy['MinInstancesInService']))
self.assertEqual(1, int(policy['MaxBatchSize'])) self.assertEqual(1, int(policy['MaxBatchSize']))
self.assertEqual('PT0S', policy['PauseTime']) self.assertEqual('PT0S', policy['PauseTime'])
self.m.VerifyAll()
def test_parse_with_bad_update_policy(self): def test_parse_with_bad_update_policy(self):
tmpl = template_format.parse(asg_tmpl_with_bad_updt_policy) tmpl = template_format.parse(asg_tmpl_with_bad_updt_policy)
@ -440,14 +438,18 @@ class AutoScalingGroupTest(HeatTestCase):
tmpl = template_format.parse(init_template) tmpl = template_format.parse(init_template)
stack = utils.parse_stack(tmpl) stack = utils.parse_stack(tmpl)
self._mock_get_image_id_success('F20-x86_64-cfntools', self.stub_KeypairConstraint_validate()
'image_id') self.stub_ImageConstraint_validate()
self.m.ReplayAll()
stack.validate() stack.validate()
self.m.VerifyAll()
self.m.UnsetStubs()
# test stack create # test stack create
size = int(stack['WebServerGroup'].properties['MinSize']) size = int(stack['WebServerGroup'].properties['MinSize'])
self._stub_grp_create(size) self._stub_grp_create(size)
self.stub_ImageConstraint_validate()
self.m.ReplayAll() self.m.ReplayAll()
stack.create() stack.create()
self.m.VerifyAll() self.m.VerifyAll()
@ -502,11 +504,12 @@ class AutoScalingGroupTest(HeatTestCase):
num_deletes_expected_on_updt, num_deletes_expected_on_updt,
num_reloads_expected_on_updt) num_reloads_expected_on_updt)
self.stub_wallclock() self.stub_wallclock()
self._mock_get_image_id_success('F20-x86_64-cfntools', 'image_id', self.stub_ImageConstraint_validate()
update_image=update_image_id) self.stub_KeypairConstraint_validate()
self.m.ReplayAll()
stack.validate() stack.validate()
self.m.ReplayAll()
stack.update(updated_stack) stack.update(updated_stack)
self.m.VerifyAll() self.m.VerifyAll()
self.assertEqual(('UPDATE', 'COMPLETE'), stack.state) self.assertEqual(('UPDATE', 'COMPLETE'), stack.state)
@ -701,12 +704,18 @@ class AutoScalingGroupTest(HeatTestCase):
# setup stack from the initial template # setup stack from the initial template
tmpl = template_format.parse(asg_tmpl_with_updt_policy) tmpl = template_format.parse(asg_tmpl_with_updt_policy)
stack = utils.parse_stack(tmpl) stack = utils.parse_stack(tmpl)
self.stub_ImageConstraint_validate()
self.stub_KeypairConstraint_validate()
self.m.ReplayAll()
stack.validate() stack.validate()
self.m.VerifyAll()
self.m.UnsetStubs()
# test stack create # test stack create
size = int(stack['WebServerGroup'].properties['MinSize']) size = int(stack['WebServerGroup'].properties['MinSize'])
self._stub_grp_create(size) self._stub_grp_create(size)
self._mock_get_image_id_success('F20-x86_64-cfntools', 'image_id') self.stub_ImageConstraint_validate()
self.m.ReplayAll() self.m.ReplayAll()
stack.create() stack.create()
self.m.VerifyAll() self.m.VerifyAll()
@ -759,7 +768,7 @@ class AutoScalingGroupTest(HeatTestCase):
# test stack create # test stack create
size = int(stack['WebServerGroup'].properties['MinSize']) size = int(stack['WebServerGroup'].properties['MinSize'])
self._stub_grp_create(size) self._stub_grp_create(size)
self._mock_get_image_id_success('F20-x86_64-cfntools', 'image_id') self.stub_ImageConstraint_validate()
self.m.ReplayAll() self.m.ReplayAll()
stack.create() stack.create()
self.m.VerifyAll() self.m.VerifyAll()
@ -796,6 +805,8 @@ class AutoScalingGroupTest(HeatTestCase):
self._stub_grp_replace(num_creates_expected_on_updt=0, self._stub_grp_replace(num_creates_expected_on_updt=0,
num_deletes_expected_on_updt=0, num_deletes_expected_on_updt=0,
num_reloads_expected_on_updt=1) num_reloads_expected_on_updt=1)
self.stub_KeypairConstraint_validate()
self.stub_ImageConstraint_validate()
self.m.ReplayAll() self.m.ReplayAll()
stack.update(updated_stack) stack.update(updated_stack)
self.m.VerifyAll() self.m.VerifyAll()

View File

@ -13,16 +13,12 @@
import copy import copy
import mox
from heat.common import exception from heat.common import exception
from heat.common import template_format from heat.common import template_format
from heat.engine.clients.os import glance
from heat.engine import parser from heat.engine import parser
from heat.engine import resource from heat.engine import resource
from heat.engine import resources from heat.engine import resources
from heat.engine.resources import instance from heat.engine.resources import instance
from heat.engine.resources import nova_keypair
from heat.engine import rsrc_defn from heat.engine import rsrc_defn
from heat.engine import scheduler from heat.engine import scheduler
from heat.tests.common import HeatTestCase from heat.tests.common import HeatTestCase
@ -73,12 +69,8 @@ class InstanceGroupTest(HeatTestCase):
""" """
self.m.StubOutWithMock(parser.Stack, 'validate') self.m.StubOutWithMock(parser.Stack, 'validate')
parser.Stack.validate() parser.Stack.validate()
self.m.StubOutWithMock(nova_keypair.KeypairConstraint, 'validate') self.stub_KeypairConstraint_validate()
nova_keypair.KeypairConstraint.validate( self.stub_ImageConstraint_validate()
mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(True)
self.m.StubOutWithMock(glance.ImageConstraint, 'validate')
glance.ImageConstraint.validate(
mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(True)
self.m.StubOutWithMock(instance_class, 'handle_create') self.m.StubOutWithMock(instance_class, 'handle_create')
self.m.StubOutWithMock(instance_class, 'check_create_complete') self.m.StubOutWithMock(instance_class, 'check_create_complete')
@ -154,21 +146,25 @@ class InstanceGroupTest(HeatTestCase):
t = template_format.parse(ig_template) t = template_format.parse(ig_template)
stack = utils.parse_stack(t) stack = utils.parse_stack(t)
self.stub_ImageConstraint_validate()
self.stub_KeypairConstraint_validate()
self.m.ReplayAll()
self.create_resource(t, stack, 'JobServerConfig') self.create_resource(t, stack, 'JobServerConfig')
rsrc = stack['JobServerGroup'] rsrc = stack['JobServerGroup']
self.m.VerifyAll()
self.m.UnsetStubs()
self.m.StubOutWithMock(instance.Instance, 'handle_create') self.m.StubOutWithMock(instance.Instance, 'handle_create')
not_found = exception.ImageNotFound(image_name='bla') not_found = exception.ImageNotFound(image_name='bla')
instance.Instance.handle_create().AndRaise(not_found) instance.Instance.handle_create().AndRaise(not_found)
self.m.StubOutWithMock(parser.Stack, 'validate') self.m.StubOutWithMock(parser.Stack, 'validate')
parser.Stack.validate() parser.Stack.validate()
self.m.StubOutWithMock(nova_keypair.KeypairConstraint, 'validate')
nova_keypair.KeypairConstraint.validate( self.stub_KeypairConstraint_validate()
mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(True) self.stub_ImageConstraint_validate()
self.m.StubOutWithMock(glance.ImageConstraint, 'validate')
glance.ImageConstraint.validate(
mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(True)
self.m.ReplayAll() self.m.ReplayAll()
@ -228,12 +224,8 @@ class InstanceGroupTest(HeatTestCase):
self.m.StubOutWithMock(parser.Stack, 'validate') self.m.StubOutWithMock(parser.Stack, 'validate')
parser.Stack.validate() parser.Stack.validate()
self.m.StubOutWithMock(nova_keypair.KeypairConstraint, 'validate') self.stub_ImageConstraint_validate()
nova_keypair.KeypairConstraint.validate( self.stub_KeypairConstraint_validate()
mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(True)
self.m.StubOutWithMock(glance.ImageConstraint, 'validate')
glance.ImageConstraint.validate(
mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(True)
self.m.StubOutWithMock(instance.Instance, 'handle_create') self.m.StubOutWithMock(instance.Instance, 'handle_create')
instance.Instance.handle_create().AndRaise(Exception) instance.Instance.handle_create().AndRaise(Exception)
@ -275,12 +267,8 @@ class InstanceGroupTest(HeatTestCase):
self.m.StubOutWithMock(parser.Stack, 'validate') self.m.StubOutWithMock(parser.Stack, 'validate')
parser.Stack.validate() parser.Stack.validate()
self.m.StubOutWithMock(nova_keypair.KeypairConstraint, 'validate') self.stub_ImageConstraint_validate()
nova_keypair.KeypairConstraint.validate( self.stub_KeypairConstraint_validate()
mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(True)
self.m.StubOutWithMock(glance.ImageConstraint, 'validate')
glance.ImageConstraint.validate(
mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(True)
self.m.StubOutWithMock(instance.Instance, 'handle_create') self.m.StubOutWithMock(instance.Instance, 'handle_create')
instance.Instance.handle_create().AndRaise(Exception) instance.Instance.handle_create().AndRaise(Exception)

View File

@ -19,12 +19,10 @@ from testtools.matchers import MatchesRegex
from heat.common import exception from heat.common import exception
from heat.common import template_format from heat.common import template_format
from heat.engine.clients.os import glance
from heat.engine.clients.os import nova from heat.engine.clients.os import nova
from heat.engine import function from heat.engine import function
from heat.engine import parser from heat.engine import parser
from heat.engine.resources import instance from heat.engine.resources import instance
from heat.engine.resources import nova_keypair
from heat.tests.common import HeatTestCase from heat.tests.common import HeatTestCase
from heat.tests import utils from heat.tests import utils
from heat.tests.v1_1 import fakes from heat.tests.v1_1 import fakes
@ -166,12 +164,8 @@ class InstanceGroupTest(HeatTestCase):
def _stub_validate(self): def _stub_validate(self):
self.m.StubOutWithMock(parser.Stack, 'validate') self.m.StubOutWithMock(parser.Stack, 'validate')
parser.Stack.validate().MultipleTimes() parser.Stack.validate().MultipleTimes()
self.m.StubOutWithMock(nova_keypair.KeypairConstraint, 'validate') self.stub_ImageConstraint_validate()
nova_keypair.KeypairConstraint.validate( self.stub_KeypairConstraint_validate()
mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(True)
self.m.StubOutWithMock(glance.ImageConstraint, 'validate')
glance.ImageConstraint.validate(
mox.IgnoreArg(), mox.IgnoreArg()).MultipleTimes().AndReturn(True)
def _stub_grp_create(self, capacity): def _stub_grp_create(self, capacity):
""" """
@ -243,13 +237,22 @@ class InstanceGroupTest(HeatTestCase):
def test_parse_without_update_policy(self): def test_parse_without_update_policy(self):
tmpl = template_format.parse(ig_tmpl_without_updt_policy) tmpl = template_format.parse(ig_tmpl_without_updt_policy)
stack = utils.parse_stack(tmpl) stack = utils.parse_stack(tmpl)
self.stub_ImageConstraint_validate()
self.stub_KeypairConstraint_validate()
self.m.ReplayAll()
stack.validate() stack.validate()
grp = stack['JobServerGroup'] grp = stack['JobServerGroup']
self.assertFalse(grp.update_policy['RollingUpdate']) self.assertFalse(grp.update_policy['RollingUpdate'])
self.m.VerifyAll()
def test_parse_with_update_policy(self): def test_parse_with_update_policy(self):
tmpl = template_format.parse(ig_tmpl_with_updt_policy) tmpl = template_format.parse(ig_tmpl_with_updt_policy)
stack = utils.parse_stack(tmpl) stack = utils.parse_stack(tmpl)
self.stub_ImageConstraint_validate()
self.stub_KeypairConstraint_validate()
self.m.ReplayAll()
stack.validate() stack.validate()
grp = stack['JobServerGroup'] grp = stack['JobServerGroup']
self.assertTrue(grp.update_policy) self.assertTrue(grp.update_policy)
@ -261,9 +264,15 @@ class InstanceGroupTest(HeatTestCase):
self.assertEqual(2, int(policy['MaxBatchSize'])) self.assertEqual(2, int(policy['MaxBatchSize']))
self.assertEqual('PT1S', policy['PauseTime']) self.assertEqual('PT1S', policy['PauseTime'])
self.m.VerifyAll()
def test_parse_with_default_update_policy(self): def test_parse_with_default_update_policy(self):
tmpl = template_format.parse(ig_tmpl_with_default_updt_policy) tmpl = template_format.parse(ig_tmpl_with_default_updt_policy)
stack = utils.parse_stack(tmpl) stack = utils.parse_stack(tmpl)
self.stub_ImageConstraint_validate()
self.stub_KeypairConstraint_validate()
self.m.ReplayAll()
stack.validate() stack.validate()
grp = stack['JobServerGroup'] grp = stack['JobServerGroup']
self.assertTrue(grp.update_policy) self.assertTrue(grp.update_policy)
@ -275,6 +284,8 @@ class InstanceGroupTest(HeatTestCase):
self.assertEqual(1, int(policy['MaxBatchSize'])) self.assertEqual(1, int(policy['MaxBatchSize']))
self.assertEqual('PT0S', policy['PauseTime']) self.assertEqual('PT0S', policy['PauseTime'])
self.m.VerifyAll()
def test_parse_with_bad_update_policy(self): def test_parse_with_bad_update_policy(self):
tmpl = template_format.parse(ig_tmpl_with_bad_updt_policy) tmpl = template_format.parse(ig_tmpl_with_bad_updt_policy)
stack = utils.parse_stack(tmpl) stack = utils.parse_stack(tmpl)
@ -351,8 +362,15 @@ class InstanceGroupTest(HeatTestCase):
# setup stack from the initial template # setup stack from the initial template
tmpl = template_format.parse(init_template) tmpl = template_format.parse(init_template)
stack = utils.parse_stack(tmpl) stack = utils.parse_stack(tmpl)
self.stub_KeypairConstraint_validate()
self.stub_ImageConstraint_validate()
self.m.ReplayAll()
stack.validate() stack.validate()
self.m.VerifyAll()
self.m.UnsetStubs()
# test stack create # test stack create
size = int(stack['JobServerGroup'].properties['Size']) size = int(stack['JobServerGroup'].properties['Size'])
self._stub_grp_create(size) self._stub_grp_create(size)
@ -668,6 +686,10 @@ class InstanceGroupTest(HeatTestCase):
config['Properties']['ImageId'] = 'bar' config['Properties']['ImageId'] = 'bar'
updated_tmpl = template_format.parse(json.dumps(updt_template)) updated_tmpl = template_format.parse(json.dumps(updt_template))
updated_stack = utils.parse_stack(updated_tmpl) updated_stack = utils.parse_stack(updated_tmpl)
self.stub_KeypairConstraint_validate()
self.stub_ImageConstraint_validate()
self.m.ReplayAll()
stack.update(updated_stack) stack.update(updated_stack)
self.assertEqual(('UPDATE', 'FAILED'), stack.state) self.assertEqual(('UPDATE', 'FAILED'), stack.state)
@ -683,3 +705,5 @@ class InstanceGroupTest(HeatTestCase):
expected_error_message = ('The current UpdatePolicy will result ' expected_error_message = ('The current UpdatePolicy will result '
'in stack update timeout.') 'in stack update timeout.')
self.assertIn(expected_error_message, stack.status_reason) self.assertIn(expected_error_message, stack.status_reason)
self.m.VerifyAll()

View File

@ -204,7 +204,8 @@ class ServerTagsTest(HeatTestCase):
self.m.StubOutWithMock(self.fc.servers, 'set_meta') self.m.StubOutWithMock(self.fc.servers, 'set_meta')
self.fc.servers.set_meta(self.fc.servers.list()[1], self.fc.servers.set_meta(self.fc.servers.list()[1],
new_metadata).AndReturn(None) new_metadata).AndReturn(None)
self._mock_get_image_id_success('CentOS 5.2', 1) self.stub_ImageConstraint_validate()
self.stub_KeypairConstraint_validate()
self.m.ReplayAll() self.m.ReplayAll()
update_template = copy.deepcopy(instance.t) update_template = copy.deepcopy(instance.t)
update_template['Properties']['Tags'] = new_tags update_template['Properties']['Tags'] = new_tags
@ -224,6 +225,9 @@ class ServerTagsTest(HeatTestCase):
# create the launch configuration # create the launch configuration
conf = stack['Config'] conf = stack['Config']
self.stub_KeypairConstraint_validate()
self.stub_ImageConstraint_validate()
self.m.ReplayAll()
self.assertIsNone(conf.validate()) self.assertIsNone(conf.validate())
scheduler.TaskRunner(conf.create)() scheduler.TaskRunner(conf.create)()
self.assertEqual((conf.CREATE, conf.COMPLETE), conf.state) self.assertEqual((conf.CREATE, conf.COMPLETE), conf.state)
@ -232,6 +236,8 @@ class ServerTagsTest(HeatTestCase):
nova_tags['metering.groupname'] = utils.PhysName(stack.name, nova_tags['metering.groupname'] = utils.PhysName(stack.name,
group.name) group.name)
self.m.VerifyAll()
self.m.UnsetStubs()
self.m.StubOutWithMock(nova.NovaClientPlugin, '_create') self.m.StubOutWithMock(nova.NovaClientPlugin, '_create')
nova.NovaClientPlugin._create().AndReturn(self.fc) nova.NovaClientPlugin._create().AndReturn(self.fc)
@ -270,6 +276,10 @@ class ServerTagsTest(HeatTestCase):
# create the launch configuration # create the launch configuration
conf = stack['Config'] conf = stack['Config']
self.stub_ImageConstraint_validate()
self.stub_KeypairConstraint_validate()
self.m.ReplayAll()
self.assertIsNone(conf.validate()) self.assertIsNone(conf.validate())
scheduler.TaskRunner(conf.create)() scheduler.TaskRunner(conf.create)()
self.assertEqual((conf.CREATE, conf.COMPLETE), conf.state) self.assertEqual((conf.CREATE, conf.COMPLETE), conf.state)
@ -280,6 +290,9 @@ class ServerTagsTest(HeatTestCase):
nova_tags['metering.groupname'] = group_refid nova_tags['metering.groupname'] = group_refid
nova_tags['AutoScalingGroupName'] = group_refid nova_tags['AutoScalingGroupName'] = group_refid
self.m.VerifyAll()
self.m.UnsetStubs()
self.m.StubOutWithMock(group, '_cooldown_timestamp') self.m.StubOutWithMock(group, '_cooldown_timestamp')
group._cooldown_timestamp(mox.IgnoreArg()).AndReturn(None) group._cooldown_timestamp(mox.IgnoreArg()).AndReturn(None)