Merge "Multiple Transport Zone API tests"
This commit is contained in:
commit
0aacba389b
@ -64,6 +64,9 @@ NSXvGroup = [
|
|||||||
cfg.StrOpt('vdn_scope_id',
|
cfg.StrOpt('vdn_scope_id',
|
||||||
default='vdnscope-1',
|
default='vdnscope-1',
|
||||||
help="NSX-v vdn scope id"),
|
help="NSX-v vdn scope id"),
|
||||||
|
cfg.IntOpt('max_mtz',
|
||||||
|
default=3,
|
||||||
|
help="Max Multiple Transport Zones used for testing."),
|
||||||
cfg.DictOpt('flat_alloc_pool_dict',
|
cfg.DictOpt('flat_alloc_pool_dict',
|
||||||
default={},
|
default={},
|
||||||
help=" Define flat network ip range."
|
help=" Define flat network ip range."
|
||||||
|
@ -0,0 +1,306 @@
|
|||||||
|
# Copyright 2016 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 re
|
||||||
|
import six
|
||||||
|
|
||||||
|
from tempest_lib.common.utils import data_utils
|
||||||
|
from tempest_lib import decorators
|
||||||
|
|
||||||
|
import base_provider as base
|
||||||
|
from tempest import config
|
||||||
|
from tempest import test
|
||||||
|
from vmware_nsx_tempest.services import nsxv_client
|
||||||
|
|
||||||
|
CONF = config.CONF
|
||||||
|
|
||||||
|
|
||||||
|
class MultipleTransportZonesTest(base.BaseAdminNetworkTest):
|
||||||
|
"""Validate that NSX-v plugin can support multiple transport zones.
|
||||||
|
|
||||||
|
The test environment must at least have 1 additional TZ created.
|
||||||
|
The default number of TZs used to test, include the default TZ is 3.
|
||||||
|
However, all MTZ tests can run with 2 TZs in the testbed.
|
||||||
|
"""
|
||||||
|
@classmethod
|
||||||
|
def skip_checks(cls):
|
||||||
|
super(MultipleTransportZonesTest, cls).skip_checks()
|
||||||
|
if not test.is_extension_enabled('provider', 'network'):
|
||||||
|
msg = "provider extension is not enabled"
|
||||||
|
raise cls.skipException(msg)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def setup_clients(cls):
|
||||||
|
super(MultipleTransportZonesTest, cls).setup_clients()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def resource_setup(cls):
|
||||||
|
super(MultipleTransportZonesTest, cls).resource_setup()
|
||||||
|
manager_ip = re.search(r"(\d{1,3}\.){3}\d{1,3}",
|
||||||
|
CONF.nsxv.manager_uri).group(0)
|
||||||
|
cls.vsm = nsxv_client.VSMClient(
|
||||||
|
manager_ip, CONF.nsxv.user, CONF.nsxv.password)
|
||||||
|
cls.nsxv_scope_ids = cls.get_all_scope_id_list(with_default_scope=True)
|
||||||
|
if len(cls.nsxv_scope_ids) < 2:
|
||||||
|
msg = "Only one transport zone deployed. Need at least 2."
|
||||||
|
raise cls.skipException(msg)
|
||||||
|
cls.provider_network_type = getattr(CONF.nsxv,
|
||||||
|
"provider_network_type",
|
||||||
|
'vxlan')
|
||||||
|
cls.MAX_MTZ = CONF.nsxv.max_mtz
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def create_tenant_network_subnet(cls, name_prefix='mtz-project'):
|
||||||
|
network_name = data_utils.rand_name(name_prefix)
|
||||||
|
resp = cls.create_network(client=cls.networks_client,
|
||||||
|
name=network_name)
|
||||||
|
network = resp.get('network', resp)
|
||||||
|
cls.tenant_net = [None, network]
|
||||||
|
resp = cls.create_subnet(network,
|
||||||
|
name=network_name,
|
||||||
|
client=cls.subnets_client)
|
||||||
|
subnet = resp.get('subnet', resp)
|
||||||
|
return (network['id'], (None, network, subnet))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_all_scope_id_list(cls, with_default_scope=False):
|
||||||
|
"""return all scope IDs w/wo the default scope defined in NSX."""
|
||||||
|
scopes = cls.vsm.get_all_vdn_scopes()
|
||||||
|
scope_id_list = [x['objectId'] for x in scopes]
|
||||||
|
if with_default_scope:
|
||||||
|
return scope_id_list
|
||||||
|
try:
|
||||||
|
scope_id_list.remove(CONF.nsxv.vdn_scope_id)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
return scope_id_list
|
||||||
|
|
||||||
|
def create_network_subnet(self, scope_id, cidr=None, cidr_offset=0):
|
||||||
|
network_name = data_utils.rand_name('mtz-network-')
|
||||||
|
create_kwargs = {'provider:network_type': self.provider_network_type,
|
||||||
|
'provider:physical_network': scope_id}
|
||||||
|
resp = self.create_network(network_name, **create_kwargs)
|
||||||
|
network = resp.get('network', resp)
|
||||||
|
net_id = network['id']
|
||||||
|
self.addCleanup(self._try_delete_resource,
|
||||||
|
self.delete_network, net_id)
|
||||||
|
self.assertEqual(scope_id,
|
||||||
|
network['provider:physical_network'])
|
||||||
|
resp = self.create_subnet(network,
|
||||||
|
name=network_name,
|
||||||
|
cidr=cidr,
|
||||||
|
cidr_offset=cidr_offset)
|
||||||
|
subnet = resp.get('subnet', resp)
|
||||||
|
resp = self.show_network(net_id)
|
||||||
|
s_network = resp.get('network', resp)
|
||||||
|
net_subnets = s_network['subnets']
|
||||||
|
self.assertIn(subnet['id'], net_subnets)
|
||||||
|
lswitch_list = self.vsm.get_all_logical_switches(scope_id)
|
||||||
|
lswitch_list = [x for x in lswitch_list if x['name'] == net_id]
|
||||||
|
msg = ("network=%s is not configured by specified vdn_scope_id=%s"
|
||||||
|
% (net_id, scope_id))
|
||||||
|
self.assertTrue(len(lswitch_list) == 1, msg=msg)
|
||||||
|
return (net_id, s_network, subnet)
|
||||||
|
|
||||||
|
def delete_networks(self, nets):
|
||||||
|
for net_id in six.iterkeys(nets):
|
||||||
|
self.delete_network(net_id)
|
||||||
|
|
||||||
|
def check_update_network(self, network):
|
||||||
|
new_name = network['name'] + "-2nd"
|
||||||
|
self.update_network(network['id'], name=new_name)
|
||||||
|
resp = self.show_network(network['id'])
|
||||||
|
s_network = resp.get('network', resp)
|
||||||
|
self.assertEqual(new_name, s_network['name'])
|
||||||
|
|
||||||
|
def check_update_subnet(self, subnet):
|
||||||
|
new_name = subnet['name'] + "-2nd"
|
||||||
|
self.update_subnet(subnet['id'], name=new_name)
|
||||||
|
resp = self.show_subnet(subnet['id'])['subnet']
|
||||||
|
s_subnet = resp.get('subnet', resp)
|
||||||
|
self.assertEqual(new_name, s_subnet['name'])
|
||||||
|
|
||||||
|
def create_show_update_delete_mtz_network_subnet(self, s_id):
|
||||||
|
net_id, network, subnet = self.create_network_subnet(s_id)
|
||||||
|
self.check_update_network(network)
|
||||||
|
self.check_update_subnet(subnet)
|
||||||
|
self.delete_network(net_id)
|
||||||
|
|
||||||
|
def create_router_by_type(self, router_type, name=None, **kwargs):
|
||||||
|
router_client = self.admin_client
|
||||||
|
router_name = name or data_utils.rand_name('mtz-')
|
||||||
|
create_kwargs = dict(name=router_name, external_gateway_info={
|
||||||
|
"network_id": CONF.network.public_network_id})
|
||||||
|
if router_type in ('shared', 'exclusive'):
|
||||||
|
create_kwargs['router_type'] = router_type
|
||||||
|
elif router_type in ('distributed'):
|
||||||
|
create_kwargs['distributed'] = True
|
||||||
|
kwargs.update(create_kwargs)
|
||||||
|
router = router_client.create_router(**kwargs)
|
||||||
|
router = router['router'] if 'router' in router else router
|
||||||
|
self.addCleanup(self._try_delete_resource,
|
||||||
|
router_client.delete_router, router['id'])
|
||||||
|
self.assertEqual(router['name'], router_name)
|
||||||
|
return (router_client, router)
|
||||||
|
|
||||||
|
def create_router_and_add_interfaces(self, router_type, nets):
|
||||||
|
(router_client, router) = self.create_router_by_type(router_type)
|
||||||
|
if router_type == 'exclusive':
|
||||||
|
router_nsxv_name = '%s-%s' % (router['name'], router['id'])
|
||||||
|
exc_edge = self.vsm.get_edge(router_nsxv_name)
|
||||||
|
self.assertTrue(exc_edge is not None)
|
||||||
|
self.assertEqual(exc_edge['edgeType'], 'gatewayServices')
|
||||||
|
for net_id, (s_id, network, subnet) in six.iteritems(nets):
|
||||||
|
# register to cleanup before adding interfaces so interfaces
|
||||||
|
# and router can be deleted if test is aborted.
|
||||||
|
self.addCleanup(
|
||||||
|
self._try_delete_resource,
|
||||||
|
router_client.remove_router_interface_with_subnet_id,
|
||||||
|
router['id'], subnet['id'])
|
||||||
|
router_client.add_router_interface_with_subnet_id(
|
||||||
|
router['id'], subnet_id=subnet['id'])
|
||||||
|
return router
|
||||||
|
|
||||||
|
def clear_router_gateway_and_interfaces(self, router, nets):
|
||||||
|
router_client = self.admin_client
|
||||||
|
router_client.update_router(router['id'],
|
||||||
|
external_gateway_info=dict())
|
||||||
|
for net_id, (s_id, network, subnet) in six.iteritems(nets):
|
||||||
|
try:
|
||||||
|
router_client.remove_router_interface_with_subnet_id(
|
||||||
|
router['id'], subnet['id'])
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def _test_router_with_multiple_mtz_networks(self, router_type):
|
||||||
|
"""test router attached with multiple TZs."""
|
||||||
|
scope_id_list = self.get_all_scope_id_list(with_default_scope=True)
|
||||||
|
nets = {}
|
||||||
|
for cidr_step in range(0, self.MAX_MTZ):
|
||||||
|
s_id = scope_id_list[cidr_step % len(scope_id_list)]
|
||||||
|
net_id, network, subnet = self.create_network_subnet(
|
||||||
|
s_id, cidr_offset=(cidr_step + 2))
|
||||||
|
nets[net_id] = (s_id, network, subnet)
|
||||||
|
router = self.create_router_and_add_interfaces(router_type, nets)
|
||||||
|
self.clear_router_gateway_and_interfaces(router, nets)
|
||||||
|
|
||||||
|
def _test_router_with_network_and_mtz_networks(self, router_type):
|
||||||
|
"""test router attached with multiple TZs and one tenant network."""
|
||||||
|
scope_id_list = self.get_all_scope_id_list(with_default_scope=True)
|
||||||
|
nets = {}
|
||||||
|
net_id, net_info = self.create_tenant_network_subnet('mtz-tenant')
|
||||||
|
nets[net_id] = net_info
|
||||||
|
for cidr_step in range(0, self.MAX_MTZ):
|
||||||
|
s_id = scope_id_list[cidr_step % len(scope_id_list)]
|
||||||
|
net_id, network, subnet = self.create_network_subnet(
|
||||||
|
s_id, cidr_offset=(cidr_step + 2))
|
||||||
|
nets[net_id] = (s_id, network, subnet)
|
||||||
|
router = self.create_router_and_add_interfaces(router_type, nets)
|
||||||
|
self.clear_router_gateway_and_interfaces(router, nets)
|
||||||
|
|
||||||
|
@test.idempotent_id('39bc7909-912c-4e16-8246-773ae6a40ba4')
|
||||||
|
def test_mtz_network_crud_operations(self):
|
||||||
|
scope_id_list = self.get_all_scope_id_list(with_default_scope=False)
|
||||||
|
s_id = scope_id_list[0]
|
||||||
|
self.create_show_update_delete_mtz_network_subnet(s_id)
|
||||||
|
|
||||||
|
@test.idempotent_id('4e1717d6-df39-4539-99da-df23814cfe14')
|
||||||
|
def test_mtz_overlay_network(self):
|
||||||
|
"""overlay subnets with the same TZ"""
|
||||||
|
scope_id_list = self.get_all_scope_id_list(with_default_scope=True)
|
||||||
|
s_id = scope_id_list[0]
|
||||||
|
nets = {}
|
||||||
|
for cidr_step in range(1, self.MAX_MTZ):
|
||||||
|
net_id, network, subnet = self.create_network_subnet(s_id)
|
||||||
|
nets[net_id] = (s_id, network, subnet)
|
||||||
|
self.delete_networks(nets)
|
||||||
|
|
||||||
|
@test.idempotent_id('6ecf67fc-4396-41d9-9d84-9d8c936dcb8f')
|
||||||
|
def test_multiple_mtz_overlay_network(self):
|
||||||
|
"""overlay subnets from multiple TZs."""
|
||||||
|
scope_id_list = self.get_all_scope_id_list(with_default_scope=True)
|
||||||
|
nets = {}
|
||||||
|
cidr_step = 0
|
||||||
|
for s_id in scope_id_list:
|
||||||
|
net_id, network, subnet = self.create_network_subnet(s_id)
|
||||||
|
nets[net_id] = (s_id, network, subnet)
|
||||||
|
net_id, network, subnet = self.create_network_subnet(s_id)
|
||||||
|
nets[net_id] = (s_id, network, subnet)
|
||||||
|
cidr_step += 1
|
||||||
|
if cidr_step < self.MAX_MTZ:
|
||||||
|
break
|
||||||
|
self.delete_networks(nets)
|
||||||
|
|
||||||
|
@test.idempotent_id('e7e0fc6c-41fd-44bc-b9b1-4501ce618738')
|
||||||
|
def test_mtz_non_overlay_network(self):
|
||||||
|
"""non-overlay subnets from one TZ."""
|
||||||
|
scope_id_list = self.get_all_scope_id_list(with_default_scope=False)
|
||||||
|
s_id = scope_id_list[0]
|
||||||
|
nets = {}
|
||||||
|
for cidr_step in range(0, self.MAX_MTZ):
|
||||||
|
net_id, network, subnet = self.create_network_subnet(
|
||||||
|
s_id, cidr_offset=(cidr_step + 1))
|
||||||
|
nets[net_id] = (s_id, network, subnet)
|
||||||
|
self.delete_networks(nets)
|
||||||
|
|
||||||
|
@test.idempotent_id('b1cb5815-6380-421f-beef-ae3cb148cef4')
|
||||||
|
def test_multiple_mtz_non_overlay_network(self):
|
||||||
|
"""non-overlay subnets from multiple TZs."""
|
||||||
|
scope_id_list = self.get_all_scope_id_list(with_default_scope=True)
|
||||||
|
nets = {}
|
||||||
|
for cidr_step in range(0, self.MAX_MTZ):
|
||||||
|
s_id = scope_id_list[cidr_step % len(scope_id_list)]
|
||||||
|
net_id, network, subnet = self.create_network_subnet(
|
||||||
|
s_id, cidr_offset=cidr_step)
|
||||||
|
nets[net_id] = (s_id, network, subnet)
|
||||||
|
self.delete_networks(nets)
|
||||||
|
|
||||||
|
@test.idempotent_id('006a1a4b-4b63-4663-8baa-affe5df62b11')
|
||||||
|
def test_shared_router_with_multiple_mtz_networks(self):
|
||||||
|
"""shared router attached with multiple TZs."""
|
||||||
|
self._test_router_with_multiple_mtz_networks(
|
||||||
|
router_type='shared')
|
||||||
|
|
||||||
|
@test.idempotent_id('b160d1dc-0332-4d1a-b2a0-c11f57fe4dd9')
|
||||||
|
def test_exclusive_router_with_multiple_mtz_networks(self):
|
||||||
|
"""exclusive router attached with multiple TZs."""
|
||||||
|
self._test_router_with_multiple_mtz_networks(
|
||||||
|
router_type='exclusive')
|
||||||
|
|
||||||
|
@decorators.skip_because(bug="1592174")
|
||||||
|
@test.idempotent_id('2c46290c-8a08-4037-aada-f96fd34b3260')
|
||||||
|
def test_distributed_router_with_multiple_mtz_networks(self):
|
||||||
|
"""exclusive router attached with multiple TZs."""
|
||||||
|
self._test_router_with_multiple_mtz_networks(
|
||||||
|
router_type='distributed')
|
||||||
|
|
||||||
|
@test.idempotent_id('be8f7320-2246-43f3-a826-768f763c9bd0')
|
||||||
|
def test_shared_router_with_network_and_mtz_networks(self):
|
||||||
|
"""router attached with multiple TZs and one tenant network."""
|
||||||
|
self._test_router_with_network_and_mtz_networks(
|
||||||
|
router_type='shared')
|
||||||
|
|
||||||
|
@test.idempotent_id('3cb27410-67e2-4e82-95c7-3dbbe9a8c64b')
|
||||||
|
def test_exclusive_router_with_network_and_mtz_networks(self):
|
||||||
|
"""router attached with multiple TZs and one tenant network."""
|
||||||
|
self._test_router_with_network_and_mtz_networks(
|
||||||
|
router_type='exclusive')
|
||||||
|
|
||||||
|
@decorators.skip_because(bug="1592174")
|
||||||
|
@test.idempotent_id('e7c066d5-c2f1-41e7-bc86-9b6295461903')
|
||||||
|
def test_distributed_router_with_network_and_mtz_networks(self):
|
||||||
|
"""router attached with multiple TZs and one tenant network."""
|
||||||
|
self._test_router_with_network_and_mtz_networks(
|
||||||
|
router_type='distributed')
|
Loading…
x
Reference in New Issue
Block a user