From 11dc22a701fd7dbde214360baeb88bc50985d080 Mon Sep 17 00:00:00 2001 From: tengqm Date: Wed, 26 Nov 2014 20:01:38 +0800 Subject: [PATCH] Extract group functions into a utility module. This patch extracts group checking functions into a dedicated module so that resource implementations are simplified. The module could later be used by the autoscaling engine as well. Change-Id: I99cdd8c9e8fe377e6923ab047a9c2ef08d1defad partial-blueprint: reorg-asg-code partial-blueprint: as-lib --- heat/common/grouputils.py | 62 +++++++++++++ .../engine/resources/aws/autoscaling_group.py | 7 +- heat/engine/resources/instance_group.py | 32 ++----- .../resources/openstack/autoscaling_group.py | 7 +- heat/tests/autoscaling/test_scaling_group.py | 7 +- heat/tests/test_autoscaling.py | 31 ++++--- heat/tests/test_autoscaling_update_policy.py | 11 ++- heat/tests/test_grouputils.py | 92 +++++++++++++++++++ heat/tests/test_heat_autoscaling_group.py | 77 ++++++++-------- .../test_instance_group_update_policy.py | 9 +- heat/tests/test_notifications.py | 7 +- 11 files changed, 242 insertions(+), 100 deletions(-) create mode 100644 heat/common/grouputils.py create mode 100644 heat/tests/test_grouputils.py diff --git a/heat/common/grouputils.py b/heat/common/grouputils.py new file mode 100644 index 0000000000..65ec62f9e1 --- /dev/null +++ b/heat/common/grouputils.py @@ -0,0 +1,62 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import six + + +def get_size(group): + """Get number of member resources managed by the specified group. + + The list of members are not sorted or returned. + """ + if group.nested(): + resources = [r for r in six.itervalues(group.nested()) + if r.status != r.FAILED] + return len(resources) + else: + return 0 + + +def get_members(group): + """Get a list of member resources managed by the specified group. + + Sort the list of instances first by created_time then by name. + """ + resources = [] + if group.nested(): + resources = [r for r in six.itervalues(group.nested()) + if r.status != r.FAILED] + + return sorted(resources, key=lambda r: (r.created_time, r.name)) + + +def get_member_refids(group, exclude=None): + """Get a list of member resources managed by the specified group. + + The list of resources is sorted first by created_time then by name. + """ + members = get_members(group) + if len(members) == 0: + return [] + + if exclude is None: + exclude = [] + return [r.FnGetRefId() for r in members + if r.FnGetRefId() not in exclude] + + +def get_member_names(group): + """Get a list of resource names of the resources in the specified group. + Failed resources will be ignored. + """ + return [r.name for r in get_members(group)] diff --git a/heat/engine/resources/aws/autoscaling_group.py b/heat/engine/resources/aws/autoscaling_group.py index f0d430e2de..82385f80ee 100644 --- a/heat/engine/resources/aws/autoscaling_group.py +++ b/heat/engine/resources/aws/autoscaling_group.py @@ -16,6 +16,7 @@ from oslo.utils import excutils import six from heat.common import exception +from heat.common import grouputils from heat.common.i18n import _ from heat.common.i18n import _LI from heat.engine import constraints @@ -213,7 +214,7 @@ class AutoScalingGroup(instgrp.InstanceGroup, cooldown.CooldownMixin): done = super(AutoScalingGroup, self).check_create_complete(task) if done: self._cooldown_timestamp( - "%s : %s" % (EXACT_CAPACITY, len(self.get_instances()))) + "%s : %s" % (EXACT_CAPACITY, grouputils.get_size(self))) return done def handle_update(self, json_snippet, tmpl_diff, prop_diff): @@ -241,7 +242,7 @@ class AutoScalingGroup(instgrp.InstanceGroup, cooldown.CooldownMixin): self.adjust(self.properties[self.DESIRED_CAPACITY], adjustment_type=EXACT_CAPACITY) else: - current_capacity = len(self.get_instances()) + current_capacity = grouputils.get_size(self) self.adjust(current_capacity, adjustment_type=EXACT_CAPACITY) def adjust(self, adjustment, adjustment_type=CHANGE_IN_CAPACITY): @@ -255,7 +256,7 @@ class AutoScalingGroup(instgrp.InstanceGroup, cooldown.CooldownMixin): 'cooldown': self.properties[self.COOLDOWN]}) return - capacity = len(self.get_instances()) + capacity = grouputils.get_size(self) lower = self.properties[self.MIN_SIZE] upper = self.properties[self.MAX_SIZE] diff --git a/heat/engine/resources/instance_group.py b/heat/engine/resources/instance_group.py index d0b5adcf48..f9e44099f4 100644 --- a/heat/engine/resources/instance_group.py +++ b/heat/engine/resources/instance_group.py @@ -15,6 +15,7 @@ import copy from heat.common import environment_format from heat.common import exception +from heat.common import grouputils from heat.common.i18n import _ from heat.common import timeutils as iso8601utils from heat.engine import attributes @@ -165,24 +166,6 @@ class InstanceGroup(stack_resource.StackResource): lc=self.LAUNCH_CONFIGURATION_NAME, ref=conf_refid)) - def get_instance_names(self): - """Get a list of resource names of the instances in this InstanceGroup. - - Failed resources will be ignored. - """ - return [r.name for r in self.get_instances()] - - def get_instances(self): - """Get a list of all the instance resources managed by this group. - - Sort the list of instances first by created_time then by name. - """ - resources = [] - if self.nested(): - resources = [resource for resource in self.nested().itervalues() - if resource.status != resource.FAILED] - return sorted(resources, key=lambda r: (r.created_time, r.name)) - def _environment(self): """Return the environment for the nested stack.""" return { @@ -232,8 +215,8 @@ class InstanceGroup(stack_resource.StackResource): # Get the current capacity, we may need to adjust if # Size has changed if self.SIZE in prop_diff: - inst_list = self.get_instances() - if len(inst_list) != self.properties[self.SIZE]: + curr_size = grouputils.get_size(self) + if curr_size != self.properties[self.SIZE]: self.resize(self.properties[self.SIZE]) def _tags(self): @@ -270,7 +253,7 @@ class InstanceGroup(stack_resource.StackResource): def _get_instance_templates(self): """Get templates for resource instances.""" return [(instance.name, instance.t) - for instance in self.get_instances()] + for instance in grouputils.get_members(self)] def _create_template(self, num_instances, num_replace=0, template_version=('HeatTemplateFormatVersion', @@ -301,7 +284,7 @@ class InstanceGroup(stack_resource.StackResource): Replace the instances in the group using updated launch configuration """ def changing_instances(tmpl): - instances = self.get_instances() + instances = grouputils.get_members(self) current = set((i.name, i.t) for i in instances) updated = set(tmpl.resource_definitions(self.nested()).items()) # includes instances to be updated and deleted @@ -374,8 +357,7 @@ class InstanceGroup(stack_resource.StackResource): ''' exclude = exclude or [] if self.properties[self.LOAD_BALANCER_NAMES]: - id_list = [inst.FnGetRefId() for inst in self.get_instances() - if inst.FnGetRefId() not in exclude] + id_list = grouputils.get_member_refids(self, exclude=exclude) for lb in self.properties[self.LOAD_BALANCER_NAMES]: lb_resource = self.stack[lb] @@ -408,7 +390,7 @@ class InstanceGroup(stack_resource.StackResource): ''' if name == self.INSTANCE_LIST: return u','.join(inst.FnGetAtt('PublicIp') - for inst in self.get_instances()) or None + for inst in grouputils.get_members(self)) or None def child_template(self): num_instances = int(self.properties[self.SIZE]) diff --git a/heat/engine/resources/openstack/autoscaling_group.py b/heat/engine/resources/openstack/autoscaling_group.py index a0c0322196..31ac842318 100644 --- a/heat/engine/resources/openstack/autoscaling_group.py +++ b/heat/engine/resources/openstack/autoscaling_group.py @@ -12,6 +12,7 @@ # under the License. from heat.common import exception +from heat.common import grouputils from heat.common.i18n import _ from heat.engine import attributes from heat.engine import constraints @@ -148,10 +149,10 @@ class AutoScalingResourceGroup(aws_asg.AutoScalingGroup): def FnGetAtt(self, key, *path): if key == self.CURRENT_SIZE: - return len(self.get_instances()) + return grouputils.get_size(self) if path: - attrs = ((rsrc.name, - rsrc.FnGetAtt(*path)) for rsrc in self.get_instances()) + members = grouputils.get_members(self) + attrs = ((rsrc.name, rsrc.FnGetAtt(*path)) for rsrc in members) if key == self.OUTPUTS: return dict(attrs) if key == self.OUTPUTS_LIST: diff --git a/heat/tests/autoscaling/test_scaling_group.py b/heat/tests/autoscaling/test_scaling_group.py index dfa58e7f27..b6928afea1 100644 --- a/heat/tests/autoscaling/test_scaling_group.py +++ b/heat/tests/autoscaling/test_scaling_group.py @@ -16,6 +16,7 @@ from oslo.config import cfg import six from heat.common import exception +from heat.common import grouputils from heat.common import template_format from heat.engine import scheduler from heat.tests.autoscaling import inline_templates @@ -178,14 +179,14 @@ class TestGroupAdjust(common.HeatTestCase): def test_scaling_policy_cooldown_toosoon(self): """If _cooldown_inprogress() returns True don't progress.""" - dont_call = self.patchobject(self.group, 'get_instances') + dont_call = self.patchobject(grouputils, 'get_members') with mock.patch.object(self.group, '_cooldown_inprogress', return_value=True): self.group.adjust(1) self.assertEqual([], dont_call.call_args_list) def test_scaling_policy_cooldown_ok(self): - self.patchobject(self.group, 'get_instances', return_value=[]) + self.patchobject(grouputils, 'get_members', return_value=[]) resize = self.patchobject(self.group, 'resize') cd_stamp = self.patchobject(self.group, '_cooldown_timestamp') notify = self.patch('heat.engine.notification.autoscaling.send') @@ -213,7 +214,7 @@ class TestGroupAdjust(common.HeatTestCase): 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(grouputils, 'get_members', return_value=[]) self.patchobject(self.group, 'resize', side_effect=ValueError('test error')) notify = self.patch('heat.engine.notification.autoscaling.send') diff --git a/heat/tests/test_autoscaling.py b/heat/tests/test_autoscaling.py index c163f7fe1e..ac1ed0ddf8 100644 --- a/heat/tests/test_autoscaling.py +++ b/heat/tests/test_autoscaling.py @@ -20,6 +20,7 @@ from oslo.utils import timeutils import six from heat.common import exception +from heat.common import grouputils from heat.common import short_id from heat.common import template_format from heat.engine.notification import autoscaling as notification @@ -260,7 +261,7 @@ class AutoScalingTest(common.HeatTestCase): 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())) + self.assertEqual(1, len(grouputils.get_member_names(rsrc))) props = copy.copy(rsrc.properties.data) props['AvailabilityZones'] = ['foo'] update_snippet = rsrc_defn.ResourceDefinition(rsrc.name, @@ -284,7 +285,7 @@ class AutoScalingTest(common.HeatTestCase): 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())) + self.assertEqual(1, len(grouputils.get_member_names(rsrc))) self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.m.VerifyAll() @@ -311,7 +312,7 @@ class AutoScalingTest(common.HeatTestCase): 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())) + self.assertEqual(1, len(grouputils.get_member_names(rsrc))) self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.m.VerifyAll() @@ -344,7 +345,7 @@ class AutoScalingTest(common.HeatTestCase): rsrc = self.create_scaling_group(t, stack, 'WebServerGroup') self.assertEqual(utils.PhysName(stack.name, rsrc.name), rsrc.FnGetRefId()) - self.assertEqual(2, len(rsrc.get_instance_names())) + self.assertEqual(2, len(grouputils.get_member_names(rsrc))) self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.m.VerifyAll() @@ -374,7 +375,7 @@ class AutoScalingTest(common.HeatTestCase): rsrc = self.create_scaling_group(t, stack, 'WebServerGroup') self.assertEqual(utils.PhysName(stack.name, rsrc.name), rsrc.FnGetRefId()) - self.assertEqual(2, len(rsrc.get_instance_names())) + self.assertEqual(2, len(grouputils.get_member_names(rsrc))) self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.m.VerifyAll() @@ -406,7 +407,7 @@ class AutoScalingTest(common.HeatTestCase): 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())) + self.assertEqual(1, len(grouputils.get_member_names(rsrc))) self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.m.VerifyAll() @@ -436,7 +437,7 @@ class AutoScalingTest(common.HeatTestCase): 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())) + self.assertEqual(1, len(grouputils.get_member_names(rsrc))) self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) self.m.VerifyAll() @@ -480,7 +481,7 @@ class AutoScalingTest(common.HeatTestCase): scheduler.TaskRunner(rsrc.create)) self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state) - self.assertEqual([], rsrc.get_instance_names()) + self.assertEqual([], grouputils.get_members(rsrc)) self.m.VerifyAll() @@ -520,7 +521,7 @@ class AutoScalingTest(common.HeatTestCase): 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())) + self.assertEqual(1, len(grouputils.get_member_names(rsrc))) props = copy.copy(rsrc.properties.data) props['Cooldown'] = '61' update_snippet = rsrc_defn.ResourceDefinition(rsrc.name, @@ -627,7 +628,7 @@ class AutoScalingTest(common.HeatTestCase): self.m.ReplayAll() rsrc = self.create_scaling_group(t, stack, 'WebServerGroup') stack.resources['WebServerGroup'] = rsrc - self.assertEqual(1, len(rsrc.get_instance_names())) + self.assertEqual(1, len(grouputils.get_member_names(rsrc))) # Scale up one self._stub_lb_reload(2) @@ -641,7 +642,7 @@ class AutoScalingTest(common.HeatTestCase): alarm_url = up_policy.FnGetAtt('AlarmUrl') self.assertIsNotNone(alarm_url) up_policy.signal() - self.assertEqual(2, len(rsrc.get_instance_names())) + self.assertEqual(2, len(grouputils.get_member_names(rsrc))) # Check CustomLB metadata was updated self.m.StubOutWithMock(instance.Instance, '_ipaddress') @@ -668,7 +669,7 @@ class AutoScalingTest(common.HeatTestCase): self.m.ReplayAll() rsrc = self.create_scaling_group(t, stack, 'WebServerGroup') stack.resources['WebServerGroup'] = rsrc - self.assertEqual(1, len(rsrc.get_instance_names())) + self.assertEqual(1, len(grouputils.get_member_names(rsrc))) # Create initial scaling policy up_policy = self.create_scaling_policy(t, stack, @@ -683,7 +684,7 @@ class AutoScalingTest(common.HeatTestCase): # Trigger alarm up_policy.signal() - self.assertEqual(2, len(rsrc.get_instance_names())) + self.assertEqual(2, len(grouputils.get_member_names(rsrc))) # Update scaling policy props = copy.copy(up_policy.properties.data) @@ -717,7 +718,7 @@ class AutoScalingTest(common.HeatTestCase): # Trigger alarm up_policy.signal() - self.assertEqual(4, len(rsrc.get_instance_names())) + self.assertEqual(4, len(grouputils.get_member_names(rsrc))) rsrc.delete() self.m.VerifyAll() @@ -736,7 +737,7 @@ class AutoScalingTest(common.HeatTestCase): self.m.ReplayAll() rsrc = self.create_scaling_group(t, stack, 'WebServerGroup') - instances = rsrc.get_instances() + instances = grouputils.get_members(rsrc) self.assertEqual(1, len(instances)) self.assertEqual('xxxx', instances[0].properties['SubnetId']) diff --git a/heat/tests/test_autoscaling_update_policy.py b/heat/tests/test_autoscaling_update_policy.py index 24bdfe6ee6..3c88c16f84 100644 --- a/heat/tests/test_autoscaling_update_policy.py +++ b/heat/tests/test_autoscaling_update_policy.py @@ -20,6 +20,7 @@ from oslo.config import cfg from testtools.matchers import MatchesRegex from heat.common import exception +from heat.common import grouputils from heat.common import template_format from heat.engine.clients.os import nova from heat.engine import function @@ -494,8 +495,8 @@ class AutoScalingGroupTest(common.HeatTestCase): self.m.UnsetStubs() # saves info from initial list of instances for comparison later - init_instances = current_grp.get_instances() - init_names = current_grp.get_instance_names() + init_instances = grouputils.get_members(current_grp) + init_names = grouputils.get_member_names(current_grp) init_images = [(i.name, i.t['Properties']['ImageId']) for i in init_instances] init_flavors = [(i.name, i.t['Properties']['InstanceType']) @@ -527,7 +528,7 @@ class AutoScalingGroupTest(common.HeatTestCase): # test that the update policy is updated updated_grp = stack['WebServerGroup'] - updt_instances = updated_grp.get_instances() + updt_instances = grouputils.get_members(updated_grp) self.assertTrue('AutoScalingRollingUpdate' in updated_grp.update_policy) updated_policy = updated_grp.update_policy['AutoScalingRollingUpdate'] @@ -540,8 +541,8 @@ class AutoScalingGroupTest(common.HeatTestCase): self.assertNotEqual(conf_name, updated_conf_name) # test that the group size are the same - updt_instances = updated_grp.get_instances() - updt_names = updated_grp.get_instance_names() + updt_instances = grouputils.get_members(updated_grp) + updt_names = grouputils.get_member_names(updated_grp) self.assertEqual(len(init_names), len(updt_names)) # test that appropriate number of instance names are the same diff --git a/heat/tests/test_grouputils.py b/heat/tests/test_grouputils.py new file mode 100644 index 0000000000..7fbc51e56a --- /dev/null +++ b/heat/tests/test_grouputils.py @@ -0,0 +1,92 @@ +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import mock + +from heat.common import grouputils +from heat.common import template_format +from heat.engine import resource +from heat.tests import common +from heat.tests import generic_resource +from heat.tests import utils + +nested_stack = ''' +heat_template_version: 2013-05-23 +resources: + r0: + type: dummy.resource + r1: + type: dummy.resource +''' + + +class SimpleResource(generic_resource.ResourceWithProps): + + def FnGetRefId(self): + return 'ID-%s' % self.name + + +class GroupUtilsTest(common.HeatTestCase): + + def setUp(self): + super(GroupUtilsTest, self).setUp() + resource._register_class('dummy.resource', SimpleResource) + + def test_non_nested_resource(self): + group = mock.Mock() + self.patchobject(group, 'nested', return_value=None) + + self.assertEqual(0, grouputils.get_size(group)) + self.assertEqual([], grouputils.get_members(group)) + self.assertEqual([], grouputils.get_member_refids(group)) + self.assertEqual([], grouputils.get_member_names(group)) + + def test_normal_group(self): + group = mock.Mock() + t = template_format.parse(nested_stack) + stack = utils.parse_stack(t) + + # group size + self.patchobject(group, 'nested', return_value=stack) + self.assertEqual(2, grouputils.get_size(group)) + + # member list (sorted) + members = [r for r in stack.itervalues()] + expected = sorted(members, key=lambda r: (r.created_time, r.name)) + actual = grouputils.get_members(group) + self.assertEqual(expected, actual) + + # refids + actual_ids = grouputils.get_member_refids(group) + self.assertEqual(['ID-r0', 'ID-r1'], actual_ids) + partial_ids = grouputils.get_member_refids(group, exclude=['ID-r1']) + self.assertEqual(['ID-r0'], partial_ids) + + # names + self.assertEqual(['r0', 'r1'], grouputils.get_member_names(group)) + + def test_group_with_failed_members(self): + group = mock.Mock() + t = template_format.parse(nested_stack) + stack = utils.parse_stack(t) + self.patchobject(group, 'nested', return_value=stack) + + # Just failed for whatever reason + rsrc_err = stack.resources['r0'] + rsrc_err.status = rsrc_err.FAILED + rsrc_ok = stack.resources['r1'] + + self.assertEqual(1, grouputils.get_size(group)) + self.assertEqual([rsrc_ok], grouputils.get_members(group)) + self.assertEqual(['ID-r1'], grouputils.get_member_refids(group)) + self.assertEqual(['r1'], grouputils.get_member_names(group)) diff --git a/heat/tests/test_heat_autoscaling_group.py b/heat/tests/test_heat_autoscaling_group.py index d2dc1ea6b5..5ea533667c 100644 --- a/heat/tests/test_heat_autoscaling_group.py +++ b/heat/tests/test_heat_autoscaling_group.py @@ -18,10 +18,10 @@ from oslo.config import cfg from oslo.utils import timeutils from heat.common import exception +from heat.common import grouputils from heat.common import short_id from heat.common import template_format from heat.engine import resource -from heat.engine.resources.openstack import autoscaling_group as asg from heat.engine import rsrc_defn from heat.engine import scheduler from heat.engine import stack_resource @@ -67,7 +67,7 @@ class AutoScalingGroupTest(common.HeatTestCase): properties['min_size'] = 0 properties['max_size'] = 0 rsrc = self.create_stack(self.parsed)['my-group'] - self.assertEqual(0, len(rsrc.get_instances())) + self.assertEqual(0, grouputils.get_size(rsrc)) rsrc.delete() def test_scaling_adjust_down_empty(self): @@ -75,7 +75,7 @@ class AutoScalingGroupTest(common.HeatTestCase): properties['min_size'] = 1 properties['max_size'] = 1 rsrc = self.create_stack(self.parsed)['my-group'] - resources = rsrc.get_instances() + resources = grouputils.get_members(rsrc) self.assertEqual(1, len(resources)) # Reduce the min size to 0, should complete without adjusting @@ -85,22 +85,22 @@ class AutoScalingGroupTest(common.HeatTestCase): rsrc.type(), props) scheduler.TaskRunner(rsrc.update, update_snippet)() - self.assertEqual(resources, rsrc.get_instances()) + self.assertEqual(resources, grouputils.get_members(rsrc)) # trigger adjustment to reduce to 0, there should be no more instances rsrc.adjust(-1) - self.assertEqual(0, len(rsrc.get_instances())) + self.assertEqual(0, grouputils.get_size(rsrc)) def test_scaling_group_suspend(self): rsrc = self.create_stack(self.parsed)['my-group'] - self.assertEqual(1, len(rsrc.get_instances())) + self.assertEqual(1, grouputils.get_size(rsrc)) self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) scheduler.TaskRunner(rsrc.suspend)() self.assertEqual((rsrc.SUSPEND, rsrc.COMPLETE), rsrc.state) def test_scaling_group_resume(self): rsrc = self.create_stack(self.parsed)['my-group'] - self.assertEqual(1, len(rsrc.get_instances())) + self.assertEqual(1, grouputils.get_size(rsrc)) self.assertEqual((rsrc.CREATE, rsrc.COMPLETE), rsrc.state) rsrc.state_set(rsrc.SUSPEND, rsrc.COMPLETE) for i in rsrc.nested().values(): @@ -120,7 +120,7 @@ class AutoScalingGroupTest(common.HeatTestCase): scheduler.TaskRunner(rsrc.create)) self.assertEqual((rsrc.CREATE, rsrc.FAILED), rsrc.state) - self.assertEqual(0, len(rsrc.get_instances())) + self.assertEqual(0, grouputils.get_size(rsrc)) def test_scaling_group_update_ok_maxsize(self): properties = self.parsed['resources']['my-group']['properties'] @@ -128,7 +128,7 @@ class AutoScalingGroupTest(common.HeatTestCase): properties['max_size'] = 3 rsrc = self.create_stack(self.parsed)['my-group'] - resources = rsrc.get_instances() + resources = grouputils.get_members(rsrc) self.assertEqual(1, len(resources)) # Reduce the max size to 2, should complete without adjusting @@ -138,7 +138,7 @@ class AutoScalingGroupTest(common.HeatTestCase): rsrc.type(), props) scheduler.TaskRunner(rsrc.update, update_snippet)() - self.assertEqual(resources, rsrc.get_instances()) + self.assertEqual(resources, grouputils.get_members(rsrc)) self.assertEqual(2, rsrc.properties['max_size']) def test_scaling_group_update_ok_minsize(self): @@ -147,7 +147,7 @@ class AutoScalingGroupTest(common.HeatTestCase): properties['max_size'] = 3 rsrc = self.create_stack(self.parsed)['my-group'] - self.assertEqual(1, len(rsrc.get_instances())) + self.assertEqual(1, grouputils.get_size(rsrc)) props = copy.copy(rsrc.properties.data) props['min_size'] = 2 @@ -155,7 +155,7 @@ class AutoScalingGroupTest(common.HeatTestCase): rsrc.type(), props) scheduler.TaskRunner(rsrc.update, update_snippet)() - self.assertEqual(2, len(rsrc.get_instances())) + self.assertEqual(2, grouputils.get_size(rsrc)) self.assertEqual(2, rsrc.properties['min_size']) def test_scaling_group_update_ok_desired(self): @@ -163,7 +163,7 @@ class AutoScalingGroupTest(common.HeatTestCase): properties['min_size'] = 1 properties['max_size'] = 3 rsrc = self.create_stack(self.parsed)['my-group'] - self.assertEqual(1, len(rsrc.get_instances())) + self.assertEqual(1, grouputils.get_size(rsrc)) props = copy.copy(rsrc.properties.data) props['desired_capacity'] = 2 @@ -171,14 +171,14 @@ class AutoScalingGroupTest(common.HeatTestCase): rsrc.type(), props) scheduler.TaskRunner(rsrc.update, update_snippet)() - self.assertEqual(2, len(rsrc.get_instances())) + self.assertEqual(2, grouputils.get_size(rsrc)) self.assertEqual(2, rsrc.properties['desired_capacity']) def test_scaling_group_update_ok_desired_remove(self): properties = self.parsed['resources']['my-group']['properties'] properties['desired_capacity'] = 2 rsrc = self.create_stack(self.parsed)['my-group'] - resources = rsrc.get_instances() + resources = grouputils.get_members(rsrc) self.assertEqual(2, len(resources)) props = copy.copy(rsrc.properties.data) @@ -187,7 +187,7 @@ class AutoScalingGroupTest(common.HeatTestCase): rsrc.type(), props) scheduler.TaskRunner(rsrc.update, update_snippet)() - self.assertEqual(resources, rsrc.get_instances()) + self.assertEqual(resources, grouputils.get_members(rsrc)) self.assertIsNone(rsrc.properties['desired_capacity']) def test_scaling_group_scale_up_failure(self): @@ -195,27 +195,27 @@ class AutoScalingGroupTest(common.HeatTestCase): mock_create = self.patchobject(generic_resource.ResourceWithProps, 'handle_create') rsrc = stack['my-group'] - self.assertEqual(1, len(rsrc.get_instances())) + self.assertEqual(1, grouputils.get_size(rsrc)) mock_create.side_effect = exception.Error('Bang') self.assertRaises(exception.Error, rsrc.adjust, 1) - self.assertEqual(1, len(rsrc.get_instances())) + self.assertEqual(1, grouputils.get_size(rsrc)) def test_scaling_group_truncate_adjustment(self): # Create initial group, 2 instances properties = self.parsed['resources']['my-group']['properties'] properties['desired_capacity'] = 2 rsrc = self.create_stack(self.parsed)['my-group'] - self.assertEqual(2, len(rsrc.get_instances())) + self.assertEqual(2, grouputils.get_size(rsrc)) rsrc.adjust(4) - self.assertEqual(5, len(rsrc.get_instances())) + self.assertEqual(5, grouputils.get_size(rsrc)) rsrc.adjust(-5) - self.assertEqual(1, len(rsrc.get_instances())) + self.assertEqual(1, grouputils.get_size(rsrc)) rsrc.adjust(0) - self.assertEqual(1, len(rsrc.get_instances())) + self.assertEqual(1, grouputils.get_size(rsrc)) def _do_test_scaling_group_percent(self, decrease, lowest, increase, create, highest): @@ -223,15 +223,15 @@ class AutoScalingGroupTest(common.HeatTestCase): properties = self.parsed['resources']['my-group']['properties'] properties['desired_capacity'] = 2 rsrc = self.create_stack(self.parsed)['my-group'] - self.assertEqual(2, len(rsrc.get_instances())) + self.assertEqual(2, grouputils.get_size(rsrc)) # reduce by decrease % rsrc.adjust(decrease, 'percentage_change_in_capacity') - self.assertEqual(lowest, len(rsrc.get_instances())) + self.assertEqual(lowest, grouputils.get_size(rsrc)) # raise by increase % rsrc.adjust(increase, 'percentage_change_in_capacity') - self.assertEqual(highest, len(rsrc.get_instances())) + self.assertEqual(highest, grouputils.get_size(rsrc)) def test_scaling_group_percent(self): self._do_test_scaling_group_percent(-50, 1, 200, 2, 3) @@ -267,17 +267,15 @@ class AutoScalingGroupTest(common.HeatTestCase): def test_attribute_current_size(self): rsrc = self.create_stack(self.parsed)['my-group'] - mock_instances = self.patchobject(asg.AutoScalingResourceGroup, - 'get_instances') - mock_instances.return_value = ['one', 'two', 'three'] + mock_instances = self.patchobject(grouputils, 'get_size') + mock_instances.return_value = 3 self.assertEqual(3, rsrc.FnGetAtt('current_size')) def test_attribute_current_size_with_path(self): rsrc = self.create_stack(self.parsed)['my-group'] - mock_instances = self.patchobject(asg.AutoScalingResourceGroup, - 'get_instances') - mock_instances.return_value = ['one', 'two', 'three', 'four'] + mock_instances = self.patchobject(grouputils, 'get_size') + mock_instances.return_value = 4 self.assertEqual(4, rsrc.FnGetAtt('current_size', 'name')) @@ -323,9 +321,9 @@ class HeatScalingGroupWithCFNScalingPolicyTest(common.HeatTestCase): stack = self.create_stack(self.parsed) scale_up = stack['scale-up'] group = stack['my-group'] - self.assertEqual(1, len(group.get_instances())) + self.assertEqual(1, grouputils.get_size(group)) scale_up.signal() - self.assertEqual(2, len(group.get_instances())) + self.assertEqual(2, grouputils.get_size(group)) def test_no_instance_list(self): """ @@ -382,9 +380,9 @@ class ScalingPolicyTest(common.HeatTestCase): self.assertEqual("1234", policy.FnGetRefId()) - self.assertEqual(1, len(group.get_instance_names())) + self.assertEqual(1, grouputils.get_size(group)) policy.signal() - self.assertEqual(2, len(group.get_instance_names())) + self.assertEqual(2, grouputils.get_size(group)) def test_signal_with_cooldown(self): self.parsed['resources']['my-policy']['properties']['cooldown'] = 60 @@ -393,19 +391,20 @@ class ScalingPolicyTest(common.HeatTestCase): policy = stack['my-policy'] group = stack['my-group'] - self.assertEqual(1, len(group.get_instance_names())) + self.assertEqual(1, grouputils.get_size(group)) policy.signal() - self.assertEqual(2, len(group.get_instance_names())) + self.assertEqual(2, grouputils.get_size(group)) policy.signal() # The second signal shouldn't have changed it because of cooldown - self.assertEqual(2, len(group.get_instance_names())) + self.assertEqual(2, grouputils.get_size(group)) past = timeutils.strtime(timeutils.utcnow() - datetime.timedelta(seconds=65)) policy.metadata_set({past: 'ChangeInCapacity : 1'}) policy.signal() - self.assertEqual(3, len(group.get_instance_names())) + + self.assertEqual(3, grouputils.get_size(group)) class RollingUpdatesTest(common.HeatTestCase): diff --git a/heat/tests/test_instance_group_update_policy.py b/heat/tests/test_instance_group_update_policy.py index f61dc50440..dd2ab3db3b 100644 --- a/heat/tests/test_instance_group_update_policy.py +++ b/heat/tests/test_instance_group_update_policy.py @@ -18,6 +18,7 @@ import mox from testtools.matchers import MatchesRegex from heat.common import exception +from heat.common import grouputils from heat.common import template_format from heat.engine.clients.os import nova from heat.engine import function @@ -406,8 +407,8 @@ class InstanceGroupTest(common.HeatTestCase): self.m.UnsetStubs() # saves info from initial list of instances for comparison later - init_instances = current_grp.get_instances() - init_names = current_grp.get_instance_names() + init_instances = grouputils.get_members(current_grp) + init_names = grouputils.get_member_names(current_grp) init_images = [(i.name, i.t['Properties']['ImageId']) for i in init_instances] init_flavors = [(i.name, i.t['Properties']['InstanceType']) @@ -444,8 +445,8 @@ class InstanceGroupTest(common.HeatTestCase): self.assertNotEqual(conf_name, updated_conf_name) # test that the group size are the same - updt_instances = updated_grp.get_instances() - updt_names = updated_grp.get_instance_names() + updt_instances = grouputils.get_members(updated_grp) + updt_names = grouputils.get_member_names(updated_grp) self.assertEqual(len(init_names), len(updt_names)) # test that the appropriate number of instance names are the same diff --git a/heat/tests/test_notifications.py b/heat/tests/test_notifications.py index 04fc782c43..115c5a3c58 100644 --- a/heat/tests/test_notifications.py +++ b/heat/tests/test_notifications.py @@ -15,6 +15,7 @@ import mock from oslo.utils import timeutils from heat.common import exception +from heat.common import grouputils from heat.common import template_format from heat.engine.clients.os import glance from heat.engine.clients.os import nova @@ -252,7 +253,7 @@ class ScaleNotificationTest(common.HeatTestCase): end_capacity=2, ) group.adjust(1) - self.assertEqual(2, len(group.get_instance_names())) + self.assertEqual(2, grouputils.get_size(group)) mock_notify.assert_has_calls(expected) expected = self.expected_notifs_calls(group, @@ -261,7 +262,7 @@ class ScaleNotificationTest(common.HeatTestCase): end_capacity=1, ) group.adjust(-1) - self.assertEqual(1, len(group.get_instance_names())) + self.assertEqual(1, grouputils.get_size(group)) mock_notify.assert_has_calls(expected) @mock.patch('heat.engine.notification.stack.send') @@ -280,6 +281,6 @@ class ScaleNotificationTest(common.HeatTestCase): start_capacity=1, with_error=err_message) self.assertRaises(exception.Error, group.adjust, 2) - self.assertEqual(1, len(group.get_instance_names())) + self.assertEqual(1, grouputils.get_size(group)) mock_error.assert_has_calls([error]) mock_info.assert_has_calls([info])