# License for the specific language governing permissions and limitations
# under the License.
-from heat.engine import resource
+from heat.common import exception
from heat.engine.resources import instance
+from heat.engine import resource
from heat.openstack.common import log as logging
from heat.openstack.common import timeutils
# resource_id is a list of resources
def handle_create(self):
- self.resize(int(self.properties['Size']))
+ self.resize(int(self.properties['Size']), raise_on_error=True)
def handle_update(self):
# TODO(asalkeld) if the only thing that has changed is the size then
for victim in inst_list:
logger.debug('handle_delete %s' % victim)
inst = self._make_instance(victim)
- inst.destroy()
+ error_str = inst.destroy()
+ if error_str is not None:
+ # try suck out the grouped resouces failure reason
+ # and re-raise
+ raise exception.NestedResourceFailure(message=error_str)
- def resize(self, new_capacity):
+ def resize(self, new_capacity, raise_on_error=False):
inst_list = []
if self.resource_id is not None:
inst_list = sorted(self.resource_id.split(','))
inst = self._make_instance(name)
inst_list.append(name)
self.resource_id_set(','.join(inst_list))
- inst.create()
+ logger.info('creating inst')
+ error_str = inst.create()
+ if raise_on_error and error_str is not None:
+ # try suck out the grouped resouces failure reason
+ # and re-raise
+ raise exception.NestedResourceFailure(message=error_str)
else:
# shrink (kill largest numbered first)
del_list = inst_list[new_capacity:]
else:
num_to_create = int(self.properties['MinSize'])
- self.adjust(num_to_create, adjustment_type='ExactCapacity')
+ self.adjust(num_to_create, adjustment_type='ExactCapacity',
+ raise_on_error=True)
def handle_update(self):
return self.UPDATE_REPLACE
- def adjust(self, adjustment, adjustment_type='ChangeInCapacity'):
+ def adjust(self, adjustment, adjustment_type='ChangeInCapacity',
+ raise_on_error=False):
if self._cooldown_inprogress():
logger.info("%s NOT performing scaling adjustment, cooldown %s" %
(self.name, self.properties['Cooldown']))
logger.debug('no change in capacity %d' % capacity)
return
- self.resize(new_capacity)
+ self.resize(new_capacity, raise_on_error=raise_on_error)
self._cooldown_timestamp("%s : %s" % (adjustment_type, adjustment))
from heat.common import template_format
from heat.engine.resources import autoscaling as asc
from heat.engine.resources import loadbalancer
+from heat.engine.resources import instance
from heat.engine import parser
from heat.engine.resource import Metadata
from heat.openstack.common import timeutils
resource = asc.ScalingPolicy(resource_name,
t['Resources'][resource_name],
stack)
+
self.assertEqual(None, resource.validate())
self.assertEqual(None, resource.create())
self.assertEqual(asc.ScalingPolicy.CREATE_COMPLETE,
resource.state)
return resource
+ def _stub_create(self, num):
+ self.m.StubOutWithMock(instance.Instance, 'create')
+ for x in range(num):
+ instance.Instance.create().AndReturn(None)
+
def _stub_lb_reload(self, expected_list, unset=True):
if unset:
self.m.VerifyAll()
self._stub_lb_reload(['WebServerGroup-0'])
now = timeutils.utcnow()
self._stub_meta_expected(now, 'ExactCapacity : 1')
+ self._stub_create(1)
self.m.ReplayAll()
resource = self.create_scaling_group(t, stack, 'WebServerGroup')
'WebServerGroup-2'])
now = timeutils.utcnow()
self._stub_meta_expected(now, 'ExactCapacity : 3')
+ self._stub_create(3)
self.m.ReplayAll()
resource = self.create_scaling_group(t, stack, 'WebServerGroup')
self.assertEqual('WebServerGroup-0,WebServerGroup-1,WebServerGroup-2',
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1',
'WebServerGroup-2'])
self._stub_meta_expected(now, 'ChangeInCapacity : 2')
+ self._stub_create(2)
self.m.ReplayAll()
resource.adjust(2)
self.assertEqual('WebServerGroup-0,WebServerGroup-1,WebServerGroup-2',
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1'])
now = timeutils.utcnow()
self._stub_meta_expected(now, 'ExactCapacity : 2')
+ self._stub_create(2)
self.m.ReplayAll()
resource = self.create_scaling_group(t, stack, 'WebServerGroup')
stack.resources['WebServerGroup'] = resource
properties = t['Resources']['WebServerGroup']['Properties']
properties['DesiredCapacity'] = '2'
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1'])
+ self._stub_create(2)
now = timeutils.utcnow()
self._stub_meta_expected(now, 'ExactCapacity : 2')
self.m.ReplayAll()
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1',
'WebServerGroup-2'])
self._stub_meta_expected(now, 'PercentChangeInCapacity : 200')
+ self._stub_create(2)
self.m.ReplayAll()
resource.adjust(200, 'PercentChangeInCapacity')
self.assertEqual('WebServerGroup-0,WebServerGroup-1,WebServerGroup-2',
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1'])
now = timeutils.utcnow()
self._stub_meta_expected(now, 'ExactCapacity : 2')
+ self._stub_create(2)
self.m.ReplayAll()
resource = self.create_scaling_group(t, stack, 'WebServerGroup')
stack.resources['WebServerGroup'] = resource
properties['DesiredCapacity'] = '2'
properties['Cooldown'] = '60'
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1'])
+ self._stub_create(2)
now = timeutils.utcnow()
self._stub_meta_expected(now, 'ExactCapacity : 2')
self.m.ReplayAll()
# raise by 200%, should work
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1',
'WebServerGroup-2'], unset=False)
+ self._stub_create(2)
self._stub_meta_expected(now, 'PercentChangeInCapacity : 200')
self.m.ReplayAll()
resource.adjust(200, 'PercentChangeInCapacity')
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1'])
now = timeutils.utcnow()
self._stub_meta_expected(now, 'ExactCapacity : 2')
+ self._stub_create(2)
self.m.ReplayAll()
resource = self.create_scaling_group(t, stack, 'WebServerGroup')
stack.resources['WebServerGroup'] = resource
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1',
'WebServerGroup-2'], unset=False)
self._stub_meta_expected(now, 'PercentChangeInCapacity : 200')
+ self._stub_create(2)
self.m.ReplayAll()
resource.adjust(200, 'PercentChangeInCapacity')
self.assertEqual('WebServerGroup-0,WebServerGroup-1,WebServerGroup-2',
self._stub_lb_reload(['WebServerGroup-0'])
now = timeutils.utcnow()
self._stub_meta_expected(now, 'ExactCapacity : 1')
+ self._stub_create(1)
self.m.ReplayAll()
resource = self.create_scaling_group(t, stack, 'WebServerGroup')
stack.resources['WebServerGroup'] = resource
# Scale up one
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1'])
self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2)
+ self._stub_create(1)
self.m.ReplayAll()
up_policy = self.create_scaling_policy(t, stack,
'WebServerScaleUpPolicy')
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1'])
now = timeutils.utcnow()
self._stub_meta_expected(now, 'ExactCapacity : 2')
+ self._stub_create(2)
self.m.ReplayAll()
resource = self.create_scaling_group(t, stack, 'WebServerGroup')
stack.resources['WebServerGroup'] = resource
self._stub_lb_reload(['WebServerGroup-0'])
now = timeutils.utcnow()
self._stub_meta_expected(now, 'ExactCapacity : 1')
+ self._stub_create(1)
self.m.ReplayAll()
resource = self.create_scaling_group(t, stack, 'WebServerGroup')
stack.resources['WebServerGroup'] = resource
# Scale up one
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1'])
self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2)
+ self._stub_create(1)
self.m.ReplayAll()
up_policy = self.create_scaling_policy(t, stack,
'WebServerScaleUpPolicy')
self._stub_lb_reload(['WebServerGroup-0'])
now = timeutils.utcnow()
self._stub_meta_expected(now, 'ExactCapacity : 1')
+ self._stub_create(1)
self.m.ReplayAll()
resource = self.create_scaling_group(t, stack, 'WebServerGroup')
stack.resources['WebServerGroup'] = resource
# Scale up one
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1'])
self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2)
+ self._stub_create(1)
self.m.ReplayAll()
up_policy = self.create_scaling_policy(t, stack,
'WebServerScaleUpPolicy')
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1',
'WebServerGroup-2'], unset=False)
self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2)
+ self._stub_create(1)
self.m.ReplayAll()
up_policy.alarm()
self._stub_lb_reload(['WebServerGroup-0'])
now = timeutils.utcnow()
self._stub_meta_expected(now, 'ExactCapacity : 1')
+ self._stub_create(1)
self.m.ReplayAll()
resource = self.create_scaling_group(t, stack, 'WebServerGroup')
stack.resources['WebServerGroup'] = resource
properties['Cooldown'] = '0'
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1'])
self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2)
+ self._stub_create(1)
self.m.ReplayAll()
up_policy = self.create_scaling_policy(t, stack,
'WebServerScaleUpPolicy')
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1',
'WebServerGroup-2'], unset=False)
self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2)
+ self._stub_create(1)
self.m.ReplayAll()
up_policy.alarm()
self._stub_lb_reload(['WebServerGroup-0'])
now = timeutils.utcnow()
self._stub_meta_expected(now, 'ExactCapacity : 1')
+ self._stub_create(1)
self.m.ReplayAll()
resource = self.create_scaling_group(t, stack, 'WebServerGroup')
stack.resources['WebServerGroup'] = resource
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1'])
now = timeutils.utcnow()
self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2)
+ self._stub_create(1)
self.m.ReplayAll()
up_policy = self.create_scaling_policy(t, stack,
'WebServerScaleUpPolicy')
self._stub_lb_reload(['WebServerGroup-0', 'WebServerGroup-1',
'WebServerGroup-2'], unset=False)
self._stub_meta_expected(now, 'ChangeInCapacity : 1', 2)
+ self._stub_create(1)
self.m.ReplayAll()
up_policy.alarm()
from nose.plugins.attrib import attr
+from heat.tests.v1_1 import fakes
from heat.common import context
from heat.common import template_format
from heat.engine.resources import autoscaling as asc
+from heat.engine.resources import instance
from heat.engine.resources import loadbalancer
from heat.engine import parser
@attr(speed='fast')
class InstanceGroupTest(unittest.TestCase):
def setUp(self):
+ self.fc = fakes.FakeClient()
self.m = mox.Mox()
self.m.StubOutWithMock(loadbalancer.LoadBalancer, 'reload')
return stack
+ def _stub_create(self, num):
+ self.m.StubOutWithMock(instance.Instance, 'create')
+ for x in range(num):
+ instance.Instance.create().AndReturn(None)
+
def create_instance_group(self, t, stack, resource_name):
resource = asc.InstanceGroup(resource_name,
t['Resources'][resource_name],
stack = self.parse_stack(t)
# start with min then delete
+ self._stub_create(1)
+ self.m.ReplayAll()
resource = self.create_instance_group(t, stack, 'JobServerGroup')
self.assertEqual('JobServerGroup', resource.FnGetRefId())
resource.handle_update())
resource.delete()
+
+ def test_missing_image(self):
+
+ t = self.load_template()
+ stack = self.parse_stack(t)
+
+ resource = asc.InstanceGroup('JobServerGroup',
+ t['Resources']['JobServerGroup'],
+ stack)
+
+ self.m.StubOutWithMock(instance.Instance, 'create')
+ instance.Instance.create().AndReturn('ImageNotFound: bla')
+
+ self.m.ReplayAll()
+
+ self.assertEqual(resource.create(), 'ImageNotFound: bla')
+ self.assertEqual(asc.InstanceGroup.CREATE_FAILED, resource.state)
+
+ self.m.VerifyAll()