tests for port-resource-request

Change-Id: Ib72b01cb25ccdaa00b2b364dca7f8e485aaaf46b
Depends-On: https://review.openstack.org/590363
Partial-Bug: #1578989
See-Also: https://review.openstack.org/502306 (nova spec)
See-Also: https://review.openstack.org/508149 (neutron spec)
This commit is contained in:
Lajos Katona 2018-08-23 14:04:56 +02:00
parent fc3b314662
commit 2f90465f73
4 changed files with 176 additions and 0 deletions

View File

@ -46,6 +46,7 @@
- network-ip-availability
- network_availability_zone
- pagination
- port-resource-request
- port-mac-address-regenerate
- port-security
- port-security-groups-filtering
@ -127,6 +128,7 @@
agent_availability_zone: nova
image_is_advanced: true
available_type_drivers: flat,geneve,vlan,gre,local,vxlan
provider_net_base_segm_id: 1
irrelevant-files: &tempest-irrelevant-files
- ^(test-|)requirements.txt$
- ^releasenotes/.*$

View File

@ -14,11 +14,17 @@
# under the License.
import netaddr
import six
from neutron_lib import constants as const
from tempest.common import utils
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from neutron_tempest_plugin.api import base
from neutron_tempest_plugin import config
CONF = config.CONF
class PortTestCasesAdmin(base.BaseAdminNetworkTest):
@ -58,3 +64,126 @@ class PortTestCasesAdmin(base.BaseAdminNetworkTest):
new_mac = body['port']['mac_address']
self.assertNotEqual(current_mac, new_mac)
self.assertTrue(netaddr.valid_mac(new_mac))
class PortTestCasesResourceRequest(base.BaseAdminNetworkTest):
required_extensions = ['port-resource-request',
'qos',
'qos-bw-minimum-ingress']
EGRESS_KBPS = 1000
INGRESS_KBPS = 2000
@classmethod
def skip_checks(cls):
super(PortTestCasesResourceRequest, cls).skip_checks()
if not config.CONF.neutron_plugin_options.provider_vlans:
msg = "Skipped as provider VLANs are not available in config"
raise cls.skipException(msg)
@classmethod
def resource_setup(cls):
super(PortTestCasesResourceRequest, cls).resource_setup()
cls.vnic_type = 'normal'
# Note(lajoskatona): to avoid creating provider network use vxlan
# as provider network type:
cls.network = cls.create_network(provider_network_type='vxlan')
cls.physnet_name = CONF.neutron_plugin_options.provider_vlans[0]
base_segm = CONF.neutron_plugin_options.provider_net_base_segm_id
cls.prov_network = cls.create_provider_network(
physnet_name=cls.physnet_name, start_segmentation_id=base_segm)
def _create_qos_policy_and_port(self, network, vnic_type,
network_policy=False):
qos_policy = self.create_qos_policy(
name=data_utils.rand_name('test_policy'), shared=True)
self.create_qos_minimum_bandwidth_rule(qos_policy['id'],
self.EGRESS_KBPS,
const.EGRESS_DIRECTION)
self.create_qos_minimum_bandwidth_rule(qos_policy['id'],
self.INGRESS_KBPS,
const.INGRESS_DIRECTION)
port_policy_id = qos_policy['id'] if not network_policy else None
port_kwargs = {
'qos_policy_id': port_policy_id,
'binding:vnic_type': vnic_type
}
if network_policy:
self.admin_client.update_network(network['id'],
qos_policy_id=qos_policy['id'])
port_id = self.create_port(network, **port_kwargs)['id']
return self.admin_client.show_port(port_id)['port']
def _assert_resource_request(self, port, vnic_type):
self.assertIn('resource_request', port)
vnic_trait = 'CUSTOM_VNIC_TYPE_%s' % vnic_type.upper()
physnet_trait = 'CUSTOM_PHYSNET_%s' % self.physnet_name.upper()
six.assertCountEqual(self, [physnet_trait, vnic_trait],
port['resource_request']['required'])
self.assertEqual(
{'NET_BW_EGR_KILOBIT_PER_SEC': self.EGRESS_KBPS,
'NET_BW_IGR_KILOBIT_PER_SEC': self.INGRESS_KBPS},
port['resource_request']['resources']
)
@decorators.idempotent_id('ebb86dc4-716c-4558-8516-6dfc4a67601f')
def test_port_resource_request(self):
port = self._create_qos_policy_and_port(
network=self.prov_network, vnic_type=self.vnic_type)
port_id = port['id']
self._assert_resource_request(port, self.vnic_type)
# Note(lajoskatona): port-resource-request is an admin only feature,
# so test if non-admin user can't see the new field.
port = self.client.show_port(port_id)['port']
self.assertNotIn('resource_request', port)
self.update_port(port, **{'qos_policy_id': None})
port = self.admin_client.show_port(port_id)['port']
self.assertIsNone(port['resource_request'])
@decorators.idempotent_id('10b3308b-d8a2-459b-9b89-a146863c357f')
def test_port_resource_request_no_provider_net(self):
port = self._create_qos_policy_and_port(
network=self.network, vnic_type=self.vnic_type)
self.assertIn('resource_request', port)
self.assertIsNone(port['resource_request'])
@decorators.idempotent_id('0eeb6ffa-9a7a-40b5-83dd-dbdcd67e2e64')
def test_port_resource_request_empty(self):
qos_policy = self.create_qos_policy(
name=data_utils.rand_name('test_policy'), shared=True)
# Note(lajoskatona): Add a non-minimum-bandwidth-rule to the policy
# to make sure that the resource request is not filled with it.
self.create_qos_bandwidth_limit_rule(qos_policy['id'],
self.EGRESS_KBPS, 800,
const.EGRESS_DIRECTION)
port_kwargs = {
'qos_policy_id': qos_policy['id'],
'binding:vnic_type': self.vnic_type
}
port_id = self.create_port(self.prov_network, **port_kwargs)['id']
port = self.admin_client.show_port(port_id)['port']
self.assertIn('resource_request', port)
self.assertIsNone(port['resource_request'])
@decorators.idempotent_id('b6c34ae4-44c8-47f0-86de-7ef9866fa000')
def test_port_resource_request_inherited_policy(self):
port = self._create_qos_policy_and_port(
network=self.prov_network, vnic_type=self.vnic_type,
network_policy=True)
self._assert_resource_request(port, self.vnic_type)

View File

@ -14,10 +14,13 @@
# under the License.
import functools
import itertools
import math
import time
import netaddr
from neutron_lib import constants as const
from oslo_log import log
from tempest.common import utils as tutils
from tempest.lib.common.utils import data_utils
from tempest.lib import exceptions as lib_exc
@ -31,6 +34,8 @@ from neutron_tempest_plugin import exceptions
CONF = config.CONF
LOG = log.getLogger(__name__)
class BaseNetworkTest(test.BaseTestCase):
@ -673,6 +678,16 @@ class BaseNetworkTest(test.BaseTestCase):
cls.qos_rules.append(qos_rule)
return qos_rule
@classmethod
def create_qos_minimum_bandwidth_rule(cls, policy_id, min_kbps,
direction=const.EGRESS_DIRECTION):
"""Wrapper utility that creates and returns a QoS min bw rule."""
body = cls.admin_client.create_minimum_bandwidth_rule(
policy_id, direction, min_kbps)
qos_rule = body['minimum_bandwidth_rule']
cls.qos_rules.append(qos_rule)
return qos_rule
@classmethod
def delete_router(cls, router, client=None):
client = client or cls.client
@ -974,6 +989,32 @@ class BaseAdminNetworkTest(BaseNetworkTest):
"net(%s) has no usable IP address in allocation pools" % net_id)
raise exceptions.InvalidConfiguration(message)
@classmethod
def create_provider_network(cls, physnet_name, start_segmentation_id,
max_attempts=30):
segmentation_id = start_segmentation_id
for attempts in itertools.count():
try:
prov_network = cls.create_network(
name=data_utils.rand_name('test_net'),
shared=True,
provider_network_type='vlan',
provider_physical_network=physnet_name,
provider_segmentation_id=segmentation_id)
break
except lib_exc.Conflict:
if attempts > max_attempts:
LOG.exception("Failed to create provider network after "
"%d attempts", attempts)
raise lib_exc.TimeoutException
segmentation_id += 1
if segmentation_id > 4095:
raise lib_exc.TempestException(
"No free segmentation id was found for provider "
"network creation!")
time.sleep(CONF.network.build_interval)
return prov_network
def require_qos_rule_type(rule_type):
def decorator(f):

View File

@ -21,6 +21,10 @@ NeutronPluginOptions = [
cfg.ListOpt('provider_vlans',
default=[],
help='List of provider networks available in the deployment.'),
cfg.IntOpt('provider_net_base_segm_id',
default=3000,
help='Base segmentation ID to create provider networks. '
'This value will be increased in case of conflict.'),
cfg.BoolOpt('specify_floating_ip_address_available',
default=True,
help='Allow passing an IP Address of the floating ip when '