Test auto-scaling for neutron
Test does the following: 1. Creates an instances with LoadBalancer 2. Increased desired capacity 3. Check that LB resources has been increased Test replaces test_neutron_autoscaling unittest. Part of blueprint decouple-nested. Change-Id: I3b4924bfe3e427ffc77b23e0a3b6b08accfa39eb
This commit is contained in:
parent
2c35c47dce
commit
c1b63d1eef
@ -1,323 +0,0 @@
|
||||
#
|
||||
# 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 copy
|
||||
import uuid
|
||||
|
||||
import mox
|
||||
from neutronclient.v2_0 import client as neutronclient
|
||||
from oslo.config import cfg
|
||||
|
||||
from heat.common import template_format
|
||||
from heat.db import api as db_api
|
||||
from heat.engine.clients.os import nova
|
||||
from heat.engine import environment
|
||||
from heat.engine import parser
|
||||
from heat.engine.resources import instance
|
||||
from heat.engine import template
|
||||
from heat.tests import common
|
||||
from heat.tests import utils
|
||||
from heat.tests.v1_1 import fakes as fakes_v1_1
|
||||
|
||||
|
||||
as_template = '''
|
||||
{
|
||||
"AWSTemplateFormatVersion" : "2010-09-09",
|
||||
"Description" : "AutoScaling Test",
|
||||
"Parameters" : {
|
||||
"ImageId": {"Type": "String"},
|
||||
"KeyName": {"Type": "String"},
|
||||
"SubnetId": {"Type": "String"}
|
||||
},
|
||||
"Resources" : {
|
||||
"SvrGrp" : {
|
||||
"Type" : "AWS::AutoScaling::AutoScalingGroup",
|
||||
"Properties" : {
|
||||
"AvailabilityZones" : ["nova"],
|
||||
"LaunchConfigurationName" : { "Ref" : "LaunchConfig" },
|
||||
"MinSize" : "1",
|
||||
"MaxSize" : "5",
|
||||
"DesiredCapacity": "1",
|
||||
"VPCZoneIdentifier": [ { "Ref": "SubnetId" } ],
|
||||
"LoadBalancerNames" : [ { "Ref" : "ElasticLoadBalancer" } ]
|
||||
}
|
||||
},
|
||||
"myMonitor": {
|
||||
"Type": "OS::Neutron::HealthMonitor",
|
||||
"Properties": {
|
||||
"type": "HTTP",
|
||||
"delay": 3,
|
||||
"max_retries": 5,
|
||||
"timeout": 10
|
||||
}
|
||||
},
|
||||
"myPool": {
|
||||
"Type": "OS::Neutron::Pool",
|
||||
"Properties": {
|
||||
"description": "Test Pool",
|
||||
"lb_method": "ROUND_ROBIN",
|
||||
"monitors": [ { "Ref": "myMonitor" } ],
|
||||
"name": "Test_Pool",
|
||||
"protocol": "HTTP",
|
||||
"subnet_id": { "Ref": "SubnetId" },
|
||||
"vip": {
|
||||
"description": "Test VIP",
|
||||
"connection_limit": 1000,
|
||||
"address": "10.0.3.121",
|
||||
"protocol_port": 80,
|
||||
"name": "test_vip"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ElasticLoadBalancer" : {
|
||||
'Type': 'OS::Neutron::LoadBalancer',
|
||||
'Properties': {
|
||||
'protocol_port': 8080,
|
||||
'pool_id': { "Ref": "myPool" }
|
||||
}
|
||||
},
|
||||
"LaunchConfig" : {
|
||||
"Type" : "AWS::AutoScaling::LaunchConfiguration",
|
||||
"Properties": {
|
||||
"ImageId" : {"Ref": "ImageId"},
|
||||
"InstanceType" : "bar",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
|
||||
class AutoScalingTest(common.HeatTestCase):
|
||||
params = {'KeyName': 'test', 'ImageId': 'foo'}
|
||||
|
||||
def setUp(self):
|
||||
super(AutoScalingTest, self).setUp()
|
||||
|
||||
self.ctx = utils.dummy_context()
|
||||
self.fc = fakes_v1_1.FakeClient()
|
||||
|
||||
cfg.CONF.set_default('heat_waitcondition_server_url',
|
||||
'http://server.test:8000/v1/waitcondition')
|
||||
|
||||
self.stub_keystoneclient()
|
||||
|
||||
self.m.StubOutWithMock(neutronclient.Client,
|
||||
'create_health_monitor')
|
||||
self.m.StubOutWithMock(neutronclient.Client,
|
||||
'associate_health_monitor')
|
||||
self.m.StubOutWithMock(neutronclient.Client, 'create_pool')
|
||||
self.m.StubOutWithMock(neutronclient.Client, 'create_vip')
|
||||
self.m.StubOutWithMock(neutronclient.Client, 'show_pool')
|
||||
self.m.StubOutWithMock(neutronclient.Client, 'show_vip')
|
||||
self.m.StubOutWithMock(neutronclient.Client, 'create_member')
|
||||
self.m.StubOutWithMock(neutronclient.Client, 'list_members')
|
||||
|
||||
self.m.StubOutWithMock(nova.NovaClientPlugin, 'server_to_ipaddress')
|
||||
self.m.StubOutWithMock(parser.Stack, 'validate')
|
||||
|
||||
self.m.StubOutWithMock(instance.Instance, 'handle_create')
|
||||
self.m.StubOutWithMock(instance.Instance, 'check_create_complete')
|
||||
|
||||
def test_lb(self):
|
||||
|
||||
tmpl = template_format.parse(as_template)
|
||||
|
||||
network_body = {
|
||||
"network": {
|
||||
"id": str(uuid.uuid4()),
|
||||
"name": "testnet",
|
||||
"admin_state_up": True
|
||||
}
|
||||
}
|
||||
subnet_body = {
|
||||
"subnet": {
|
||||
"name": "testsubnet",
|
||||
"id": str(uuid.uuid4()),
|
||||
"network_id": network_body['network']['id'],
|
||||
"ip_version": 4,
|
||||
"cidr": "10.0.3.0/24",
|
||||
"allocation_pools": [
|
||||
{
|
||||
"start": "10.0.3.20",
|
||||
"end": "10.0.3.150"
|
||||
}
|
||||
],
|
||||
"gateway_ip": "10.0.3.1"
|
||||
}
|
||||
}
|
||||
|
||||
self.params["SubnetId"] = subnet_body['subnet']['id']
|
||||
mon_block = {
|
||||
'health_monitor': tmpl['Resources']['myMonitor']['Properties']
|
||||
}
|
||||
mon_block['health_monitor']['admin_state_up'] = True
|
||||
mon_ret_block = copy.deepcopy(mon_block)
|
||||
mon_ret_block['health_monitor']['id'] = str(uuid.uuid4())
|
||||
mon_ret_block['health_monitor']['status'] = 'ACTIVE'
|
||||
|
||||
pool_block = {'pool': {}}
|
||||
tmp_pool_block = tmpl['Resources']['myPool']['Properties']
|
||||
for val in ['lb_method', 'protocol', 'name', 'description']:
|
||||
pool_block['pool'][val] = tmp_pool_block[val]
|
||||
pool_block['pool']['admin_state_up'] = True
|
||||
pool_block['pool']['subnet_id'] = self.params['SubnetId']
|
||||
pool_block['pool']['admin_state_up'] = True
|
||||
pool_ret_block = copy.deepcopy(pool_block)
|
||||
pool_ret_block['pool']['id'] = str(uuid.uuid4())
|
||||
pool_ret_block['pool']['status'] = 'ACTIVE'
|
||||
|
||||
tmp_vip_block = tmp_pool_block.pop('vip')
|
||||
vip_block = {
|
||||
'vip': {
|
||||
'protocol': pool_block['pool']['protocol'],
|
||||
'description': tmp_vip_block['description'],
|
||||
'admin_state_up': True,
|
||||
'subnet_id': self.params['SubnetId'],
|
||||
'connection_limit': tmp_vip_block['connection_limit'],
|
||||
'pool_id': pool_ret_block['pool']['id'],
|
||||
'address': tmp_vip_block['address'],
|
||||
'protocol_port': tmp_vip_block['protocol_port'],
|
||||
'name': tmp_vip_block['name']
|
||||
}
|
||||
}
|
||||
vip_ret_block = copy.deepcopy(vip_block)
|
||||
vip_ret_block['vip']['id'] = str(uuid.uuid4())
|
||||
vip_ret_block['vip']['status'] = 'ACTIVE'
|
||||
|
||||
membera_block = {
|
||||
'member': {
|
||||
'protocol_port': 8080,
|
||||
'pool_id': pool_ret_block['pool']['id'],
|
||||
'address': '1.2.3.4'
|
||||
}
|
||||
}
|
||||
membera_ret_block = copy.deepcopy(membera_block)
|
||||
membera_ret_block['member']['id'] = str(uuid.uuid4())
|
||||
|
||||
memberb_block = {
|
||||
'member': {
|
||||
'protocol_port': 8080,
|
||||
'pool_id': pool_ret_block['pool']['id'],
|
||||
'address': '1.2.3.5'
|
||||
}
|
||||
}
|
||||
memberb_ret_block = copy.deepcopy(memberb_block)
|
||||
memberb_ret_block['member']['id'] = str(uuid.uuid4())
|
||||
|
||||
memberc_block = {
|
||||
'member': {
|
||||
'protocol_port': 8080,
|
||||
'pool_id': pool_ret_block['pool']['id'],
|
||||
'address': '1.2.3.6'
|
||||
}
|
||||
}
|
||||
memberc_ret_block = copy.deepcopy(memberc_block)
|
||||
memberc_ret_block['member']['id'] = str(uuid.uuid4())
|
||||
|
||||
neutronclient.Client.create_health_monitor(
|
||||
mon_block).AndReturn(mon_ret_block)
|
||||
|
||||
neutronclient.Client.create_pool(
|
||||
pool_block).AndReturn(pool_ret_block)
|
||||
|
||||
neutronclient.Client.associate_health_monitor(
|
||||
pool_ret_block['pool']['id'],
|
||||
{'health_monitor': {
|
||||
'id': mon_ret_block['health_monitor']['id']
|
||||
}}).AndReturn(None)
|
||||
|
||||
neutronclient.Client.create_vip(
|
||||
vip_block).AndReturn(vip_ret_block)
|
||||
|
||||
neutronclient.Client.show_pool(
|
||||
pool_ret_block['pool']['id']).AndReturn(pool_ret_block)
|
||||
|
||||
neutronclient.Client.show_vip(
|
||||
vip_ret_block['vip']['id']).AndReturn(vip_ret_block)
|
||||
|
||||
parser.Stack.validate()
|
||||
instid = str(uuid.uuid4())
|
||||
instance.Instance.handle_create().AndReturn(instid)
|
||||
instance.Instance.check_create_complete(
|
||||
mox.IgnoreArg()).AndReturn(False)
|
||||
instance.Instance.check_create_complete(
|
||||
mox.IgnoreArg()).AndReturn(True)
|
||||
self.stub_ImageConstraint_validate()
|
||||
self.stub_FlavorConstraint_validate()
|
||||
nova.NovaClientPlugin.server_to_ipaddress(
|
||||
mox.IgnoreArg()).AndReturn('1.2.3.4')
|
||||
|
||||
neutronclient.Client.create_member(
|
||||
membera_block).AndReturn(membera_ret_block)
|
||||
|
||||
# Start of update
|
||||
parser.Stack.validate()
|
||||
instid = str(uuid.uuid4())
|
||||
instance.Instance.handle_create().AndReturn(instid)
|
||||
instance.Instance.check_create_complete(
|
||||
mox.IgnoreArg()).AndReturn(False)
|
||||
instance.Instance.check_create_complete(
|
||||
mox.IgnoreArg()).AndReturn(True)
|
||||
|
||||
instid = str(uuid.uuid4())
|
||||
instance.Instance.handle_create().AndReturn(instid)
|
||||
instance.Instance.check_create_complete(
|
||||
mox.IgnoreArg()).AndReturn(False)
|
||||
instance.Instance.check_create_complete(
|
||||
mox.IgnoreArg()).AndReturn(True)
|
||||
|
||||
nova.NovaClientPlugin.server_to_ipaddress(
|
||||
mox.IgnoreArg()).AndReturn('1.2.3.5')
|
||||
|
||||
neutronclient.Client.create_member(
|
||||
memberb_block).AndReturn(memberb_ret_block)
|
||||
|
||||
nova.NovaClientPlugin.server_to_ipaddress(
|
||||
mox.IgnoreArg()).AndReturn('1.2.3.6')
|
||||
|
||||
neutronclient.Client.create_member(
|
||||
memberc_block).AndReturn(memberc_ret_block)
|
||||
|
||||
self.m.ReplayAll()
|
||||
|
||||
# Start of stack create
|
||||
env = {'parameters': self.params}
|
||||
tmpl = template_format.parse(as_template)
|
||||
|
||||
stack = parser.Stack(self.ctx, 'update_test_stack',
|
||||
template.Template(tmpl),
|
||||
environment.Environment(env))
|
||||
|
||||
stack.store()
|
||||
stack.create()
|
||||
self.assertEqual((parser.Stack.CREATE, parser.Stack.COMPLETE),
|
||||
stack.state)
|
||||
|
||||
# Start of stack update
|
||||
stack2 = parser.Stack.load(self.ctx, stack_id=stack.id)
|
||||
|
||||
tmpl2 = copy.deepcopy(tmpl)
|
||||
tmpl2['Resources']['SvrGrp']['Properties']['DesiredCapacity'] = '3'
|
||||
|
||||
update_stack = parser.Stack(self.ctx, 'update_test_stack',
|
||||
template.Template(tmpl2),
|
||||
environment.Environment(env))
|
||||
stack2.update(update_stack)
|
||||
self.assertEqual((parser.Stack.UPDATE, parser.Stack.COMPLETE),
|
||||
stack2.state)
|
||||
|
||||
members = db_api.resource_data_get_all(stack['ElasticLoadBalancer'])
|
||||
self.assertEqual(3, len(members.keys()))
|
||||
|
||||
self.m.VerifyAll()
|
@ -68,6 +68,9 @@ IntegrationTestGroup = [
|
||||
cfg.StrOpt('fixed_network_name',
|
||||
default='private',
|
||||
help="Visible fixed network name "),
|
||||
cfg.StrOpt('fixed_subnet_name',
|
||||
default='private-subnet',
|
||||
help="Visible fixed sub-network name "),
|
||||
cfg.IntOpt('ssh_timeout',
|
||||
default=300,
|
||||
help="Timeout in seconds to wait for authentication to "
|
||||
|
@ -23,6 +23,9 @@
|
||||
# Visible fixed network name (string value)
|
||||
#fixed_network_name = private
|
||||
|
||||
# Visible fixed sub-network name (string value)
|
||||
#fixed_subnet_name = private-subnet
|
||||
|
||||
# Name of image to use for tests which boot servers. (string value)
|
||||
#image_ref = <None>
|
||||
|
||||
|
124
heat_integrationtests/scenario/test_neutron_autoscaling.py
Normal file
124
heat_integrationtests/scenario/test_neutron_autoscaling.py
Normal file
@ -0,0 +1,124 @@
|
||||
# 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.
|
||||
|
||||
from heat_integrationtests.common import test
|
||||
|
||||
test_template = '''
|
||||
heat_template_version: 2014-10-16
|
||||
|
||||
description: Auto-scaling Test
|
||||
|
||||
parameters:
|
||||
image_id:
|
||||
type: string
|
||||
label: Image ID
|
||||
description: Image ID from configurations
|
||||
capacity:
|
||||
type: string
|
||||
label: Capacity
|
||||
description: Auto-scaling group desired capacity
|
||||
fixed_subnet_name:
|
||||
type: string
|
||||
label: fixed subnetwork ID
|
||||
description: subnetwork ID used for autoscaling
|
||||
instance_type:
|
||||
type: string
|
||||
label: instance_type
|
||||
description: type of instance to launch
|
||||
|
||||
resources:
|
||||
test_pool:
|
||||
type: OS::Neutron::Pool
|
||||
properties:
|
||||
description: Test Pool
|
||||
lb_method: ROUND_ROBIN
|
||||
name: test_pool
|
||||
protocol: HTTP
|
||||
subnet: { get_param: fixed_subnet_name }
|
||||
vip: {
|
||||
"description": "Test VIP",
|
||||
"protocol_port": 80,
|
||||
"name": "test_vip"
|
||||
}
|
||||
load_balancer:
|
||||
type: OS::Neutron::LoadBalancer
|
||||
properties:
|
||||
protocol_port: 80
|
||||
pool_id: { get_resource: test_pool }
|
||||
launch_config:
|
||||
type: AWS::AutoScaling::LaunchConfiguration
|
||||
properties:
|
||||
ImageId: { get_param: image_id }
|
||||
InstanceType: { get_param: instance_type }
|
||||
server_group:
|
||||
type: AWS::AutoScaling::AutoScalingGroup
|
||||
properties:
|
||||
AvailabilityZones : ["nova"]
|
||||
LaunchConfigurationName : { get_resource : launch_config }
|
||||
MinSize : 1
|
||||
MaxSize : 5
|
||||
DesiredCapacity: { get_param: capacity }
|
||||
LoadBalancerNames : [ { get_resource : load_balancer } ]
|
||||
'''
|
||||
|
||||
|
||||
class NeutronAutoscalingTest(test.HeatIntegrationTest):
|
||||
""""
|
||||
The class is responsible for testing of neutron resources autoscaling.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(NeutronAutoscalingTest, self).setUp()
|
||||
self.client = self.orchestration_client
|
||||
if not self.conf.minimal_image_ref:
|
||||
raise self.skipException("No minimal image configured to test")
|
||||
if not self.conf.instance_type:
|
||||
raise self.skipException("No flavor configured to test")
|
||||
if not self.conf.fixed_subnet_name:
|
||||
raise self.skipException("No sub-network configured to test")
|
||||
|
||||
def test_neutron_autoscaling(self):
|
||||
"""
|
||||
Check autoscaling of load balancer members in heat.
|
||||
|
||||
The alternative scenario is the following:
|
||||
1. Initialize environment variables.
|
||||
2. Create a stack with a load balancer.
|
||||
3. Check that the load balancer created
|
||||
one load balancer member for stack.
|
||||
4. Update stack definition: increase desired capacity of stack.
|
||||
5. Check that number of members in load balancer was increased.
|
||||
"""
|
||||
|
||||
# Init env variables
|
||||
env = {'parameters': {"image_id": self.conf.minimal_image_ref,
|
||||
"capacity": "1",
|
||||
"instance_type": self.conf.instance_type,
|
||||
"fixed_subnet_name":
|
||||
self.conf.fixed_subnet_name,
|
||||
}}
|
||||
|
||||
# Create stack
|
||||
stack_id = self.stack_create(template=test_template,
|
||||
environment=env)
|
||||
|
||||
members = self.network_client.list_members()
|
||||
self.assertEqual(1, len(members["members"]))
|
||||
|
||||
# Increase desired capacity and update the stack
|
||||
env["parameters"]["capacity"] = "2"
|
||||
self.update_stack(stack_id,
|
||||
template=test_template,
|
||||
environment=env)
|
||||
|
||||
upd_members = self.network_client.list_members()
|
||||
self.assertEqual(2, len(upd_members["members"]))
|
Loading…
Reference in New Issue
Block a user