Merge "Tempest: Adding l2gw test"

This commit is contained in:
Jenkins 2016-03-21 20:57:02 +00:00 committed by Gerrit Code Review
commit f3c58aaaa6
6 changed files with 403 additions and 24 deletions

View File

View File

@ -0,0 +1,26 @@
# 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.
from oslo_log import log
LOG = log.getLogger(__name__)
# L2GW constants.
L2GW = "l2_gateway"
L2GWS = L2GW + "s"
L2_GWS_BASE_URI = "/l2-gateways"
EXPECTED_HTTP_RESPONSE_200 = "200"
EXPECTED_HTTP_RESPONSE_201 = "201"
EXPECTED_HTTP_RESPONSE_204 = "204"

View File

@ -111,6 +111,12 @@ L2gwGroup = [
default="",
help="l2gw multiple devices, interface has multiple VLANs"
" m-ifs::dvportgroup-144|138#246;dvportgroup-155|339"),
cfg.StrOpt('vlan_1',
default="16",
help="VLAN id"),
cfg.StrOpt('vlan_2',
default="17",
help="VLAN id"),
]
nsxv3_group = cfg.OptGroup(name='nsxv3',

View File

@ -1,3 +1,6 @@
# 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
@ -9,55 +12,69 @@
# 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 oslo_log import log
from tempest.lib.services.network import base
from vmware_nsx_tempest._i18n import _LI
from vmware_nsx_tempest._i18n import _LW
from vmware_nsx_tempest.common import constants
LOG = log.getLogger(__name__)
class L2GatewayClient(base.BaseNetworkClient):
resource = 'l2_gateway'
resource_plural = 'l2_gateways'
path = 'l2-gateways'
resource_base_path = '/%s' % path
resource_object_path = '/%s/%%s' % path
"""
Request resources via API for L2GatewayClient
l2 gateway create request
l2 gateway update request
l2 gateway show request
l2 gateway delete request
l2 gateway list all request
"""
def create_l2_gateway(self, **kwargs):
uri = self.resource_base_path
post_data = {self.resource: kwargs}
uri = constants.L2_GWS_BASE_URI
post_data = {constants.L2GW: kwargs}
LOG.info(_LI("URI : %(uri)s, posting data : %(post_data)s") % {
"uri": uri, "post_data": post_data})
return self.create_resource(uri, post_data)
def update_l2_gateway(self, l2_gateway_id, **kwargs):
uri = self.resource_object_path % l2_gateway_id
post_data = {self.resource: kwargs}
uri = constants.L2_GWS_BASE_URI + "/" + l2_gateway_id
post_data = {constants.L2GW: kwargs}
constants.LOG.info(
_LI("URI : %(uri)s, posting data : %(post_data)s") % {
"uri": uri, "post_data": post_data})
return self.update_resource(uri, post_data)
def show_l2_gateway(self, l2_gateway_id, **fields):
uri = self.resource_object_path % l2_gateway_id
uri = constants.L2_GWS_BASE_URI + "/" + l2_gateway_id
LOG.info(_LI("URI : %(uri)s") % {"uri": uri})
return self.show_resource(uri, **fields)
def delete_l2_gateway(self, l2_gateway_id):
uri = self.resource_object_path % l2_gateway_id
uri = constants.L2_GWS_BASE_URI + "/" + l2_gateway_id
LOG.info(_LI("URI : %(uri)s") % {"uri": uri})
return self.delete_resource(uri)
def list_l2_gateways(self, **filters):
uri = self.resource_base_path
uri = constants.L2_GWS_BASE_URI
LOG.info(_LI("URI : %(uri)s") % {"uri": uri})
return self.list_resources(uri, **filters)
def get_client(client_mgr):
"""create a l2-gateway client from manager or networks_client
For itempest user:
from itempest import load_our_solar_system as osn
from vmware_nsx_tempest.services import l2_gateway_client
l2gw_client = l2_gateway_client.get_client(osn.adm.manager)
For tempest user:
l2gw_client = l2_gateway_client.get_client(osn.adm)
"""
manager = getattr(client_mgr, 'manager', client_mgr)
net_client = getattr(manager, 'networks_client')
Create a l2-gateway client from manager or networks_client
"""
try:
_params = manager.default_params_with_timeout_values.copy()
except Exception:
manager = getattr(client_mgr, "manager", client_mgr)
net_client = getattr(manager, "networks_client")
_params = manager.default_params_withy_timeout_values.copy()
except AttributeError as attribute_err:
LOG.warning(_LW("Failed to locate the attribute, Error: %(err_msg)s") %
{"err_msg": attribute_err.__str__()})
_params = {}
client = L2GatewayClient(net_client.auth_provider,
net_client.service,

View File

@ -223,6 +223,15 @@ class NSXV3Client(object):
response = self.get(endpoint="/logical-switches")
return response.json()['results']
def get_bridge_cluster_info(self):
"""
Get bridge cluster information.
:return: returns bridge cluster id and bridge cluster name.
"""
response = self.get(endpoint="/bridge-clusters")
return response.json()["results"]
def get_logical_switch(self, os_name, os_uuid):
"""
Get the logical switch based on the name and uuid provided.

View File

@ -0,0 +1,321 @@
# Copyright 2016 VMware Inc
# All Rights Reserved.
#
# Copyright 2015 OpenStack Foundation
#
# 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 tempest.api.network import base
from tempest import config
from tempest.lib.common.utils import data_utils
from tempest import test
from vmware_nsx_tempest._i18n import _LI
from vmware_nsx_tempest._i18n import _LW
from vmware_nsx_tempest.common import constants
from vmware_nsx_tempest.services import l2_gateway_client
from vmware_nsx_tempest.services import nsxv3_client
LOG = constants.log.getLogger(__name__)
CONF = config.CONF
class L2GatewayTest(base.BaseAdminNetworkTest):
"""
Test l2 gateway operations.
"""
credentials = ["primary", "admin"]
@classmethod
def skip_checks(cls):
"""
Skip running test if we do not meet crietria to run the tests.
"""
super(L2GatewayTest, cls).skip_checks()
if not test.is_extension_enabled("l2-gateway", "network"):
raise cls.skipException("l2-gateway extension not enabled.")
@classmethod
def setup_clients(cls):
"""
Create various client connections. Such as NSXv3 and L2 Gateway.
"""
super(L2GatewayTest, cls).setup_clients()
cls.l2gw_created = {}
try:
manager = getattr(cls.os_adm, "manager", cls.os_adm)
net_client = getattr(manager, "networks_client")
_params = manager.default_params_withy_timeout_values.copy()
except AttributeError as attribute_err:
LOG.warning(
_LW("Failed to locate the attribute, Error: %(err_msg)s") %
{"err_msg": attribute_err.__str__()})
_params = {}
cls.l2gw_client = l2_gateway_client.L2GatewayClient(
net_client.auth_provider,
net_client.service,
net_client.region,
net_client.endpoint_type,
**_params)
cls.nsxv3_client_obj = nsxv3_client.NSXV3Client(
CONF.nsxv3.nsx_manager,
CONF.nsxv3.nsx_user,
CONF.nsxv3.nsx_password)
@classmethod
def resource_setup(cls):
"""
Setting up the resources for the test.
"""
super(L2GatewayTest, cls).resource_setup()
cls.VLAN_1 = getattr(CONF.l2gw, "vlan_1", None)
cls.VLAN_2 = getattr(CONF.l2gw, "vlan_2", None)
@classmethod
def resource_cleanup(cls):
"""
Clean all the resources used during the test.
"""
for l2gw_id in cls.l2gw_created.keys():
cls.l2gw_client.delete_l2_gateway(l2gw_id)
cls.l2gw_created.pop(l2gw_id)
def operate_l2gw(self, name, devices, task):
"""
l2gw operations such create, delete, update and show.
:param name: l2gw name.
:param devices: l2gw parameters information.
:param task: Operation to perform.
"""
LOG.info(_LI("name: %(name)s, devices: %(devices)s, "
"task: %(task)s") %
{"name": name, "devices": devices, "task": task})
if task == "create":
rsp = self.l2gw_client.create_l2_gateway(
name=name, **devices)
self.assertEqual(constants.EXPECTED_HTTP_RESPONSE_201,
rsp.response["status"],
"Response code is not %(code)s" % {
"code":
constants.EXPECTED_HTTP_RESPONSE_201})
rsp_l2gw = rsp[constants.L2GW]
self.l2gw_created[rsp_l2gw["id"]] = rsp_l2gw
LOG.info(_LI("response : %(rsp_l2gw)s") % {"rsp_l2gw": rsp_l2gw})
self.assertEqual(name, rsp_l2gw["name"],
"l2gw name=%(rsp_name)s is not the same as "
"requested=%(name)s" % {"rsp_name": rsp_l2gw[
"name"], "name": name})
elif task == "delete":
l2gw_id, _ = self.l2gw_created.popitem()
rsp = self.l2gw_client.delete_l2_gateway(l2gw_id)
LOG.info(_LI("response : %(rsp)s") % {"rsp": rsp})
self.assertEqual(constants.EXPECTED_HTTP_RESPONSE_204,
rsp.response["status"],
"Response code is not %(code)s" % {
"code":
constants.EXPECTED_HTTP_RESPONSE_204})
elif task == "update":
l2gw_id, _ = self.l2gw_created.popitem()
rsp = self.l2gw_client.update_l2_gateway(l2gw_id,
name=name, **devices)
self.assertEqual(constants.EXPECTED_HTTP_RESPONSE_200,
rsp.response["status"],
"Response code is not %(code)s" % {
"code":
constants.EXPECTED_HTTP_RESPONSE_200})
rsp_l2gw = rsp[constants.L2GW]
self.l2gw_created[rsp_l2gw["id"]] = rsp_l2gw
LOG.info(_LI("response : %(rsp_l2gw)s") % {"rsp_l2gw": rsp_l2gw})
self.assertEqual(name, rsp_l2gw["name"],
"l2gw name=%(rsp_name)s is not the same as "
"requested=%(name)s" % {
"rsp_name": rsp_l2gw["name"], "name": name})
if "name" in devices["devices"][0]["interfaces"][0]:
self.assertEqual(
devices["devices"][0]["interfaces"][0]["name"],
rsp_l2gw["devices"][0]["interfaces"][0][
"name"], "L2GW interface name update "
"failed!!!")
if "segmentation_id" in devices["devices"][0]["interfaces"][0]:
self.assertEqual(devices["devices"][0]["interfaces"][0][
"segmentation_id"][0],
rsp_l2gw["devices"][0]["interfaces"][0][
"segmentation_id"][0],
"L2GW segmentation id update failed!!!")
elif task == "show":
l2gw_id, l2gw_parameters = self.l2gw_created.popitem()
rsp = self.l2gw_client.show_l2_gateway(l2gw_id)
self.assertEqual(constants.EXPECTED_HTTP_RESPONSE_200,
rsp.response["status"],
"Response code is not %(code)s" % {
"code":
constants.EXPECTED_HTTP_RESPONSE_200})
rsp_l2gw = rsp[constants.L2GW]
constants.LOG.info(
_LI("response : %(rsp_l2gw)s") % {"rsp_l2gw": rsp_l2gw})
self.assertEqual(name, rsp_l2gw["name"],
"l2gw name=%(rsp_name)s is not the same as "
"requested=%(name)s" % {
"rsp_name": rsp_l2gw["name"],
"name": name})
self.assertEqual(l2gw_parameters, rsp_l2gw,
"l2-gateway-show does not show parameter as it "
"was created.")
self.l2gw_created[l2gw_id] = l2gw_parameters
def nsx_bridge_cluster_info(self):
"""
Collect the device and interface name of the nsx brdige cluster.
:return: nsx bridge id and display name.
"""
response = self.nsxv3_client_obj.get_bridge_cluster_info()
if len(response) == 0:
raise RuntimeError("NSX bridge cluster information is null")
return response[0]["id"], response[0]["display_name"]
@test.attr(type="nsxv3")
@test.idempotent_id("e5e3a089-602c-496e-8c17-4ef613266924")
def test_l2_gateway_create(self):
"""
Create l2gw based on UUID and bridge cluster name. It creates l2gw.
To create l2gw we need bridge cluster name (interface name) and
bridge cluster UUID (device name) from NSX manager.
"""
LOG.info(_LI("Testing l2_gateway_create api"))
device_name, interface_name = self.nsx_bridge_cluster_info()
l2gw_name = data_utils.rand_name(constants.L2GW)
devices = {"devices": [{"device_name": device_name,
"interfaces": [{"name": interface_name}]}]
}
self.operate_l2gw(name=l2gw_name, devices=devices, task="create")
self.resource_cleanup()
@test.attr(type="nsxv3")
@test.idempotent_id("9968a529-e785-472f-8705-9b394a912e43")
def test_l2_gateway_create_with_segmentation_id(self):
"""
Create l2gw based on UUID and bridge cluster name. It creates l2gw.
To create l2gw we need bridge cluster name (interface name) and
bridge cluster UUID (device name) from NSX manager and vlan id.
"""
LOG.info(_LI("Testing l2_gateway_create api"))
device_name, interface_name = self.nsx_bridge_cluster_info()
l2gw_name = data_utils.rand_name(constants.L2GW)
devices = {"devices": [
{"device_name": device_name,
"interfaces": [{"name": interface_name,
"segmentation_id": [
self.VLAN_1,
self.VLAN_2
]
}]
}]
}
self.operate_l2gw(name=l2gw_name, devices=devices, task="create")
self.resource_cleanup()
@test.attr(type="nsxv3")
@test.idempotent_id("670cacb5-134e-467d-ba41-0d7cdbcf3903")
def test_l2_gateway_delete(self):
"""
Delete l2gw will create l2gw and delete recently created l2gw. To
delete l2gw we need l2gw id.
"""
LOG.info(_LI("Testing l2_gateway_delete api"))
device_name, interface_name = self.nsx_bridge_cluster_info()
l2gw_name = data_utils.rand_name(constants.L2GW)
devices = {"devices": [{"device_name": device_name,
"interfaces": [{"name": interface_name}]}]
}
# Creating l2gw.
self.operate_l2gw(name=l2gw_name, devices=devices, task="create")
# Deleting already created l2gw.
self.operate_l2gw(name=l2gw_name, devices=devices, task="delete")
self.resource_cleanup()
@test.attr(type="nsxv3")
@test.idempotent_id("fa76f6e6-8aa7-46d8-9af4-2206d0773dc3")
def test_l2_gateway_update_l2gw_name(self):
"""
Update l2gw will update info in already created l2gw. To
update l2gw we need l2gw id and payload to update.
"""
LOG.info(_LI("Testing l2_gateway_update api"))
device_name, interface_name = self.nsx_bridge_cluster_info()
l2gw_name = data_utils.rand_name(constants.L2GW)
devices = {"devices": [{"device_name": device_name,
"interfaces": [{"name": interface_name}]}]
}
# Creating l2gw.
self.operate_l2gw(name=l2gw_name, devices=devices, task="create")
# Updating already created l2gw with new l2gw name.
self.operate_l2gw(name=l2gw_name + "_updated", devices=devices,
task="update")
self.resource_cleanup()
@test.attr(type="nsxv3")
@test.idempotent_id("c4977df8-8e3a-4b7e-a8d2-5aa757117658")
def test_l2_gateway_update_interface(self):
"""
Update l2gw will update info in already created l2gw. To
update l2gw we need l2gw id and payload to update.
"""
LOG.info(_LI("Testing l2_gateway_update api"))
device_name, interface_name = self.nsx_bridge_cluster_info()
l2gw_name = data_utils.rand_name(constants.L2GW)
devices = {"devices": [{"device_name": device_name,
"interfaces": [{"name": interface_name}]}]
}
# Creating l2gw.
self.operate_l2gw(name=l2gw_name, devices=devices, task="create")
# Updating Interfaces.
devices = {"devices": [
{"device_name": device_name,
"interfaces": [{"name": "new_name",
"segmentation_id": [
self.VLAN_1]}],
"deleted_interfaces": [
{"name": interface_name}]}
]
}
# Updating already created l2gw with new interface.
self.operate_l2gw(name=l2gw_name, devices=devices, task="update")
self.resource_cleanup()
@test.attr(type="nsxv3")
@test.idempotent_id("5a3cef97-c91c-4e03-92c8-d180f9269f27")
def test_l2_gateway_show(self):
"""
show l2gw based on UUID. To see l2gw info we need l2gw id.
"""
LOG.info(_LI("Testing l2_gateway_show api"))
device_name, interface_name = self.nsx_bridge_cluster_info()
l2gw_name = data_utils.rand_name(constants.L2GW)
devices = {"devices": [
{"device_name": device_name,
"interfaces": [{"name": interface_name,
"segmentation_id": [
self.VLAN_1,
self.VLAN_2]}]
}]
}
# Creating l2gw.
self.operate_l2gw(name=l2gw_name, devices=devices, task="create")
# Show already created l2gw with l2gw id.
self.operate_l2gw(name=l2gw_name, devices=devices, task="show")
self.resource_cleanup()