Browse Source
This patch propose to use heat tempest plugin for potential co-gating integration tests. These tests are consider as potential co-gating. And we now already maintain them in heat tempest plugin. This also disables all except two of the gate/test jobs, to enable us to land this series and stop the carnage. The jobs will be re-enabled once all of the duplicated tests have been eliminated. Change-Id: I55e204b72cd5a2876576852b10ad09f24d04beb4changes/69/528569/18
17 changed files with 5 additions and 858 deletions
@ -1,79 +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 uuid |
||||
|
||||
from zaqarclient.queues.v2 import client as zaqarclient |
||||
|
||||
from heat_integrationtests.common import test |
||||
from heat_integrationtests.functional import functional_base |
||||
|
||||
|
||||
class ZaqarEventSinkTest(functional_base.FunctionalTestsBase): |
||||
template = ''' |
||||
heat_template_version: "2013-05-23" |
||||
resources: |
||||
test_resource: |
||||
type: OS::Heat::TestResource |
||||
properties: |
||||
value: ok |
||||
''' |
||||
|
||||
def test_events(self): |
||||
queue_id = str(uuid.uuid4()) |
||||
environment = {'event_sinks': [{'type': 'zaqar-queue', |
||||
'target': queue_id, |
||||
'ttl': 120}]} |
||||
stack_identifier = self.stack_create( |
||||
template=self.template, |
||||
environment=environment) |
||||
stack_name, stack_id = stack_identifier.split('/') |
||||
conf = { |
||||
'auth_opts': { |
||||
'backend': 'keystone', |
||||
'options': { |
||||
'os_username': self.conf.username, |
||||
'os_password': self.conf.password, |
||||
'os_project_name': self.conf.project_name, |
||||
'os_auth_url': self.conf.auth_url, |
||||
'os_user_domain_id': self.conf.user_domain_id, |
||||
'os_project_domain_id': self.conf.project_domain_id, |
||||
'os_user_domain_name': self.conf.user_domain_name, |
||||
'os_project_domain_name': self.conf.project_domain_name |
||||
} |
||||
} |
||||
} |
||||
|
||||
zaqar = zaqarclient.Client(conf=conf) |
||||
queue = zaqar.queue(queue_id) |
||||
|
||||
def validate_messages(): |
||||
messages = list(queue.messages()) |
||||
if len(messages) < 4: |
||||
return False |
||||
|
||||
types = [m.body['type'] for m in messages] |
||||
self.assertEqual(['os.heat.event'] * 4, types) |
||||
resources = set([m.body['payload'][ |
||||
'resource_name'] for m in messages]) |
||||
self.assertEqual(set([stack_name, 'test_resource']), resources) |
||||
stack_ids = [m.body['payload']['stack_id'] for m in messages] |
||||
self.assertEqual([stack_id] * 4, stack_ids) |
||||
statuses = [m.body['payload']['resource_status'] for m in messages] |
||||
statuses.sort() |
||||
self.assertEqual(['COMPLETE', 'COMPLETE', |
||||
'IN_PROGRESS', 'IN_PROGRESS'], statuses) |
||||
actions = [m.body['payload']['resource_action'] for m in messages] |
||||
self.assertEqual(['CREATE'] * 4, actions) |
||||
return True |
||||
|
||||
self.assertTrue(test.call_until_true(20, 0, validate_messages)) |
@ -1,155 +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. |
||||
|
||||
|
||||
from heat_integrationtests.functional import functional_base |
||||
|
||||
|
||||
class LoadBalancerv2Test(functional_base.FunctionalTestsBase): |
||||
|
||||
create_template = ''' |
||||
heat_template_version: 2016-04-08 |
||||
parameters: |
||||
subnet: |
||||
type: string |
||||
resources: |
||||
loadbalancer: |
||||
type: OS::Neutron::LBaaS::LoadBalancer |
||||
properties: |
||||
description: aLoadBalancer |
||||
vip_subnet: { get_param: subnet } |
||||
listener: |
||||
type: OS::Neutron::LBaaS::Listener |
||||
properties: |
||||
description: aListener |
||||
loadbalancer: { get_resource: loadbalancer } |
||||
protocol: HTTP |
||||
protocol_port: 80 |
||||
connection_limit: 5555 |
||||
pool: |
||||
type: OS::Neutron::LBaaS::Pool |
||||
properties: |
||||
description: aPool |
||||
lb_algorithm: ROUND_ROBIN |
||||
protocol: HTTP |
||||
listener: { get_resource: listener } |
||||
poolmember: |
||||
type: OS::Neutron::LBaaS::PoolMember |
||||
properties: |
||||
address: 1.1.1.1 |
||||
pool: { get_resource: pool } |
||||
protocol_port: 1111 |
||||
subnet: { get_param: subnet } |
||||
weight: 255 |
||||
# pm2 |
||||
healthmonitor: |
||||
type: OS::Neutron::LBaaS::HealthMonitor |
||||
properties: |
||||
delay: 3 |
||||
type: HTTP |
||||
timeout: 3 |
||||
max_retries: 3 |
||||
pool: { get_resource: pool } |
||||
outputs: |
||||
loadbalancer: |
||||
value: { get_attr: [ loadbalancer, show ] } |
||||
pool: |
||||
value: { get_attr: [ pool, show ] } |
||||
poolmember: |
||||
value: { get_attr: [ poolmember, show ] } |
||||
listener: |
||||
value: { get_attr: [ listener, show ] } |
||||
healthmonitor: |
||||
value: { get_attr: [ healthmonitor, show ] } |
||||
''' |
||||
|
||||
add_member = ''' |
||||
poolmember2: |
||||
type: OS::Neutron::LBaaS::PoolMember |
||||
properties: |
||||
address: 2.2.2.2 |
||||
pool: { get_resource: pool } |
||||
protocol_port: 2222 |
||||
subnet: { get_param: subnet } |
||||
weight: 222 |
||||
''' |
||||
|
||||
def setUp(self): |
||||
super(LoadBalancerv2Test, self).setUp() |
||||
if not self.is_network_extension_supported('lbaasv2'): |
||||
self.skipTest('LBaasv2 extension not available, skipping') |
||||
|
||||
def test_create_update_loadbalancer(self): |
||||
parameters = { |
||||
'subnet': self.conf.fixed_subnet_name, |
||||
} |
||||
stack_identifier = self.stack_create(template=self.create_template, |
||||
parameters=parameters) |
||||
stack = self.client.stacks.get(stack_identifier) |
||||
output = self._stack_output(stack, 'loadbalancer') |
||||
self.assertEqual('ONLINE', output['operating_status']) |
||||
|
||||
template = self.create_template.replace('ROUND_ROBIN', 'SOURCE_IP') |
||||
template = template.replace('3', '6') |
||||
template = template.replace('255', '256') |
||||
template = template.replace('5555', '7777') |
||||
template = template.replace('aLoadBalancer', 'updatedLoadBalancer') |
||||
template = template.replace('aPool', 'updatedPool') |
||||
template = template.replace('aListener', 'updatedListener') |
||||
self.update_stack(stack_identifier, template=template, |
||||
parameters=parameters) |
||||
stack = self.client.stacks.get(stack_identifier) |
||||
|
||||
output = self._stack_output(stack, 'loadbalancer') |
||||
self.assertEqual('ONLINE', output['operating_status']) |
||||
self.assertEqual('updatedLoadBalancer', output['description']) |
||||
output = self._stack_output(stack, 'pool') |
||||
self.assertEqual('SOURCE_IP', output['lb_algorithm']) |
||||
self.assertEqual('updatedPool', output['description']) |
||||
output = self._stack_output(stack, 'poolmember') |
||||
self.assertEqual(256, output['weight']) |
||||
output = self._stack_output(stack, 'healthmonitor') |
||||
self.assertEqual(6, output['delay']) |
||||
self.assertEqual(6, output['timeout']) |
||||
self.assertEqual(6, output['max_retries']) |
||||
output = self._stack_output(stack, 'listener') |
||||
self.assertEqual(7777, output['connection_limit']) |
||||
self.assertEqual('updatedListener', output['description']) |
||||
|
||||
def test_add_delete_poolmember(self): |
||||
parameters = { |
||||
'subnet': self.conf.fixed_subnet_name, |
||||
} |
||||
stack_identifier = self.stack_create(template=self.create_template, |
||||
parameters=parameters) |
||||
stack = self.client.stacks.get(stack_identifier) |
||||
output = self._stack_output(stack, 'loadbalancer') |
||||
self.assertEqual('ONLINE', output['operating_status']) |
||||
output = self._stack_output(stack, 'pool') |
||||
self.assertEqual(1, len(output['members'])) |
||||
# add pool member |
||||
template = self.create_template.replace('# pm2', self.add_member) |
||||
self.update_stack(stack_identifier, template=template, |
||||
parameters=parameters) |
||||
stack = self.client.stacks.get(stack_identifier) |
||||
output = self._stack_output(stack, 'loadbalancer') |
||||
self.assertEqual('ONLINE', output['operating_status']) |
||||
output = self._stack_output(stack, 'pool') |
||||
self.assertEqual(2, len(output['members'])) |
||||
# delete pool member |
||||
self.update_stack(stack_identifier, template=self.create_template, |
||||
parameters=parameters) |
||||
stack = self.client.stacks.get(stack_identifier) |
||||
output = self._stack_output(stack, 'loadbalancer') |
||||
self.assertEqual('ONLINE', output['operating_status']) |
||||
output = self._stack_output(stack, 'pool') |
||||
self.assertEqual(1, len(output['members'])) |
@ -1,126 +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 json |
||||
import os |
||||
import subprocess |
||||
import sys |
||||
import tempfile |
||||
import time |
||||
|
||||
from oslo_utils import timeutils |
||||
|
||||
from heat_integrationtests.common import exceptions |
||||
from heat_integrationtests.functional import functional_base |
||||
|
||||
|
||||
class ZaqarSignalTransportTest(functional_base.FunctionalTestsBase): |
||||
server_template = ''' |
||||
heat_template_version: "2013-05-23" |
||||
|
||||
parameters: |
||||
flavor: |
||||
type: string |
||||
image: |
||||
type: string |
||||
network: |
||||
type: string |
||||
|
||||
resources: |
||||
server: |
||||
type: OS::Nova::Server |
||||
properties: |
||||
image: {get_param: image} |
||||
flavor: {get_param: flavor} |
||||
user_data_format: SOFTWARE_CONFIG |
||||
software_config_transport: ZAQAR_MESSAGE |
||||
networks: [{network: {get_param: network}}] |
||||
config: |
||||
type: OS::Heat::SoftwareConfig |
||||
properties: |
||||
config: echo 'foo' |
||||
deployment: |
||||
type: OS::Heat::SoftwareDeployment |
||||
properties: |
||||
config: {get_resource: config} |
||||
server: {get_resource: server} |
||||
signal_transport: ZAQAR_SIGNAL |
||||
|
||||
outputs: |
||||
data: |
||||
value: {get_attr: [deployment, deploy_stdout]} |
||||
''' |
||||
|
||||
conf_template = ''' |
||||
[zaqar] |
||||
user_id = %(user_id)s |
||||
password = %(password)s |
||||
project_id = %(project_id)s |
||||
auth_url = %(auth_url)s |
||||
queue_id = %(queue_id)s |
||||
''' |
||||
|
||||
def test_signal_queues(self): |
||||
parms = {'flavor': self.conf.minimal_instance_type, |
||||
'network': self.conf.fixed_network_name, |
||||
'image': self.conf.minimal_image_ref} |
||||
stack_identifier = self.stack_create( |
||||
parameters=parms, |
||||
template=self.server_template, |
||||
expected_status=None) |
||||
metadata = self.wait_for_deploy_metadata_set(stack_identifier) |
||||
config = metadata['os-collect-config']['zaqar'] |
||||
conf_content = self.conf_template % config |
||||
fd, temp_path = tempfile.mkstemp() |
||||
os.write(fd, conf_content.encode('utf-8')) |
||||
os.close(fd) |
||||
cmd = ['os-collect-config', '--one-time', |
||||
'--config-file=%s' % temp_path, 'zaqar'] |
||||
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) |
||||
stdout_value = proc.communicate()[0] |
||||
data = json.loads(stdout_value.decode('utf-8')) |
||||
self.assertEqual(config, data['zaqar']['os-collect-config']['zaqar']) |
||||
proc = subprocess.Popen(cmd, stdout=subprocess.PIPE) |
||||
stdout_value = proc.communicate()[0] |
||||
data = json.loads(stdout_value.decode('utf-8')) |
||||
|
||||
fd, temp_path = tempfile.mkstemp() |
||||
os.write(fd, |
||||
json.dumps(data['zaqar']['deployments'][0]).encode('utf-8')) |
||||
os.close(fd) |
||||
cmd = [sys.executable, self.conf.heat_config_notify_script, temp_path] |
||||
proc = subprocess.Popen(cmd, |
||||
stderr=subprocess.PIPE, |
||||
stdin=subprocess.PIPE) |
||||
proc.communicate( |
||||
json.dumps({'deploy_stdout': 'here!'}).encode('utf-8')) |
||||
self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE') |
||||
stack = self.client.stacks.get(stack_identifier) |
||||
self.assertEqual('here!', stack.outputs[0]['output_value']) |
||||
|
||||
def wait_for_deploy_metadata_set(self, stack): |
||||
build_timeout = self.conf.build_timeout |
||||
build_interval = self.conf.build_interval |
||||
|
||||
start = timeutils.utcnow() |
||||
while timeutils.delta_seconds(start, |
||||
timeutils.utcnow()) < build_timeout: |
||||
server_metadata = self.client.resources.metadata( |
||||
stack, 'server') |
||||
if server_metadata.get('deployments'): |
||||
return server_metadata |
||||
time.sleep(build_interval) |
||||
|
||||
message = ('Deployment resources failed to be created within ' |
||||
'the required time (%s s).' % |
||||
(build_timeout)) |
||||
raise exceptions.TimeoutException(message) |
@ -1,72 +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 json |
||||
|
||||
from keystoneclient.v3 import client as keystoneclient |
||||
from zaqarclient.queues.v2 import client as zaqarclient |
||||
|
||||
from heat_integrationtests.functional import functional_base |
||||
|
||||
|
||||
class ZaqarWaitConditionTest(functional_base.FunctionalTestsBase): |
||||
template = ''' |
||||
heat_template_version: "2013-05-23" |
||||
|
||||
resources: |
||||
wait_condition: |
||||
type: OS::Heat::WaitCondition |
||||
properties: |
||||
handle: {get_resource: wait_handle} |
||||
timeout: 120 |
||||
wait_handle: |
||||
type: OS::Heat::WaitConditionHandle |
||||
properties: |
||||
signal_transport: ZAQAR_SIGNAL |
||||
|
||||
outputs: |
||||
wait_data: |
||||
value: {'Fn::Select': ['data_id', {get_attr: [wait_condition, data]}]} |
||||
''' |
||||
|
||||
def test_signal_queues(self): |
||||
stack_identifier = self.stack_create( |
||||
template=self.template, |
||||
expected_status=None) |
||||
self._wait_for_resource_status(stack_identifier, 'wait_handle', |
||||
'CREATE_COMPLETE') |
||||
resource = self.client.resources.get(stack_identifier, 'wait_handle') |
||||
signal = json.loads(resource.attributes['signal']) |
||||
ks = keystoneclient.Client( |
||||
auth_url=signal['auth_url'], |
||||
user_id=signal['user_id'], |
||||
password=signal['password'], |
||||
project_id=signal['project_id']) |
||||
endpoint = ks.service_catalog.url_for( |
||||
service_type='messaging', endpoint_type='publicURL') |
||||
conf = { |
||||
'auth_opts': { |
||||
'backend': 'keystone', |
||||
'options': { |
||||
'os_auth_token': ks.auth_token, |
||||
'os_project_id': signal['project_id'] |
||||
} |
||||
} |
||||
} |
||||
|
||||
zaqar = zaqarclient.Client(endpoint, conf=conf) |
||||
|
||||
queue = zaqar.queue(signal['queue_id']) |
||||
queue.post({'body': {'data': 'here!', 'id': 'data_id'}, 'ttl': 600}) |
||||
self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE') |
||||
stack = self.client.stacks.get(stack_identifier) |
||||
self.assertEqual('here!', stack.outputs[0]['output_value']) |
@ -1,69 +0,0 @@
|
||||
heat_template_version: 2015-10-15 |
||||
|
||||
description: | |
||||
App server that is a member of Neutron Pool. |
||||
|
||||
parameters: |
||||
|
||||
image: |
||||
type: string |
||||
|
||||
flavor: |
||||
type: string |
||||
|
||||
net: |
||||
type: string |
||||
|
||||
sec_group: |
||||
type: string |
||||
|
||||
pool: |
||||
type: string |
||||
|
||||
app_port: |
||||
type: number |
||||
|
||||
timeout: |
||||
type: number |
||||
|
||||
subnet: |
||||
type: string |
||||
|
||||
resources: |
||||
|
||||
config: |
||||
type: OS::Test::WebAppConfig |
||||
properties: |
||||
app_port: { get_param: app_port } |
||||
wc_curl_cli: { get_attr: [ handle, curl_cli ] } |
||||
|
||||
server: |
||||
type: OS::Nova::Server |
||||
properties: |
||||
image: { get_param: image } |
||||
flavor: { get_param: flavor } |
||||
networks: |
||||
- network: { get_param: net } |
||||
security_groups: |
||||
- { get_param: sec_group } |
||||
user_data_format: RAW |
||||
user_data: { get_resource: config } |
||||
|
||||
handle: |
||||
type: OS::Heat::WaitConditionHandle |
||||
|
||||
waiter: |
||||
type: OS::Heat::WaitCondition |
||||
depends_on: server |
||||
properties: |
||||
timeout: { get_param: timeout } |
||||
handle: { get_resource: handle } |
||||
|
||||
pool_member: |
||||
type: OS::Neutron::LBaaS::PoolMember |
||||
depends_on: waiter |
||||
properties: |
||||
address: { get_attr: [ server, networks, { get_param: net }, 0 ] } |
||||
pool: { get_param: pool } |
||||
protocol_port: { get_param: app_port } |
||||
subnet: { get_param: subnet } |
@ -1,37 +0,0 @@
|
||||
heat_template_version: 2013-05-23 |
||||
parameters: |
||||
metric_id: |
||||
type: string |
||||
resources: |
||||
asg: |
||||
type: OS::Heat::AutoScalingGroup |
||||
properties: |
||||
max_size: 5 |
||||
min_size: 1 |
||||
resource: |
||||
type: OS::Heat::RandomString |
||||
scaleup_policy: |
||||
type: OS::Heat::ScalingPolicy |
||||
properties: |
||||
adjustment_type: change_in_capacity |
||||
auto_scaling_group_id: {get_resource: asg} |
||||
cooldown: 0 |
||||
scaling_adjustment: 1 |
||||
alarm: |
||||
type: OS::Aodh::GnocchiAggregationByMetricsAlarm |
||||
properties: |
||||
metrics: |
||||
- {get_param: metric_id} |
||||
comparison_operator: ge |
||||
evaluation_periods: 1 |
||||
granularity: 60 |
||||
aggregation_method: mean |
||||
threshold: 10 |
||||
alarm_actions: |
||||
- str_replace: |
||||
template: trust+url |
||||
params: |
||||
url: {get_attr: [scaleup_policy, signal_url]} |
||||
outputs: |
||||
asg_size: |
||||
value: {get_attr: [asg, current_size]} |
@ -1,116 +0,0 @@
|
||||
heat_template_version: 2015-04-30 |
||||
|
||||
description: | |
||||
Template which tests Neutron load balancing requests to members of |
||||
Heat AutoScalingGroup. This uses LBaas V2. |
||||
Instances must be running some webserver on a given app_port |
||||
producing HTTP response that is different between servers |
||||
but stable over time for given server. |
||||
|
||||
parameters: |
||||
flavor: |
||||
type: string |
||||
image: |
||||
type: string |
||||
net: |
||||
type: string |
||||
subnet: |
||||
type: string |
||||
public_net: |
||||
type: string |
||||
app_port: |
||||
type: number |
||||
default: 8080 |
||||
lb_port: |
||||
type: number |
||||
default: 80 |
||||
timeout: |
||||
type: number |
||||
default: 600 |
||||
|
||||
resources: |
||||
|
||||
sec_group: |
||||
type: OS::Neutron::SecurityGroup |
||||
properties: |
||||
rules: |
||||
- remote_ip_prefix: 0.0.0.0/0 |
||||
protocol: tcp |
||||
port_range_min: { get_param: app_port } |
||||
port_range_max: { get_param: app_port } |
||||
|
||||
asg: |
||||
type: OS::Heat::AutoScalingGroup |
||||
properties: |
||||
desired_capacity: 1 |
||||
max_size: 2 |
||||
min_size: 1 |
||||
resource: |
||||
type: OS::Test::NeutronAppServer |
||||
properties: |
||||
image: { get_param: image } |
||||
flavor: { get_param: flavor } |
||||
net: { get_param: net} |
||||
sec_group: { get_resource: sec_group } |
||||
app_port: { get_param: app_port } |
||||
pool: { get_resource: pool } |
||||
subnet: { get_param: subnet } |
||||
timeout: { get_param: timeout } |
||||
|
||||
scale_up: |
||||
type: OS::Heat::ScalingPolicy |
||||
properties: |
||||
adjustment_type: change_in_capacity |
||||
auto_scaling_group_id: { get_resource: asg } |
||||
scaling_adjustment: 1 |
||||
|
||||
scale_down: |
||||
type: OS::Heat::ScalingPolicy |
||||
properties: |
||||
adjustment_type: change_in_capacity |
||||
auto_scaling_group_id: { get_resource: asg } |
||||
scaling_adjustment: -1 |
||||
|
||||
health_monitor: |
||||
type: OS::Neutron::LBaaS::HealthMonitor |
||||
properties: |
||||
delay: 3 |
||||
type: HTTP |
||||
timeout: 3 |
||||
max_retries: 3 |
||||
pool: { get_resource: pool } |
||||
|
||||
pool: |
||||
type: OS::Neutron::LBaaS::Pool |
||||
properties: |
||||
lb_algorithm: ROUND_ROBIN |
||||
protocol: HTTP |
||||
listener: { get_resource: listener } |
||||
|
||||
listener: |
||||
type: OS::Neutron::LBaaS::Listener |
||||
properties: |
||||
loadbalancer: { get_resource: loadbalancer } |
||||
protocol: HTTP |
||||
protocol_port: { get_param: lb_port } |
||||
|
||||
loadbalancer: |
||||
type: OS::Neutron::LBaaS::LoadBalancer |
||||
properties: |
||||
vip_subnet: { get_param: subnet } |
||||
|
||||
floating_ip: |
||||
type: OS::Neutron::FloatingIP |
||||
properties: |
||||
floating_network: { get_param: public_net } |
||||
port_id: { get_attr: [loadbalancer, vip_port_id] } |
||||
|
||||
outputs: |
||||
lburl: |
||||
description: URL of the loadbalanced app |
||||
value: |
||||
str_replace: |
||||
template: http://IP_ADDRESS:PORT |
||||
params: |
||||
IP_ADDRESS: { get_attr: [ floating_ip, floating_ip_address ] } |
||||
PORT: { get_param: lb_port } |
@ -1,64 +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 datetime |
||||
from heat.common import timeutils |
||||
from oslo_log import log as logging |
||||
|
||||
from heat_integrationtests.common import test |
||||
from heat_integrationtests.scenario import scenario_base |
||||
|
||||
LOG = logging.getLogger(__name__) |
||||
|
||||
|
||||
class AodhAlarmTest(scenario_base.ScenarioTestsBase): |
||||
"""Class is responsible for testing of aodh usage.""" |
||||
def setUp(self): |
||||
super(AodhAlarmTest, self).setUp() |
||||
self.template = self._load_template(__file__, |
||||
'test_aodh_alarm.yaml', |
||||
'templates') |
||||
|
||||
def check_instance_count(self, stack_identifier, expected): |
||||
stack = self.client.stacks.get(stack_identifier) |
||||
actual = self._stack_output(stack, 'asg_size') |
||||
if actual != expected: |
||||
LOG.warning('check_instance_count exp:%d, act:%s' % (expected, |
||||
actual)) |
||||
return actual == expected |
||||
|
||||
def test_alarm(self): |
||||
"""Confirm we can create an alarm and trigger it.""" |
||||
# create metric |
||||
metric = self.metric_client.metric.create({ |
||||
'name': 'my_metric', |
||||
'archive_policy_name': 'high', |
||||
}) |
||||
|
||||
# create the stack |
||||
parameters = {'metric_id': metric['id']} |
||||
stack_identifier = self.stack_create(template=self.template, |
||||
parameters=parameters) |
||||
measures = [{'timestamp': timeutils.isotime(datetime.datetime.now()), |
||||
'value': 100}, {'timestamp': timeutils.isotime( |
||||
datetime.datetime.now() + datetime.timedelta( |
||||
minutes=1)), 'value': 100}] |
||||
# send measures(should cause the alarm to fire) |
||||
self.metric_client.metric.add_measures(metric['id'], measures) |
||||
|
||||
# confirm we get a scaleup. |
||||
# Note: there is little point waiting more than 60s+time to scale up. |
||||
self.assertTrue(test.call_until_true( |
||||
120, 2, self.check_instance_count, stack_identifier, 2)) |
||||
|
||||
# cleanup metric |
||||
self.metric_client.metric.delete(metric['id']) |
@ -1,110 +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 time |
||||
|
||||
import requests |
||||
|
||||
from heat_integrationtests.common import test |
||||
from heat_integrationtests.scenario import scenario_base |
||||
|
||||
|
||||
class AutoscalingLoadBalancerv2Test(scenario_base.ScenarioTestsBase): |
||||
"""The class is responsible for testing ASG + LBv2 scenario. |
||||
|
||||
The very common use case tested is an autoscaling group |
||||
of some web application servers behind a loadbalancer. |
||||
""" |
||||
|
||||
def setUp(self): |
||||
super(AutoscalingLoadBalancerv2Test, self).setUp() |
||||
self.template_name = 'test_autoscaling_lbv2_neutron.yaml' |
||||
self.app_server_template_name = 'app_server_lbv2_neutron.yaml' |
||||
self.webapp_template_name = 'netcat-webapp.yaml' |
||||
if not self.is_network_extension_supported('lbaasv2'): |
||||
self.skipTest('LBaasv2 extension not available, skipping') |
||||
|
||||
def check_num_responses(self, url, expected_num, retries=20): |
||||
resp = set() |
||||
for count in range(retries): |
||||
time.sleep(2) |
||||
try: |
||||
r = requests.get(url, verify=self.verify_cert) |
||||
except requests.exceptions.ConnectionError: |
||||
# The LB may not be up yet, let's retry |
||||
continue |
||||
# skip unsuccessful requests |
||||
if r.status_code == 200: |
||||
resp.add(r.text) |
||||
if len(resp) == expected_num: |
||||
break |
||||
self.assertEqual(expected_num, len(resp)) |
||||
|
||||
def test_autoscaling_loadbalancer_neutron(self): |
||||
"""Check work of AutoScaing and Neutron LBaaS v2 resource in Heat. |
||||
|
||||
The scenario is the following: |
||||
1. Launch a stack with a load balancer and autoscaling group |
||||
of one server, wait until stack create is complete. |
||||
2. Check that there is only one distinctive response from |
||||
loadbalanced IP. |
||||
3. Signal the scale_up policy, wait until all resources in |
||||
autoscaling group are complete. |
||||
4. Check that now there are two distinctive responses from |
||||
loadbalanced IP. |
||||
""" |
||||
|
||||
parameters = { |
||||
'flavor': self.conf.minimal_instance_type, |
||||
'image': self.conf.minimal_image_ref, |
||||
'net': self.conf.fixed_network_name, |
||||
'subnet': self.conf.fixed_subnet_name, |
||||
'public_net': self.conf.floating_network_name |
||||
} |
||||
|
||||
app_server_template = self._load_template( |
||||
__file__, self.app_server_template_name, self.sub_dir |
||||
) |
||||
webapp_template = self._load_template( |
||||
__file__, self.webapp_template_name, self.sub_dir |
||||
) |
||||
files = {'appserver.yaml': app_server_template, |
||||
'webapp.yaml': webapp_template} |
||||
env = {'resource_registry': |
||||
{'OS::Test::NeutronAppServer': 'appserver.yaml', |
||||
'OS::Test::WebAppConfig': 'webapp.yaml'}} |
||||
|
||||
# Launch stack |
||||
sid = self.launch_stack( |
||||
template_name=self.template_name, |
||||
parameters=parameters, |
||||
files=files, |
||||
environment=env |
||||
) |
||||
stack = self.client.stacks.get(sid) |
||||
lb_url = self._stack_output(stack, 'lburl') |
||||
# Check number of distinctive responces, must be 1 |
||||
self.check_num_responses(lb_url, 1) |
||||
|
||||
# Signal the scaling hook |
||||
self.client.resources.signal(sid, 'scale_up') |
||||
|
||||
# Wait for AutoScalingGroup update to finish |
||||
asg = self.client.resources.get(sid, 'asg') |
||||
test.call_until_true(self.conf.build_timeout, |
||||
self.conf.build_interval, |
||||
self.check_autoscale_complete, |
||||
asg.physical_resource_id, 2, sid, 'scale_up') |
||||
|
||||
# Check number of distinctive responses, must now be 2 |
||||
self.check_num_responses(lb_url, 2) |
Loading…
Reference in new issue