5b65a7e652
- Decorator idempotent_id() in tempest.test is deprecated and tempest.lib.decorators.idempotent_id() should be used instead. This patch will move all the tests on new decorator. - Removed deprecated tempest-lib from test-requirements.txt Change-Id: I0c007de3137b1236dc0977dc6d13ae22583dc811
496 lines
22 KiB
Python
496 lines
22 KiB
Python
# Copyright 2013 OpenStack Foundation
|
|
# Copyright 2015 VMware Inc
|
|
# All Rights Reserved.
|
|
#
|
|
# 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
|
|
|
|
from tempest.lib.common.utils import data_utils
|
|
from tempest.lib.common.utils import test_utils
|
|
from tempest.lib import decorators
|
|
|
|
from tempest.api.network import base
|
|
from tempest import config
|
|
from tempest import test
|
|
|
|
from vmware_nsx_tempest.services import load_balancer_v1_client as LBV1C
|
|
from vmware_nsx_tempest.services import network_client_base as base_client
|
|
|
|
CONF = config.CONF
|
|
|
|
|
|
class LoadBalancerTestJSON(base.BaseNetworkTest):
|
|
"""
|
|
Tests the following operations in the Neutron API using the REST client
|
|
for
|
|
Neutron:
|
|
|
|
create vIP, and Pool
|
|
show vIP
|
|
list vIP
|
|
update vIP
|
|
delete vIP
|
|
update pool
|
|
delete pool
|
|
show pool
|
|
list pool
|
|
health monitoring operations
|
|
"""
|
|
|
|
@classmethod
|
|
def skip_checks(cls):
|
|
super(LoadBalancerTestJSON, cls).skip_checks()
|
|
if not test.is_extension_enabled('lbaas', 'network'):
|
|
msg = "lbaas extension not enabled."
|
|
raise cls.skipException(msg)
|
|
if not test.is_extension_enabled('nsxv-router-type', 'network'):
|
|
msg = "nsxv-router-type extension is not enabled"
|
|
raise cls.skipException(msg)
|
|
|
|
@classmethod
|
|
def resource_setup(cls):
|
|
super(LoadBalancerTestJSON, cls).resource_setup()
|
|
_params = base_client.default_params_with_timeout_values.copy()
|
|
for p in _params.keys():
|
|
if p in ['service', 'region', 'endpoint_type']:
|
|
_params.pop(p)
|
|
cls.lbv1_client = LBV1C.get_client(cls.manager)
|
|
cls.network = cls.create_network()
|
|
cls.name = cls.network['name']
|
|
cls.subnet = cls.create_subnet(cls.network)
|
|
cls.ext_net_id = CONF.network.public_network_id
|
|
cls.router = cls.create_router(data_utils.rand_name('router-'),
|
|
admin_state_up=True,
|
|
external_network_id=cls.ext_net_id,
|
|
router_type='exclusive')
|
|
cls.create_router_interface(cls.router['id'], cls.subnet['id'])
|
|
pool_name = data_utils.rand_name('pool-')
|
|
vip_name = data_utils.rand_name('vip-')
|
|
cls.pool = cls.lbv1_client.create_pool(
|
|
pool_name, "ROUND_ROBIN", "HTTP", cls.subnet['id'])['pool']
|
|
cls.vip = cls.lbv1_client.create_vip(cls.pool['id'],
|
|
subnet_id=cls.subnet['id'],
|
|
name=vip_name,
|
|
protocol="HTTP",
|
|
protocol_port=80)['vip']
|
|
cls.member = cls.lbv1_client.create_member(
|
|
80, cls.pool['id'], cls._ip_version)['member']
|
|
cls.member_address = ("10.0.9.47" if cls._ip_version == 4
|
|
else "2015::beef")
|
|
cls.health_monitor = cls.lbv1_client.create_health_monitor(
|
|
delay=4, max_retries=3, type="TCP", timeout=1)['health_monitor']
|
|
|
|
@classmethod
|
|
def resource_cleanup(cls):
|
|
"""
|
|
Cleanup the lb resources first and then call resource_cleanup
|
|
in BaseNetworkTest to cleanup other network resources. NSX-v
|
|
plugin requires the lb resources to be deleted before we can
|
|
delete subnet or remove interface from router.
|
|
"""
|
|
# Cleanup lb health monitors
|
|
if cls.health_monitor:
|
|
test_utils.call_and_ignore_notfound_exc(
|
|
cls.lbv1_client.delete_health_monitor,
|
|
cls.health_monitor['id'])
|
|
cls.health_monitor = None
|
|
|
|
# Cleanup members
|
|
if cls.member:
|
|
test_utils.call_and_ignore_notfound_exc(
|
|
cls.lbv1_client.delete_member, cls.member['id'])
|
|
cls.member = None
|
|
|
|
# Cleanup vips
|
|
if cls.vip:
|
|
test_utils.call_and_ignore_notfound_exc(
|
|
cls.lbv1_client.delete_vip, cls.vip['id'])
|
|
cls.vip = None
|
|
|
|
# Cleanup pool
|
|
if cls.pool:
|
|
test_utils.call_and_ignore_notfound_exc(
|
|
cls.lbv1_client.delete_pool, cls.pool['id'])
|
|
cls.pool = None
|
|
|
|
super(LoadBalancerTestJSON, cls).resource_cleanup()
|
|
|
|
def _check_list_with_filter(self, obj_name, attr_exceptions, **kwargs):
|
|
create_obj = getattr(self.lbv1_client, 'create_' + obj_name)
|
|
delete_obj = getattr(self.lbv1_client, 'delete_' + obj_name)
|
|
list_objs = getattr(self.lbv1_client, 'list_' + obj_name + 's')
|
|
|
|
body = create_obj(**kwargs)
|
|
obj = body[obj_name]
|
|
self.addCleanup(delete_obj, obj['id'])
|
|
for key, value in six.iteritems(obj):
|
|
# It is not relevant to filter by all arguments. That is why
|
|
# there is a list of attr to except
|
|
if key not in attr_exceptions:
|
|
body = list_objs(**{key: value})
|
|
objs = [v[key] for v in body[obj_name + 's']]
|
|
self.assertIn(value, objs)
|
|
|
|
@decorators.idempotent_id('1c959a37-feb3-4d58-b5fc-58ba653de065')
|
|
def test_list_vips(self):
|
|
# Verify the vIP exists in the list of all vIPs
|
|
body = self.lbv1_client.list_vips()
|
|
vips = body['vips']
|
|
self.assertIn(self.vip['id'], [v['id'] for v in vips])
|
|
|
|
@decorators.idempotent_id('687b7fd1-fd15-4ffd-8166-f376407a6081')
|
|
def test_list_vips_with_filter(self):
|
|
pool_name = data_utils.rand_name("pool-")
|
|
vip_name = data_utils.rand_name('vip-')
|
|
body = self.lbv1_client.create_pool(pool_name,
|
|
lb_method="ROUND_ROBIN",
|
|
protocol="HTTPS",
|
|
subnet_id=self.subnet['id'])
|
|
pool = body['pool']
|
|
self.addCleanup(self.lbv1_client.delete_pool, pool['id'])
|
|
attr_exceptions = ['status', 'session_persistence',
|
|
'status_description']
|
|
self._check_list_with_filter(
|
|
'vip', attr_exceptions, name=vip_name, protocol="HTTPS",
|
|
protocol_port=81, subnet_id=self.subnet['id'], pool_id=pool['id'],
|
|
description=data_utils.rand_name('description-'),
|
|
admin_state_up=False)
|
|
|
|
@decorators.idempotent_id('73dfc119-b64b-4e56-90d2-df61d7181098')
|
|
def test_create_update_delete_pool_vip(self):
|
|
# Creates a vip
|
|
pool_name = data_utils.rand_name("pool-")
|
|
vip_name = data_utils.rand_name('vip-')
|
|
address = self.subnet['allocation_pools'][0]['end']
|
|
body = self.lbv1_client.create_pool(
|
|
pool_name,
|
|
lb_method='ROUND_ROBIN',
|
|
protocol='HTTP',
|
|
subnet_id=self.subnet['id'])
|
|
pool = body['pool']
|
|
body = self.lbv1_client.create_vip(pool['id'],
|
|
name=vip_name,
|
|
protocol="HTTP",
|
|
protocol_port=80,
|
|
subnet_id=self.subnet['id'],
|
|
address=address)
|
|
vip = body['vip']
|
|
vip_id = vip['id']
|
|
# Confirm VIP's address correctness with a show
|
|
body = self.lbv1_client.show_vip(vip_id)
|
|
vip = body['vip']
|
|
self.assertEqual(address, vip['address'])
|
|
# Verification of vip update
|
|
new_name = "New_vip"
|
|
new_description = "New description"
|
|
persistence_type = "HTTP_COOKIE"
|
|
update_data = {"session_persistence": {
|
|
"type": persistence_type}}
|
|
body = self.lbv1_client.update_vip(vip_id,
|
|
name=new_name,
|
|
description=new_description,
|
|
connection_limit=10,
|
|
admin_state_up=False,
|
|
**update_data)
|
|
updated_vip = body['vip']
|
|
self.assertEqual(new_name, updated_vip['name'])
|
|
self.assertEqual(new_description, updated_vip['description'])
|
|
self.assertEqual(10, updated_vip['connection_limit'])
|
|
self.assertFalse(updated_vip['admin_state_up'])
|
|
self.assertEqual(persistence_type,
|
|
updated_vip['session_persistence']['type'])
|
|
self.lbv1_client.delete_vip(vip['id'])
|
|
self.lbv1_client.wait_for_resource_deletion('vip', vip['id'])
|
|
# Verification of pool update
|
|
new_name = "New_pool"
|
|
body = self.lbv1_client.update_pool(pool['id'],
|
|
name=new_name,
|
|
description="new_description",
|
|
lb_method='LEAST_CONNECTIONS')
|
|
updated_pool = body['pool']
|
|
self.assertEqual(new_name, updated_pool['name'])
|
|
self.assertEqual('new_description', updated_pool['description'])
|
|
self.assertEqual('LEAST_CONNECTIONS', updated_pool['lb_method'])
|
|
self.lbv1_client.delete_pool(pool['id'])
|
|
|
|
@decorators.idempotent_id('277a99ce-4b3e-451d-a18a-d26c0376d176')
|
|
def test_show_vip(self):
|
|
# Verifies the details of a vip
|
|
body = self.lbv1_client.show_vip(self.vip['id'])
|
|
vip = body['vip']
|
|
for key, value in six.iteritems(vip):
|
|
# 'status' should not be confirmed in api tests
|
|
if key != 'status':
|
|
self.assertEqual(self.vip[key], value)
|
|
|
|
@decorators.idempotent_id('432470dd-836b-4555-8388-af95a1c74d32')
|
|
def test_show_pool(self):
|
|
# Here we need to new pool without any dependence with vips
|
|
pool_name = data_utils.rand_name("pool-")
|
|
body = self.lbv1_client.create_pool(pool_name,
|
|
lb_method='ROUND_ROBIN',
|
|
protocol='HTTP',
|
|
subnet_id=self.subnet['id'])
|
|
pool = body['pool']
|
|
self.addCleanup(self.lbv1_client.delete_pool, pool['id'])
|
|
# Verifies the details of a pool
|
|
body = self.lbv1_client.show_pool(pool['id'])
|
|
shown_pool = body['pool']
|
|
for key, value in six.iteritems(pool):
|
|
# 'status' should not be confirmed in api tests
|
|
if key != 'status':
|
|
self.assertEqual(value, shown_pool[key])
|
|
|
|
@decorators.idempotent_id('c9951820-7b24-4e67-8c0c-41065ec66071')
|
|
def test_list_pools(self):
|
|
# Verify the pool exists in the list of all pools
|
|
body = self.lbv1_client.list_pools()
|
|
pools = body['pools']
|
|
self.assertIn(self.pool['id'], [p['id'] for p in pools])
|
|
|
|
@decorators.idempotent_id('55a1fb8e-e88e-4042-a46a-13a0282e4990')
|
|
def test_list_pools_with_filters(self):
|
|
attr_exceptions = ['status', 'vip_id', 'members', 'provider',
|
|
'status_description']
|
|
self._check_list_with_filter(
|
|
'pool', attr_exceptions, name=data_utils.rand_name("pool-"),
|
|
lb_method="ROUND_ROBIN", protocol="HTTPS",
|
|
subnet_id=self.subnet['id'],
|
|
description=data_utils.rand_name('description-'),
|
|
admin_state_up=False)
|
|
|
|
@decorators.idempotent_id('dd441433-de8f-4992-a721-0755dec737ff')
|
|
def test_list_members(self):
|
|
# Verify the member exists in the list of all members
|
|
body = self.lbv1_client.list_members()
|
|
members = body['members']
|
|
self.assertIn(self.member['id'], [m['id'] for m in members])
|
|
|
|
@decorators.idempotent_id('ccebe68a-f096-478d-b495-f17d5c0eac7b')
|
|
def test_list_members_with_filters(self):
|
|
attr_exceptions = ['status', 'status_description']
|
|
self._check_list_with_filter('member', attr_exceptions,
|
|
address=self.member_address,
|
|
protocol_port=80,
|
|
pool_id=self.pool['id'])
|
|
|
|
@decorators.idempotent_id('b4efe862-0439-4260-828c-cc09ff7e12a6')
|
|
def test_create_update_delete_member(self):
|
|
# Creates a member
|
|
body = self.lbv1_client.create_member(address=self.member_address,
|
|
protocol_port=80,
|
|
pool_id=self.pool['id'])
|
|
member = body['member']
|
|
# Verification of member update
|
|
body = self.lbv1_client.update_member(member['id'],
|
|
admin_state_up=False)
|
|
updated_member = body['member']
|
|
self.assertFalse(updated_member['admin_state_up'])
|
|
# Verification of member delete
|
|
self.lbv1_client.delete_member(member['id'])
|
|
|
|
@decorators.idempotent_id('4806ca47-b3a0-4280-9962-6631c6815e93')
|
|
def test_show_member(self):
|
|
# Verifies the details of a member
|
|
body = self.lbv1_client.show_member(self.member['id'])
|
|
member = body['member']
|
|
for key, value in six.iteritems(member):
|
|
# 'status' should not be confirmed in api tests
|
|
if key != 'status':
|
|
self.assertEqual(self.member[key], value)
|
|
|
|
@decorators.idempotent_id('65c4d817-d8d2-44df-9c15-86fc7b910044')
|
|
def test_list_health_monitors(self):
|
|
# Verify the health monitor exists in the list of all health monitors
|
|
body = self.lbv1_client.list_health_monitors()
|
|
health_monitors = body['health_monitors']
|
|
self.assertIn(self.health_monitor['id'],
|
|
[h['id'] for h in health_monitors])
|
|
|
|
@decorators.idempotent_id('a2c749a0-4eac-4acc-b729-6b469c3c616a')
|
|
def test_list_health_monitors_with_filters(self):
|
|
attr_exceptions = ['status', 'status_description', 'pools']
|
|
self._check_list_with_filter('health_monitor', attr_exceptions,
|
|
delay=5, max_retries=4, type="TCP",
|
|
timeout=2)
|
|
|
|
@decorators.idempotent_id('94f1e066-de6e-4cd8-b352-533d216956b7')
|
|
def test_create_update_delete_health_monitor(self):
|
|
# Creates a health_monitor
|
|
body = self.lbv1_client.create_health_monitor(delay=4,
|
|
max_retries=3,
|
|
type="TCP",
|
|
timeout=1)
|
|
health_monitor = body['health_monitor']
|
|
# Verification of health_monitor update
|
|
body = (self.lbv1_client.update_health_monitor
|
|
(health_monitor['id'],
|
|
admin_state_up=False))
|
|
updated_health_monitor = body['health_monitor']
|
|
self.assertFalse(updated_health_monitor['admin_state_up'])
|
|
# Verification of health_monitor delete
|
|
body = self.lbv1_client.delete_health_monitor(health_monitor['id'])
|
|
|
|
@decorators.idempotent_id('82943dcf-d424-43f0-890f-4b796f5043dc')
|
|
def test_create_health_monitor_http_type(self):
|
|
hm_type = "HTTP"
|
|
body = self.lbv1_client.create_health_monitor(delay=4,
|
|
max_retries=3,
|
|
type=hm_type,
|
|
timeout=1)
|
|
health_monitor = body['health_monitor']
|
|
self.addCleanup(self.lbv1_client.delete_health_monitor,
|
|
health_monitor['id'])
|
|
self.assertEqual(hm_type, health_monitor['type'])
|
|
|
|
@decorators.idempotent_id('b1279c46-822a-4406-bb16-6a6ce7bf4e4e')
|
|
def test_update_health_monitor_http_method(self):
|
|
body = self.lbv1_client.create_health_monitor(delay=4,
|
|
max_retries=3,
|
|
type="HTTP",
|
|
timeout=1)
|
|
health_monitor = body['health_monitor']
|
|
self.addCleanup(self.lbv1_client.delete_health_monitor,
|
|
health_monitor['id'])
|
|
body = (self.lbv1_client.update_health_monitor
|
|
(health_monitor['id'],
|
|
http_method="POST",
|
|
url_path="/home/user",
|
|
expected_codes="290"))
|
|
updated_health_monitor = body['health_monitor']
|
|
self.assertEqual("POST", updated_health_monitor['http_method'])
|
|
self.assertEqual("/home/user", updated_health_monitor['url_path'])
|
|
self.assertEqual("290", updated_health_monitor['expected_codes'])
|
|
|
|
@decorators.idempotent_id('7beabd44-0200-4cc4-b18d-5fb1f44cf36c')
|
|
def test_show_health_monitor(self):
|
|
# Verifies the details of a health_monitor
|
|
body = self.lbv1_client.show_health_monitor(self.health_monitor['id'])
|
|
health_monitor = body['health_monitor']
|
|
for key, value in six.iteritems(health_monitor):
|
|
# 'status' should not be confirmed in api tests
|
|
if key != 'status':
|
|
self.assertEqual(self.health_monitor[key], value)
|
|
|
|
@decorators.idempotent_id('5386d600-1372-4f99-b0f2-316401718ac4')
|
|
def test_associate_disassociate_health_monitor_with_pool(self):
|
|
# Verify that a health monitor can be associated with a pool
|
|
self.lbv1_client.associate_health_monitor_with_pool(
|
|
self.health_monitor['id'], self.pool['id'])
|
|
body = self.lbv1_client.show_health_monitor(
|
|
self.health_monitor['id'])
|
|
health_monitor = body['health_monitor']
|
|
body = self.lbv1_client.show_pool(self.pool['id'])
|
|
pool = body['pool']
|
|
self.assertIn(pool['id'],
|
|
[p['pool_id'] for p in health_monitor['pools']])
|
|
self.assertIn(health_monitor['id'], pool['health_monitors'])
|
|
# Verify that a health monitor can be disassociated from a pool
|
|
(self.lbv1_client.disassociate_health_monitor_with_pool
|
|
(self.health_monitor['id'], self.pool['id']))
|
|
body = self.lbv1_client.show_pool(self.pool['id'])
|
|
pool = body['pool']
|
|
body = self.lbv1_client.show_health_monitor(
|
|
self.health_monitor['id'])
|
|
health_monitor = body['health_monitor']
|
|
self.assertNotIn(health_monitor['id'], pool['health_monitors'])
|
|
self.assertNotIn(pool['id'],
|
|
[p['pool_id'] for p in health_monitor['pools']])
|
|
|
|
@decorators.idempotent_id('17a6b730-0780-46c9-bca0-cec67387e469')
|
|
def test_get_lb_pool_stats(self):
|
|
# Verify the details of pool stats
|
|
body = self.lbv1_client.list_lb_pool_stats(self.pool['id'])
|
|
stats = body['stats']
|
|
self.assertIn("bytes_in", stats)
|
|
self.assertIn("total_connections", stats)
|
|
self.assertIn("active_connections", stats)
|
|
self.assertIn("bytes_out", stats)
|
|
|
|
@decorators.idempotent_id('a113c740-6194-4622-a187-8343ad3e5208')
|
|
def test_update_list_of_health_monitors_associated_with_pool(self):
|
|
(self.lbv1_client.associate_health_monitor_with_pool
|
|
(self.health_monitor['id'], self.pool['id']))
|
|
self.lbv1_client.update_health_monitor(
|
|
self.health_monitor['id'], admin_state_up=False)
|
|
body = self.lbv1_client.show_pool(self.pool['id'])
|
|
health_monitors = body['pool']['health_monitors']
|
|
for health_monitor_id in health_monitors:
|
|
body = self.lbv1_client.show_health_monitor(health_monitor_id)
|
|
self.assertFalse(body['health_monitor']['admin_state_up'])
|
|
(self.lbv1_client.disassociate_health_monitor_with_pool
|
|
(self.health_monitor['id'], self.pool['id']))
|
|
|
|
@decorators.idempotent_id('a2843ec6-80d8-4617-b985-8c8565daac8d')
|
|
def test_update_admin_state_up_of_pool(self):
|
|
self.lbv1_client.update_pool(self.pool['id'],
|
|
admin_state_up=False)
|
|
body = self.lbv1_client.show_pool(self.pool['id'])
|
|
pool = body['pool']
|
|
self.assertFalse(pool['admin_state_up'])
|
|
|
|
@decorators.idempotent_id('fd45c684-b847-472f-a7e8-a3f70e8e08e0')
|
|
def test_show_vip_associated_with_pool(self):
|
|
body = self.lbv1_client.show_pool(self.pool['id'])
|
|
pool = body['pool']
|
|
body = self.lbv1_client.show_vip(pool['vip_id'])
|
|
vip = body['vip']
|
|
self.assertEqual(self.vip['name'], vip['name'])
|
|
self.assertEqual(self.vip['id'], vip['id'])
|
|
|
|
@decorators.idempotent_id('1ac0ca5f-7d6a-4ac4-b286-d68c92a98405')
|
|
def test_show_members_associated_with_pool(self):
|
|
body = self.lbv1_client.show_pool(self.pool['id'])
|
|
members = body['pool']['members']
|
|
for member_id in members:
|
|
body = self.lbv1_client.show_member(member_id)
|
|
self.assertIsNotNone(body['member']['status'])
|
|
self.assertEqual(member_id, body['member']['id'])
|
|
self.assertIsNotNone(body['member']['admin_state_up'])
|
|
|
|
@decorators.idempotent_id('4fa308fa-ac2b-4acf-87db-adfe2ee4739c')
|
|
def test_update_pool_related_to_member(self):
|
|
# Create new pool
|
|
pool_name = data_utils.rand_name("pool-")
|
|
body = self.lbv1_client.create_pool(
|
|
pool_name,
|
|
lb_method='ROUND_ROBIN',
|
|
protocol='HTTP',
|
|
subnet_id=self.subnet['id'])
|
|
new_pool = body['pool']
|
|
self.addCleanup(self.lbv1_client.delete_pool, new_pool['id'])
|
|
# Update member with new pool's id
|
|
body = self.lbv1_client.update_member(self.member['id'],
|
|
pool_id=new_pool['id'])
|
|
# Confirm with show that pool_id change
|
|
body = self.lbv1_client.show_member(self.member['id'])
|
|
member = body['member']
|
|
self.assertEqual(member['pool_id'], new_pool['id'])
|
|
# Update member with old pool id, this is needed for clean up
|
|
body = self.lbv1_client.update_member(self.member['id'],
|
|
pool_id=self.pool['id'])
|
|
|
|
@decorators.idempotent_id('0af2ff6b-a896-433d-8107-3c76262a9dfa')
|
|
def test_update_member_weight(self):
|
|
self.lbv1_client.update_member(self.member['id'],
|
|
weight=2)
|
|
body = self.lbv1_client.show_member(self.member['id'])
|
|
member = body['member']
|
|
self.assertEqual(2, member['weight'])
|
|
|
|
|
|
@decorators.skip_because(bug="1402007")
|
|
class LoadBalancerIpV6TestJSON(LoadBalancerTestJSON):
|
|
_ip_version = 6
|