Create the first qos basic test

Workload is created using a CentOS image with a QoS policy associated to
a network
Basic verification of the created stack is performed

Change-Id: Idf98ebf92972968722f77ef4bea7d39a2b5686bc
This commit is contained in:
Eduardo Olivares 2021-03-31 16:26:34 +02:00
parent b23243f065
commit e18d15f4e4
8 changed files with 203 additions and 1 deletions

View File

@ -55,7 +55,16 @@ OPTIONS = [
help="Host where nameservers files are located"), help="Host where nameservers files are located"),
cfg.ListOpt('nameservers_filenames', cfg.ListOpt('nameservers_filenames',
default=['/etc/resolv.conf'], default=['/etc/resolv.conf'],
help="File to parse for getting default nameservers list") help="File to parse for getting default nameservers list"),
cfg.IntOpt('bwlimit_kbps',
default=100,
help="The BW limit value configured for the QoS Policy Rule"),
cfg.StrOpt('direction',
default='egress',
help="The direction for the QoS Policy Rule"),
cfg.IntOpt('dscp_mark',
default=40,
help="The DSCP marking value for the QoS Policy Rule")
] ]

View File

@ -28,6 +28,7 @@ CentosFlavorStackFixture = _centos.CentosFlavorStackFixture
CentosImageFixture = _centos.CentosImageFixture CentosImageFixture = _centos.CentosImageFixture
CentosServerStackFixture = _centos.CentosServerStackFixture CentosServerStackFixture = _centos.CentosServerStackFixture
CentosExternalServerStackFixture = _centos.CentosExternalServerStackFixture CentosExternalServerStackFixture = _centos.CentosExternalServerStackFixture
CentosQosServerStackFixture = _centos.CentosQosServerStackFixture
CirrosFlavorStackFixture = _cirros.CirrosFlavorStackFixture CirrosFlavorStackFixture = _cirros.CirrosFlavorStackFixture
CirrosImageFixture = _cirros.CirrosImageFixture CirrosImageFixture = _cirros.CirrosImageFixture

View File

@ -57,3 +57,8 @@ class CentosServerStackFixture(_nova.ServerStackFixture):
class CentosExternalServerStackFixture(CentosServerStackFixture, class CentosExternalServerStackFixture(CentosServerStackFixture,
_nova.ExternalServerStackFixture): _nova.ExternalServerStackFixture):
pass pass
class CentosQosServerStackFixture(CentosServerStackFixture,
_nova.QosServerStackFixture):
pass

View File

@ -299,6 +299,37 @@ class NetworkWithNetMtuWriteStackFixture(NetworkStackFixture):
return dict(value_specs, mtu=self.custom_mtu_size) return dict(value_specs, mtu=self.custom_mtu_size)
@neutron.skip_if_missing_networking_extensions('qos')
class QosPolicyStackFixture(heat.HeatStackFixture):
"""Heat stack with a QoS Policy and some QoS Policy Rules
"""
has_qos_policy = True
has_bwlimit = True
has_dscp_marking = True
bwlimit_kbps = CONF.tobiko.neutron.bwlimit_kbps
bwlimit_burst_kbps = int(0.8 * bwlimit_kbps)
direction = CONF.tobiko.neutron.direction
dscp_mark = CONF.tobiko.neutron.dscp_mark
#: Heat template file
template = _hot.heat_template_file('neutron/qos.yaml')
@neutron.skip_if_missing_networking_extensions('qos')
class NetworkQosPolicyStackFixture(NetworkStackFixture):
#: stack with the qos policy for the network
qos_stack = tobiko.required_setup_fixture(QosPolicyStackFixture)
has_qos_policy = True
@property
def network_value_specs(self):
value_specs = super(NetworkQosPolicyStackFixture,
self).network_value_specs
return dict(value_specs, qos_policy_id=self.qos_stack.qos_policy_id)
@neutron.skip_if_missing_networking_extensions('security-group') @neutron.skip_if_missing_networking_extensions('security-group')
class SecurityGroupsFixture(heat.HeatStackFixture): class SecurityGroupsFixture(heat.HeatStackFixture):
"""Heat stack with some security groups """Heat stack with some security groups

View File

@ -405,6 +405,12 @@ class ExternalServerStackFixture(ServerStackFixture, abc.ABC):
return self.network_stack.network_id return self.network_stack.network_id
class QosServerStackFixture(ServerStackFixture, abc.ABC):
#: stack with the network with a qos policy
network_stack = tobiko.required_setup_fixture(
_neutron.NetworkQosPolicyStackFixture)
class PeerServerStackFixture(ServerStackFixture, abc.ABC): class PeerServerStackFixture(ServerStackFixture, abc.ABC):
"""Server witch networking access requires passing by another Nova server """Server witch networking access requires passing by another Nova server
""" """

View File

@ -88,6 +88,11 @@ parameters:
type: boolean type: boolean
default: false default: false
has_qos_policy:
description: whether qos policy is attached to the network
type: boolean
default: false
conditions: conditions:
has_ipv4: has_ipv4:
@ -117,6 +122,9 @@ conditions:
- get_param: has_l3_ha - get_param: has_l3_ha
- get_param: has_gateway - get_param: has_gateway
has_qos_policy:
get_param: has_qos_policy
resources: resources:
@ -202,3 +210,8 @@ outputs:
description: Network MTU value (integer) description: Network MTU value (integer)
value: {get_attr: [network, mtu]} value: {get_attr: [network, mtu]}
condition: has_net_mtu condition: has_net_mtu
qos_policy_id:
description: QoS Policy ID attached to the network
value: {get_attr: [network, qos_policy_id]}
condition: has_qos_policy

View File

@ -0,0 +1,86 @@
heat_template_version: newton
description: |
Creates a qos policy with two qos rules (dscp marking and bw limit)
parameters:
has_qos_policy:
type: boolean
default: false
has_bwlimit:
type: boolean
default: false
has_dscp_marking:
type: boolean
default: false
bwlimit_kbps:
type: number
bwlimit_burst_kbps:
type: number
default: 0
bwlimit_direction:
type: string
default: egress
constraints:
- allowed_values: [ egress, ingress ]
dscp_mark:
type: number
constraints:
- allowed_values: [ 0, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 46, 48, 56 ]
conditions:
has_qos_policy:
get_param: has_qos_policy
has_bwlimit:
get_param: has_bwlimit
has_dscp_marking:
get_param: has_dscp_marking
resources:
qos_policy:
type: OS::Neutron::QoSPolicy
condition: has_qos_policy
qos_bwlimit_rule:
type: OS::Neutron::QoSBandwidthLimitRule
condition: has_bwlimit
properties:
max_burst_kbps: {get_param: bwlimit_burst_kbps}
max_kbps: {get_param: bwlimit_kbps}
direction: {get_param: bwlimit_direction}
policy: {get_resource: qos_policy}
qos_dscp_rule:
type: OS::Neutron::QoSDscpMarkingRule
condition: has_dscp_marking
properties:
dscp_mark: {get_param: dscp_mark}
policy: {get_resource: qos_policy}
outputs:
qos_policy_id:
description: QoS Policy ID
value: {get_resource: qos_policy}
condition: has_qos_policy
qos_bwlimit_rule_id:
description: QoS BW limit rule ID
value: {get_resource: qos_bwlimit_rule}
condition: has_bwlimit
qos_dscp_rule_id:
description: QoS DSCP marking rule ID
value: {get_resource: qos_dscp_rule}
condition: has_dscp_marking

View File

@ -0,0 +1,51 @@
# Copyright (c) 2021 Red Hat
# 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 __future__ import absolute_import
from oslo_log import log
import testtools
import tobiko
from tobiko.openstack import stacks
from tobiko.openstack import topology
from tobiko.tripleo import containers
from tobiko.tripleo import overcloud
LOG = log.getLogger(__name__)
class QoSBasicTest(testtools.TestCase):
"""Tests QoS basic functionality"""
#: Resources stack with QoS Policy and QoS Rules and Advanced server
stack = tobiko.required_setup_fixture(stacks.CentosQosServerStackFixture)
def setUp(self):
"""Skip these tests if OVN is configured and OSP version is lower than
16.1
"""
super(QoSBasicTest, self).setUp()
if (overcloud.has_overcloud() and
topology.verify_osp_version('16.0', lower=True) and
containers.ovn_used_on_overcloud()):
self.skip("QoS not supported in this setup")
def test_qos_basic(self):
# Verify QoS Policy attached to the network corresponds with the QoS
# Policy previously created
self.assertEqual(self.stack.network_stack.qos_stack.qos_policy_id,
self.stack.network_stack.qos_policy_id)
self.assertIsNone(self.stack.port_details['qos_policy_id'])