Rewrite AutoScalingGroup adjustment tests as unit tests
Change-Id: I1c752243ef981a19ff1572071f43e5eaebe3b0dc part of blueprint decouple-nested
This commit is contained in:
parent
90b8c3a69b
commit
e0a94ce2b2
@ -17,8 +17,6 @@ import six
|
||||
|
||||
from heat.common import exception
|
||||
from heat.common import template_format
|
||||
from heat.engine.resources import autoscaling as asc
|
||||
from heat.engine import rsrc_defn
|
||||
from heat.engine import scheduler
|
||||
from heat.tests.autoscaling import inline_templates
|
||||
from heat.tests import common
|
||||
@ -137,29 +135,106 @@ class TestAutoScalingGroupValidation(common.HeatTestCase):
|
||||
self.assertEqual(expected_msg, six.text_type(e))
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_child_template_uses_min_size(self):
|
||||
|
||||
class TestInitialGroupSize(common.HeatTestCase):
|
||||
scenarios = [
|
||||
('000', dict(mins=0, maxs=0, desired=0, expected=0)),
|
||||
('040', dict(mins=0, maxs=4, desired=0, expected=0)),
|
||||
('253', dict(mins=2, maxs=5, desired=3, expected=3)),
|
||||
('14n', dict(mins=1, maxs=4, desired=None, expected=1)),
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
super(TestInitialGroupSize, self).setUp()
|
||||
cfg.CONF.set_default('heat_waitcondition_server_url',
|
||||
'http://server.test:8000/v1/waitcondition')
|
||||
self.stub_keystoneclient()
|
||||
|
||||
def test_initial_size(self):
|
||||
t = template_format.parse(as_template)
|
||||
properties = t['Resources']['WebServerGroup']['Properties']
|
||||
properties['MinSize'] = self.mins
|
||||
properties['MaxSize'] = self.maxs
|
||||
properties['DesiredCapacity'] = self.desired
|
||||
stack = utils.parse_stack(t, params=inline_templates.as_params)
|
||||
group = stack['WebServerGroup']
|
||||
with mock.patch.object(group, '_create_template') as mock_cre_temp:
|
||||
group.child_template()
|
||||
mock_cre_temp.assert_called_once_with(self.expected)
|
||||
|
||||
|
||||
class TestGroupAdjust(common.HeatTestCase):
|
||||
def setUp(self):
|
||||
super(TestGroupAdjust, self).setUp()
|
||||
cfg.CONF.set_default('heat_waitcondition_server_url',
|
||||
'http://server.test:8000/v1/waitcondition')
|
||||
self.stub_keystoneclient()
|
||||
|
||||
t = template_format.parse(as_template)
|
||||
stack = utils.parse_stack(t, params=inline_templates.as_params)
|
||||
defn = rsrc_defn.ResourceDefinition(
|
||||
'asg', 'AWS::AutoScaling::AutoScalingGroup',
|
||||
{'MinSize': 2, 'MaxSize': 5, 'LaunchConfigurationName': 'foo'})
|
||||
rsrc = asc.AutoScalingGroup('asg', defn, stack)
|
||||
self.group = stack['WebServerGroup']
|
||||
self.assertIsNone(self.group.validate())
|
||||
|
||||
rsrc._create_template = mock.Mock(return_value='tpl')
|
||||
def test_scaling_policy_cooldown_toosoon(self):
|
||||
"""If _cooldown_inprogress() returns True don't progress."""
|
||||
|
||||
self.assertEqual('tpl', rsrc.child_template())
|
||||
rsrc._create_template.assert_called_once_with(2)
|
||||
dont_call = self.patchobject(self.group, 'get_instances')
|
||||
with mock.patch.object(self.group, '_cooldown_inprogress',
|
||||
return_value=True):
|
||||
self.group.adjust(1)
|
||||
self.assertEqual([], dont_call.call_args_list)
|
||||
|
||||
def test_child_template_uses_desired_capacity(self):
|
||||
t = template_format.parse(as_template)
|
||||
stack = utils.parse_stack(t, params=inline_templates.as_params)
|
||||
defn = rsrc_defn.ResourceDefinition(
|
||||
'asg', 'AWS::AutoScaling::AutoScalingGroup',
|
||||
{'MinSize': 2, 'MaxSize': 5, 'DesiredCapacity': 3,
|
||||
'LaunchConfigurationName': 'foo'})
|
||||
rsrc = asc.AutoScalingGroup('asg', defn, stack)
|
||||
def test_scaling_policy_cooldown_ok(self):
|
||||
self.patchobject(self.group, 'get_instances', return_value=[])
|
||||
resize = self.patchobject(self.group, 'resize')
|
||||
cd_stamp = self.patchobject(self.group, '_cooldown_timestamp')
|
||||
notify = self.patch('heat.engine.notification.autoscaling.send')
|
||||
self.patchobject(self.group, '_cooldown_inprogress',
|
||||
return_value=False)
|
||||
self.group.adjust(1)
|
||||
|
||||
rsrc._create_template = mock.Mock(return_value='tpl')
|
||||
expected_notifies = [
|
||||
mock.call(
|
||||
capacity=0, suffix='start', adjustment_type='ChangeInCapacity',
|
||||
groupname=u'WebServerGroup',
|
||||
message=u'Start resizing the group WebServerGroup',
|
||||
adjustment=1,
|
||||
stack=self.group.stack),
|
||||
mock.call(
|
||||
capacity=1, suffix='end',
|
||||
adjustment_type='ChangeInCapacity',
|
||||
groupname=u'WebServerGroup',
|
||||
message=u'End resizing the group WebServerGroup',
|
||||
adjustment=1,
|
||||
stack=self.group.stack)]
|
||||
|
||||
self.assertEqual('tpl', rsrc.child_template())
|
||||
rsrc._create_template.assert_called_once_with(3)
|
||||
self.assertEqual(expected_notifies, notify.call_args_list)
|
||||
resize.assert_called_once_with(1)
|
||||
cd_stamp.assert_called_once_with('ChangeInCapacity : 1')
|
||||
|
||||
def test_scaling_policy_resize_fail(self):
|
||||
self.patchobject(self.group, 'get_instances', return_value=[])
|
||||
self.patchobject(self.group, 'resize',
|
||||
side_effect=ValueError('test error'))
|
||||
notify = self.patch('heat.engine.notification.autoscaling.send')
|
||||
self.patchobject(self.group, '_cooldown_inprogress',
|
||||
return_value=False)
|
||||
self.assertRaises(ValueError, self.group.adjust, 1)
|
||||
|
||||
expected_notifies = [
|
||||
mock.call(
|
||||
capacity=0, suffix='start',
|
||||
adjustment_type='ChangeInCapacity',
|
||||
groupname=u'WebServerGroup',
|
||||
message=u'Start resizing the group WebServerGroup',
|
||||
adjustment=1,
|
||||
stack=self.group.stack),
|
||||
mock.call(
|
||||
capacity=0, suffix='error',
|
||||
adjustment_type='ChangeInCapacity',
|
||||
groupname=u'WebServerGroup',
|
||||
message=u'test error',
|
||||
adjustment=1,
|
||||
stack=self.group.stack)]
|
||||
|
||||
self.assertEqual(expected_notifies, notify.call_args_list)
|
||||
|
@ -248,61 +248,6 @@ class AutoScalingTest(common.HeatTestCase):
|
||||
for x in range(nmeta):
|
||||
resource.Resource.metadata_set(expected).AndReturn(None)
|
||||
|
||||
def test_scaling_delete_empty(self):
|
||||
t = template_format.parse(as_template)
|
||||
properties = t['Resources']['WebServerGroup']['Properties']
|
||||
properties['MinSize'] = '0'
|
||||
properties['MaxSize'] = '0'
|
||||
properties['DesiredCapacity'] = '0'
|
||||
stack = utils.parse_stack(t, params=self.params)
|
||||
self._stub_lb_reload(0)
|
||||
self.stub_ImageConstraint_validate()
|
||||
self.m.ReplayAll()
|
||||
rsrc = self.create_scaling_group(t, stack, 'WebServerGroup')
|
||||
self.assertIsNone(rsrc.FnGetAtt("InstanceList"))
|
||||
|
||||
rsrc.delete()
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_scaling_adjust_down_empty(self):
|
||||
t = template_format.parse(as_template)
|
||||
properties = t['Resources']['WebServerGroup']['Properties']
|
||||
properties['MinSize'] = '1'
|
||||
properties['MaxSize'] = '1'
|
||||
stack = utils.parse_stack(t, params=self.params)
|
||||
|
||||
self._stub_lb_reload(1)
|
||||
now = timeutils.utcnow()
|
||||
self._stub_meta_expected(now, 'ExactCapacity : 1')
|
||||
self._stub_create(1)
|
||||
self.m.ReplayAll()
|
||||
|
||||
rsrc = self.create_scaling_group(t, stack, 'WebServerGroup')
|
||||
instance_names = rsrc.get_instance_names()
|
||||
self.assertEqual(1, len(instance_names))
|
||||
|
||||
# Reduce the min size to 0, should complete without adjusting
|
||||
props = copy.copy(rsrc.properties.data)
|
||||
props['MinSize'] = '0'
|
||||
update_snippet = rsrc_defn.ResourceDefinition(rsrc.name,
|
||||
rsrc.type(),
|
||||
props)
|
||||
scheduler.TaskRunner(rsrc.update, update_snippet)()
|
||||
self.assertEqual(instance_names, rsrc.get_instance_names())
|
||||
|
||||
# trigger adjustment to reduce to 0, there should be no more instances
|
||||
self._stub_lb_reload(0)
|
||||
self._stub_scale_notification(adjust=-1, groupname=rsrc.FnGetRefId(),
|
||||
start_capacity=1, end_capacity=0)
|
||||
self._stub_meta_expected(now, 'ChangeInCapacity : -1')
|
||||
self._stub_delete(1)
|
||||
self.m.ReplayAll()
|
||||
rsrc.adjust(-1)
|
||||
self.assertEqual([], rsrc.get_instance_names())
|
||||
|
||||
rsrc.delete()
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_scaling_group_update_replace(self):
|
||||
t = template_format.parse(as_template)
|
||||
stack = utils.parse_stack(t, params=self.params)
|
||||
@ -539,192 +484,6 @@ class AutoScalingTest(common.HeatTestCase):
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_scaling_group_update_ok_maxsize(self):
|
||||
t = template_format.parse(as_template)
|
||||
properties = t['Resources']['WebServerGroup']['Properties']
|
||||
properties['MinSize'] = '1'
|
||||
properties['MaxSize'] = '3'
|
||||
stack = utils.parse_stack(t, params=self.params)
|
||||
|
||||
self._stub_lb_reload(1)
|
||||
now = timeutils.utcnow()
|
||||
self._stub_meta_expected(now, 'ExactCapacity : 1')
|
||||
self._stub_create(1)
|
||||
self.m.ReplayAll()
|
||||
rsrc = self.create_scaling_group(t, stack, 'WebServerGroup')
|
||||
self.assertEqual(1, len(rsrc.get_instance_names()))
|
||||
instance_names = rsrc.get_instance_names()
|
||||
|
||||
# Reduce the max size to 2, should complete without adjusting
|
||||
props = copy.copy(rsrc.properties.data)
|
||||
props['MaxSize'] = '2'
|
||||
update_snippet = rsrc_defn.ResourceDefinition(rsrc.name,
|
||||
rsrc.type(),
|
||||
props)
|
||||
scheduler.TaskRunner(rsrc.update, update_snippet)()
|
||||
self.assertEqual(instance_names, rsrc.get_instance_names())
|
||||
self.assertEqual(2, rsrc.properties['MaxSize'])
|
||||
|
||||
rsrc.delete()
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_scaling_group_update_ok_minsize(self):
|
||||
t = template_format.parse(as_template)
|
||||
properties = t['Resources']['WebServerGroup']['Properties']
|
||||
properties['MinSize'] = '1'
|
||||
properties['MaxSize'] = '3'
|
||||
stack = utils.parse_stack(t, params=self.params)
|
||||
|
||||
self._stub_lb_reload(1)
|
||||
now = timeutils.utcnow()
|
||||
self._stub_meta_expected(now, 'ExactCapacity : 1')
|
||||
self._stub_create(1)
|
||||
self.m.ReplayAll()
|
||||
rsrc = self.create_scaling_group(t, stack, 'WebServerGroup')
|
||||
self.assertEqual(1, len(rsrc.get_instance_names()))
|
||||
|
||||
# Increase min size to 2, should trigger an ExactCapacity adjust
|
||||
self._stub_lb_reload(2)
|
||||
self._stub_meta_expected(now, 'ExactCapacity : 1')
|
||||
self._stub_create(1)
|
||||
self.m.ReplayAll()
|
||||
|
||||
props = copy.copy(rsrc.properties.data)
|
||||
props['MinSize'] = '2'
|
||||
update_snippet = rsrc_defn.ResourceDefinition(rsrc.name,
|
||||
rsrc.type(),
|
||||
props)
|
||||
scheduler.TaskRunner(rsrc.update, update_snippet)()
|
||||
self.assertEqual(2, len(rsrc.get_instance_names()))
|
||||
self.assertEqual(2, rsrc.properties['MinSize'])
|
||||
|
||||
rsrc.delete()
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_scaling_group_update_ok_desired(self):
|
||||
t = template_format.parse(as_template)
|
||||
properties = t['Resources']['WebServerGroup']['Properties']
|
||||
properties['MinSize'] = '1'
|
||||
properties['MaxSize'] = '3'
|
||||
stack = utils.parse_stack(t, params=self.params)
|
||||
|
||||
self._stub_lb_reload(1)
|
||||
now = timeutils.utcnow()
|
||||
self._stub_meta_expected(now, 'ExactCapacity : 1')
|
||||
self._stub_create(1)
|
||||
self.m.ReplayAll()
|
||||
rsrc = self.create_scaling_group(t, stack, 'WebServerGroup')
|
||||
self.assertEqual(1, len(rsrc.get_instance_names()))
|
||||
|
||||
# Increase min size to 2 via DesiredCapacity, should adjust
|
||||
self._stub_lb_reload(2)
|
||||
self._stub_meta_expected(now, 'ExactCapacity : 2')
|
||||
self._stub_create(1)
|
||||
self.m.ReplayAll()
|
||||
|
||||
props = copy.copy(rsrc.properties.data)
|
||||
props['DesiredCapacity'] = '2'
|
||||
update_snippet = rsrc_defn.ResourceDefinition(rsrc.name,
|
||||
rsrc.type(),
|
||||
props)
|
||||
scheduler.TaskRunner(rsrc.update, update_snippet)()
|
||||
self.assertEqual(2, len(rsrc.get_instance_names()))
|
||||
self.assertEqual(2, rsrc.properties['DesiredCapacity'])
|
||||
|
||||
rsrc.delete()
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_scaling_group_update_ok_desired_zero(self):
|
||||
t = template_format.parse(as_template)
|
||||
properties = t['Resources']['WebServerGroup']['Properties']
|
||||
properties['MinSize'] = '1'
|
||||
properties['MaxSize'] = '3'
|
||||
stack = utils.parse_stack(t, params=self.params)
|
||||
|
||||
self._stub_lb_reload(1)
|
||||
now = timeutils.utcnow()
|
||||
self._stub_meta_expected(now, 'ExactCapacity : 1')
|
||||
self._stub_create(1)
|
||||
self.m.ReplayAll()
|
||||
rsrc = self.create_scaling_group(t, stack, 'WebServerGroup')
|
||||
self.assertEqual(1, len(rsrc.get_instance_names()))
|
||||
|
||||
# Increase min size to 2 via DesiredCapacity, should adjust
|
||||
self._stub_lb_reload(0)
|
||||
self._stub_meta_expected(now, 'ExactCapacity : 0')
|
||||
self._stub_delete(1)
|
||||
self.m.ReplayAll()
|
||||
|
||||
props = copy.copy(rsrc.properties.data)
|
||||
props['MinSize'] = '0'
|
||||
props['DesiredCapacity'] = '0'
|
||||
update_snippet = rsrc_defn.ResourceDefinition(rsrc.name,
|
||||
rsrc.type(),
|
||||
props)
|
||||
scheduler.TaskRunner(rsrc.update, update_snippet)()
|
||||
self.assertEqual(0, len(rsrc.get_instance_names()))
|
||||
self.assertEqual(0, rsrc.properties['DesiredCapacity'])
|
||||
|
||||
rsrc.delete()
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_scaling_group_update_ok_desired_remove(self):
|
||||
t = template_format.parse(as_template)
|
||||
properties = t['Resources']['WebServerGroup']['Properties']
|
||||
properties['DesiredCapacity'] = '2'
|
||||
stack = utils.parse_stack(t, params=self.params)
|
||||
|
||||
self._stub_lb_reload(2)
|
||||
now = timeutils.utcnow()
|
||||
self._stub_meta_expected(now, 'ExactCapacity : 2')
|
||||
self._stub_create(2)
|
||||
self.m.ReplayAll()
|
||||
rsrc = self.create_scaling_group(t, stack, 'WebServerGroup')
|
||||
self.assertEqual(2, len(rsrc.get_instance_names()))
|
||||
instance_names = rsrc.get_instance_names()
|
||||
|
||||
# Remove DesiredCapacity from the updated template, which should
|
||||
# have no effect, it's an optional parameter
|
||||
props = copy.copy(rsrc.properties.data)
|
||||
del props['DesiredCapacity']
|
||||
update_snippet = rsrc_defn.ResourceDefinition(rsrc.name,
|
||||
rsrc.type(),
|
||||
props)
|
||||
scheduler.TaskRunner(rsrc.update, update_snippet)()
|
||||
self.assertEqual(instance_names, rsrc.get_instance_names())
|
||||
self.assertIsNone(rsrc.properties['DesiredCapacity'])
|
||||
|
||||
rsrc.delete()
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_scaling_group_update_ok_cooldown(self):
|
||||
t = template_format.parse(as_template)
|
||||
properties = t['Resources']['WebServerGroup']['Properties']
|
||||
properties['Cooldown'] = '60'
|
||||
stack = utils.parse_stack(t, params=self.params)
|
||||
|
||||
self._stub_lb_reload(1)
|
||||
now = timeutils.utcnow()
|
||||
self._stub_meta_expected(now, 'ExactCapacity : 1')
|
||||
self._stub_create(1)
|
||||
self.m.ReplayAll()
|
||||
rsrc = self.create_scaling_group(t, stack, 'WebServerGroup')
|
||||
|
||||
self.assertEqual(utils.PhysName(stack.name, rsrc.name),
|
||||
rsrc.FnGetRefId())
|
||||
self.assertEqual(1, len(rsrc.get_instance_names()))
|
||||
|
||||
props = copy.copy(rsrc.properties.data)
|
||||
props['Cooldown'] = '61'
|
||||
update_snippet = rsrc_defn.ResourceDefinition(rsrc.name,
|
||||
rsrc.type(),
|
||||
props)
|
||||
scheduler.TaskRunner(rsrc.update, update_snippet)()
|
||||
self.assertEqual(61, rsrc.properties['Cooldown'])
|
||||
|
||||
rsrc.delete()
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_lb_reload_static_resolve(self):
|
||||
t = template_format.parse(as_template)
|
||||
properties = t['Resources']['ElasticLoadBalancer']['Properties']
|
||||
@ -829,35 +588,6 @@ class AutoScalingTest(common.HeatTestCase):
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_scaling_group_scale_up_failure(self):
|
||||
t = template_format.parse(as_template)
|
||||
stack = utils.parse_stack(t, params=self.params)
|
||||
|
||||
# Create initial group
|
||||
self._stub_lb_reload(1)
|
||||
now = timeutils.utcnow()
|
||||
self._stub_meta_expected(now, 'ExactCapacity : 1')
|
||||
self._stub_create(1)
|
||||
self.m.ReplayAll()
|
||||
rsrc = self.create_scaling_group(t, stack, 'WebServerGroup')
|
||||
self.assertEqual(1, len(rsrc.get_instance_names()))
|
||||
self.m.VerifyAll()
|
||||
self.m.UnsetStubs()
|
||||
|
||||
# Scale up one 1 instance with resource failure
|
||||
self._stub_create(1, with_error='Bang')
|
||||
self._stub_lb_reload(1, unset=False, nochange=True)
|
||||
self._stub_scale_notification(adjust=1,
|
||||
groupname=rsrc.FnGetRefId(),
|
||||
start_capacity=1,
|
||||
with_error='Bang')
|
||||
self.m.ReplayAll()
|
||||
|
||||
self.assertRaises(exception.Error, rsrc.adjust, 1)
|
||||
self.assertEqual(1, len(rsrc.get_instance_names()))
|
||||
|
||||
self.m.VerifyAll()
|
||||
|
||||
def test_scaling_policy_bad_group(self):
|
||||
t = template_format.parse(as_template_bad_group)
|
||||
stack = utils.parse_stack(t, params=self.params)
|
||||
|
Loading…
Reference in New Issue
Block a user