summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEoghan Glynn <eglynn@redhat.com>2013-11-25 17:09:40 +0000
committerEoghan Glynn <eglynn@redhat.com>2013-11-26 15:39:06 +0000
commita8c0b1107a62d5a145cf9ff58b85d9e3210fe95c (patch)
treef8aa43624995ff2a34238d66334267195b7e8215
parentf33297d7f13eedc8e8aa5e5db294d3a725679974 (diff)
downloadheat-a8c0b1107a62d5a145cf9ff58b85d9e3210fe95c.tar.gz
Use all available headroom for autoscaling
Fixes bug 1254796 Previously, potential headroom for autoscaling group growth or shrinkage would remain unused unless the adjustment exactly hit the max or min size respectively. Now, we truncate the adjustment to the upper or lower bound in the case of an over-shoot. Change-Id: I760be999039f7038dab77cb8b77a0f683ef56db3
-rw-r--r--heat/engine/resources/autoscaling.py23
-rw-r--r--heat/tests/test_autoscaling.py40
2 files changed, 40 insertions, 23 deletions
diff --git a/heat/engine/resources/autoscaling.py b/heat/engine/resources/autoscaling.py
index ee7cfbe96..35ac1fbb6 100644
--- a/heat/engine/resources/autoscaling.py
+++ b/heat/engine/resources/autoscaling.py
@@ -420,12 +420,23 @@ class AutoScalingGroup(InstanceGroup, CooldownMixin):
else math.ceil(delta))
new_capacity = capacity + rounded
- if new_capacity > int(self.properties['MaxSize']):
- logger.warn('can not exceed %s' % self.properties['MaxSize'])
- return
- if new_capacity < int(self.properties['MinSize']):
- logger.warn('can not be less than %s' % self.properties['MinSize'])
- return
+ upper = int(self.properties['MaxSize'])
+ lower = int(self.properties['MinSize'])
+
+ if new_capacity > upper:
+ if upper > capacity:
+ logger.info(_('truncating growth to %s') % upper)
+ new_capacity = upper
+ else:
+ logger.warn(_('can not exceed %s') % upper)
+ return
+ if new_capacity < lower:
+ if lower < capacity:
+ logger.info(_('truncating shrinkage to %s') % lower)
+ new_capacity = lower
+ else:
+ logger.warn(_('can not be less than %s') % lower)
+ return
if new_capacity == capacity:
logger.debug('no change in capacity %d' % capacity)
diff --git a/heat/tests/test_autoscaling.py b/heat/tests/test_autoscaling.py
index 119ce747e..d47c185d8 100644
--- a/heat/tests/test_autoscaling.py
+++ b/heat/tests/test_autoscaling.py
@@ -801,7 +801,7 @@ class AutoScalingTest(HeatTestCase):
self.m.VerifyAll()
- def test_scaling_group_nochange(self):
+ def test_scaling_group_truncate_adjustment(self):
t = template_format.parse(as_template)
stack = utils.parse_stack(t, params=self.params)
@@ -819,33 +819,39 @@ class AutoScalingTest(HeatTestCase):
rsrc.get_instance_names())
# raise above the max
+ self._stub_lb_reload(5)
+ self._stub_meta_expected(now, 'ChangeInCapacity : 4')
+ self._stub_create(3)
+ self.m.ReplayAll()
rsrc.adjust(4)
- self.assertEqual(['WebServerGroup-0', 'WebServerGroup-1'],
- rsrc.get_instance_names())
+ self._verify_instance_names(rsrc, 5)
# lower below the min
- rsrc.adjust(-2)
- self.assertEqual(['WebServerGroup-0', 'WebServerGroup-1'],
- rsrc.get_instance_names())
+ self._stub_lb_reload(1)
+ self._stub_validate()
+ self._stub_meta_expected(now, 'ChangeInCapacity : -5')
+ self.m.ReplayAll()
+ rsrc.adjust(-5)
+ self._verify_instance_names(rsrc, 1)
# no change
rsrc.adjust(0)
- self.assertEqual(['WebServerGroup-0', 'WebServerGroup-1'],
- rsrc.get_instance_names())
+ self._verify_instance_names(rsrc, 1)
+
rsrc.delete()
self.m.VerifyAll()
+ def _verify_instance_names(self, group, bound):
+ instance_names = group.get_instance_names()
+ self.assertEqual(len(instance_names), bound)
+ for i in xrange(bound):
+ self.assertEqual('WebServerGroup-%d' % i, instance_names[i])
+
def _do_test_scaling_group_percent(self, decrease, lowest,
increase, create, highest):
t = template_format.parse(as_template)
stack = utils.parse_stack(t, params=self.params)
- def _verify_instance_names(bound):
- instance_names = rsrc.get_instance_names()
- self.assertEqual(len(instance_names), bound)
- for i in xrange(bound):
- self.assertEqual('WebServerGroup-%d' % i, instance_names[i])
-
# Create initial group, 2 instances
properties = t['Resources']['WebServerGroup']['Properties']
properties['DesiredCapacity'] = '2'
@@ -856,7 +862,7 @@ class AutoScalingTest(HeatTestCase):
self.m.ReplayAll()
rsrc = self.create_scaling_group(t, stack, 'WebServerGroup')
stack.resources['WebServerGroup'] = rsrc
- _verify_instance_names(2)
+ self._verify_instance_names(rsrc, 2)
# reduce by decrease %
self._stub_lb_reload(lowest)
@@ -865,7 +871,7 @@ class AutoScalingTest(HeatTestCase):
self._stub_validate()
self.m.ReplayAll()
rsrc.adjust(decrease, 'PercentChangeInCapacity')
- _verify_instance_names(lowest)
+ self._verify_instance_names(rsrc, lowest)
# raise by increase %
self._stub_lb_reload(highest)
@@ -874,7 +880,7 @@ class AutoScalingTest(HeatTestCase):
self._stub_create(create)
self.m.ReplayAll()
rsrc.adjust(increase, 'PercentChangeInCapacity')
- _verify_instance_names(highest)
+ self._verify_instance_names(rsrc, highest)
rsrc.delete()