
This patch bumps the hacking, bandit and flake8 requirements to match suit with similar work (ex [1]). It also updates the code to fix a few new pep8 errors as well as adds a local tox target for requirements-check-dev. [1] https://review.opendev.org/#/c/658245/ Change-Id: I6caeb52dc1a5842338ec989a742ae5989608e0da
357 lines
16 KiB
Python
357 lines
16 KiB
Python
# 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 mock
|
|
|
|
from neutron_lib import context
|
|
from neutron_lib import exceptions
|
|
from neutron_lib.objects import registry as obj_reg
|
|
from oslo_config import cfg
|
|
from oslo_utils import uuidutils
|
|
|
|
from neutron.services.qos import qos_plugin
|
|
from neutron.tests.unit.services.qos import base
|
|
|
|
from vmware_nsx.common import utils
|
|
from vmware_nsx.plugins.nsx_v3 import utils as v3_utils
|
|
from vmware_nsx.services.qos.nsx_v3 import driver as qos_driver
|
|
from vmware_nsx.services.qos.nsx_v3 import pol_utils as qos_utils
|
|
from vmware_nsx.tests.unit.nsx_p import test_plugin
|
|
from vmware_nsxlib.v3.policy import core_defs as policy_defs
|
|
|
|
PLUGIN_NAME = 'vmware_nsx.plugins.nsx_p.plugin.NsxPolicyPlugin'
|
|
QoSPolicy = obj_reg.load_class('QosPolicy')
|
|
QosBandwidthLimitRule = obj_reg.load_class('QosBandwidthLimitRule')
|
|
QosDscpMarkingRule = obj_reg.load_class('QosDscpMarkingRule')
|
|
QosMinimumBandwidthRule = obj_reg.load_class('QosMinimumBandwidthRule')
|
|
|
|
|
|
class TestQosNsxPNotification(base.BaseQosTestCase,
|
|
test_plugin.NsxPPluginTestCaseMixin):
|
|
|
|
def setUp(self):
|
|
# Reset the drive to re-create it
|
|
qos_driver.DRIVER = None
|
|
super(TestQosNsxPNotification, self).setUp()
|
|
self.setup_coreplugin(PLUGIN_NAME)
|
|
|
|
self.qos_plugin = qos_plugin.QoSPlugin()
|
|
self.ctxt = context.Context('fake_user', 'fake_tenant')
|
|
mock.patch.object(self.ctxt.session, 'refresh').start()
|
|
mock.patch.object(self.ctxt.session, 'expunge').start()
|
|
policy_id = uuidutils.generate_uuid()
|
|
self.project_id = uuidutils.generate_uuid()
|
|
self.policy_data = {
|
|
'policy': {'id': policy_id,
|
|
'project_id': self.project_id,
|
|
'name': 'test-policy',
|
|
'description': 'Test policy description',
|
|
'shared': True}}
|
|
self.rule_data = {
|
|
'bandwidth_limit_rule': {'id': uuidutils.generate_uuid(),
|
|
'max_kbps': 2000,
|
|
'max_burst_kbps': 150}}
|
|
self.ingress_rule_data = {
|
|
'bandwidth_limit_rule': {'id': uuidutils.generate_uuid(),
|
|
'max_kbps': 3000,
|
|
'max_burst_kbps': 350,
|
|
'direction': 'ingress'}}
|
|
self.dscp_rule_data = {
|
|
'dscp_marking_rule': {'id': uuidutils.generate_uuid(),
|
|
'dscp_mark': 22}}
|
|
|
|
self.policy = QoSPolicy(
|
|
self.ctxt, **self.policy_data['policy'])
|
|
|
|
# egress BW limit rule
|
|
self.rule = QosBandwidthLimitRule(
|
|
self.ctxt, **self.rule_data['bandwidth_limit_rule'])
|
|
# ingress bw limit rule
|
|
self.ingress_rule = QosBandwidthLimitRule(
|
|
self.ctxt, **self.ingress_rule_data['bandwidth_limit_rule'])
|
|
self.dscp_rule = QosDscpMarkingRule(
|
|
self.ctxt, **self.dscp_rule_data['dscp_marking_rule'])
|
|
|
|
self.fake_profile = {'id': policy_id}
|
|
|
|
mock.patch('neutron.objects.db.api.create_object').start()
|
|
mock.patch('neutron.objects.db.api.update_object').start()
|
|
mock.patch('neutron.objects.db.api.delete_object').start()
|
|
|
|
self.peak_bw_multiplier = cfg.CONF.NSX.qos_peak_bw_multiplier
|
|
|
|
self.nsxlib = v3_utils.get_nsxlib_wrapper()
|
|
|
|
def _get_expected_tags(self):
|
|
policy_dict = {'id': self.policy.id, 'tenant_id': self.project_id}
|
|
return self.nsxlib.build_v3_tags_payload(
|
|
policy_dict, resource_type='os-neutron-qos-id',
|
|
project_name=self.ctxt.tenant_name)
|
|
|
|
@mock.patch.object(QoSPolicy, 'create_rbac_policy')
|
|
def test_policy_create_profile(self, *mocks):
|
|
# test the profile creation when a QoS policy is created
|
|
with mock.patch('vmware_nsxlib.v3.policy.core_resources.'
|
|
'NsxQosProfileApi.create_or_overwrite',
|
|
return_value=self.fake_profile) as create_profile,\
|
|
mock.patch.object(QoSPolicy, 'get_object',
|
|
return_value=self.policy),\
|
|
mock.patch.object(QoSPolicy, 'create'):
|
|
self.qos_plugin.create_policy(self.ctxt, self.policy_data)
|
|
exp_name = utils.get_name_and_uuid(self.policy.name,
|
|
self.policy.id)
|
|
|
|
create_profile.assert_called_once_with(
|
|
exp_name,
|
|
profile_id=self.policy.id,
|
|
description=self.policy_data["policy"]["description"],
|
|
dscp=None,
|
|
shaper_configurations=[],
|
|
tags=self._get_expected_tags())
|
|
|
|
@mock.patch.object(QoSPolicy, '_reload_rules')
|
|
def test_bw_rule_create_profile(self, *mocks):
|
|
# test the profile update when an egress QoS BW rule is created
|
|
_policy = QoSPolicy(
|
|
self.ctxt, **self.policy_data['policy'])
|
|
# add a rule to the policy
|
|
setattr(_policy, "rules", [self.rule])
|
|
with mock.patch.object(QoSPolicy, 'get_object', return_value=_policy),\
|
|
mock.patch('vmware_nsxlib.v3.policy.core_resources.'
|
|
'NsxQosProfileApi.'
|
|
'create_or_overwrite') as create_profile,\
|
|
mock.patch('neutron.objects.db.api.update_object',
|
|
return_value=self.rule_data):
|
|
self.qos_plugin.update_policy_bandwidth_limit_rule(
|
|
self.ctxt, self.rule.id, _policy.id, self.rule_data)
|
|
|
|
# validate the data on the profile
|
|
rule_dict = self.rule_data['bandwidth_limit_rule']
|
|
expected_bw = int(round(float(
|
|
rule_dict['max_kbps']) / 1024))
|
|
expected_burst = rule_dict['max_burst_kbps'] * 128
|
|
expected_peak = int(expected_bw * self.peak_bw_multiplier)
|
|
exp_name = utils.get_name_and_uuid(self.policy.name,
|
|
self.policy.id)
|
|
# egress neutron rule -> ingress nsx args
|
|
shaper_type = policy_defs.QoSRateLimiter.INGRESS_RATE_LIMITER_TYPE
|
|
expected_shaper = policy_defs.QoSRateLimiter(
|
|
resource_type=shaper_type,
|
|
enabled=True,
|
|
burst_size=expected_burst,
|
|
peak_bandwidth=expected_peak,
|
|
average_bandwidth=expected_bw)
|
|
create_profile.assert_called_once_with(
|
|
exp_name,
|
|
profile_id=self.policy.id,
|
|
description=self.policy_data["policy"]["description"],
|
|
dscp=None,
|
|
shaper_configurations=[mock.ANY],
|
|
tags=self._get_expected_tags())
|
|
# Compare the shaper
|
|
actual_shaper = create_profile.call_args[1][
|
|
'shaper_configurations'][0]
|
|
self.assertEqual(expected_shaper.get_obj_dict(),
|
|
actual_shaper.get_obj_dict())
|
|
|
|
@mock.patch.object(QoSPolicy, '_reload_rules')
|
|
def test_ingress_bw_rule_create_profile(self, *mocks):
|
|
# test the profile update when a ingress QoS BW rule is created
|
|
_policy = QoSPolicy(
|
|
self.ctxt, **self.policy_data['policy'])
|
|
# add a rule to the policy
|
|
setattr(_policy, "rules", [self.ingress_rule])
|
|
with mock.patch.object(QoSPolicy, 'get_object', return_value=_policy),\
|
|
mock.patch('vmware_nsxlib.v3.policy.core_resources.'
|
|
'NsxQosProfileApi.'
|
|
'create_or_overwrite') as create_profile,\
|
|
mock.patch('neutron.objects.db.api.update_object',
|
|
return_value=self.ingress_rule_data):
|
|
self.qos_plugin.update_policy_bandwidth_limit_rule(
|
|
self.ctxt, self.ingress_rule.id, _policy.id,
|
|
self.ingress_rule_data)
|
|
|
|
# validate the data on the profile
|
|
rule_dict = self.ingress_rule_data['bandwidth_limit_rule']
|
|
expected_bw = int(round(float(
|
|
rule_dict['max_kbps']) / 1024))
|
|
expected_burst = rule_dict['max_burst_kbps'] * 128
|
|
expected_peak = int(expected_bw * self.peak_bw_multiplier)
|
|
exp_name = utils.get_name_and_uuid(self.policy.name,
|
|
self.policy.id)
|
|
# ingress neutron rule -> egress nsx args
|
|
shaper_type = policy_defs.QoSRateLimiter.EGRESS_RATE_LIMITER_TYPE
|
|
expected_shaper = policy_defs.QoSRateLimiter(
|
|
resource_type=shaper_type,
|
|
enabled=True,
|
|
burst_size=expected_burst,
|
|
peak_bandwidth=expected_peak,
|
|
average_bandwidth=expected_bw)
|
|
create_profile.assert_called_once_with(
|
|
exp_name,
|
|
profile_id=self.policy.id,
|
|
description=self.policy_data["policy"]["description"],
|
|
dscp=None,
|
|
shaper_configurations=[mock.ANY],
|
|
tags=self._get_expected_tags())
|
|
# Compare the shaper
|
|
actual_shaper = create_profile.call_args[1][
|
|
'shaper_configurations'][0]
|
|
self.assertEqual(expected_shaper.get_obj_dict(),
|
|
actual_shaper.get_obj_dict())
|
|
|
|
@mock.patch.object(QoSPolicy, '_reload_rules')
|
|
def test_bw_rule_create_profile_minimal_val(self, *mocks):
|
|
# test driver precommit with an invalid limit value
|
|
bad_limit = qos_utils.MAX_KBPS_MIN_VALUE - 1
|
|
rule_data = {
|
|
'bandwidth_limit_rule': {'id': uuidutils.generate_uuid(),
|
|
'max_kbps': bad_limit,
|
|
'max_burst_kbps': 150}}
|
|
|
|
rule = QosBandwidthLimitRule(
|
|
self.ctxt, **rule_data['bandwidth_limit_rule'])
|
|
|
|
_policy = QoSPolicy(
|
|
self.ctxt, **self.policy_data['policy'])
|
|
# add a rule to the policy
|
|
setattr(_policy, "rules", [rule])
|
|
with mock.patch.object(QoSPolicy, 'get_object',
|
|
return_value=_policy),\
|
|
mock.patch('neutron.objects.db.api.update_object',
|
|
return_value=rule_data):
|
|
self.assertRaises(
|
|
exceptions.DriverCallError,
|
|
self.qos_plugin.update_policy_bandwidth_limit_rule,
|
|
self.ctxt, rule.id, _policy.id, rule_data)
|
|
|
|
@mock.patch.object(QoSPolicy, '_reload_rules')
|
|
def test_bw_rule_create_profile_maximal_val(self, *mocks):
|
|
# test driver precommit with an invalid burst value
|
|
bad_burst = qos_utils.MAX_BURST_MAX_VALUE + 1
|
|
rule_data = {
|
|
'bandwidth_limit_rule': {'id': uuidutils.generate_uuid(),
|
|
'max_kbps': 1025,
|
|
'max_burst_kbps': bad_burst}}
|
|
|
|
rule = QosBandwidthLimitRule(
|
|
self.ctxt, **rule_data['bandwidth_limit_rule'])
|
|
|
|
_policy = QoSPolicy(
|
|
self.ctxt, **self.policy_data['policy'])
|
|
# add a rule to the policy
|
|
setattr(_policy, "rules", [rule])
|
|
with mock.patch.object(
|
|
QoSPolicy, 'get_object', return_value=_policy), mock.patch(
|
|
'neutron.objects.db.api.update_object',
|
|
return_value=rule_data):
|
|
self.assertRaises(
|
|
exceptions.DriverCallError,
|
|
self.qos_plugin.update_policy_bandwidth_limit_rule,
|
|
self.ctxt, rule.id, _policy.id, rule_data)
|
|
|
|
@mock.patch.object(QoSPolicy, '_reload_rules')
|
|
def test_dscp_rule_create_profile(self, *mocks):
|
|
# test the profile update when a QoS DSCP rule is created
|
|
_policy = QoSPolicy(
|
|
self.ctxt, **self.policy_data['policy'])
|
|
# add a rule to the policy
|
|
setattr(_policy, "rules", [self.dscp_rule])
|
|
with mock.patch.object(QoSPolicy, 'get_object', return_value=_policy),\
|
|
mock.patch('vmware_nsxlib.v3.policy.core_resources.'
|
|
'NsxQosProfileApi.'
|
|
'create_or_overwrite') as create_profile,\
|
|
mock.patch('neutron.objects.db.api.update_object',
|
|
return_value=self.dscp_rule_data):
|
|
self.qos_plugin.update_policy_dscp_marking_rule(
|
|
self.ctxt, self.dscp_rule.id,
|
|
_policy.id, self.dscp_rule_data)
|
|
|
|
# validate the data on the profile
|
|
rule_dict = self.dscp_rule_data['dscp_marking_rule']
|
|
dscp_mark = rule_dict['dscp_mark']
|
|
|
|
exp_name = utils.get_name_and_uuid(self.policy.name,
|
|
self.policy.id)
|
|
expected_dscp = policy_defs.QoSDscp(
|
|
mode=policy_defs.QoSDscp.QOS_DSCP_UNTRUSTED,
|
|
priority=dscp_mark)
|
|
create_profile.assert_called_once_with(
|
|
exp_name,
|
|
profile_id=self.policy.id,
|
|
description=self.policy_data["policy"]["description"],
|
|
dscp=mock.ANY,
|
|
shaper_configurations=[],
|
|
tags=self._get_expected_tags())
|
|
# Compare the dscp obj
|
|
actual_dscp = create_profile.call_args[1]['dscp']
|
|
self.assertEqual(expected_dscp.get_obj_dict(),
|
|
actual_dscp.get_obj_dict())
|
|
|
|
@mock.patch.object(QoSPolicy, '_reload_rules')
|
|
def test_minimum_bw_rule_create_profile(self, *mocks):
|
|
# Minimum BW rules are not supported
|
|
policy = QoSPolicy(
|
|
self.ctxt, **self.policy_data['policy'])
|
|
min_bw_rule_data = {
|
|
'minimum_bandwidth_rule': {'id': uuidutils.generate_uuid(),
|
|
'min_kbps': 10,
|
|
'direction': 'egress'}}
|
|
min_bw_rule = QosMinimumBandwidthRule(
|
|
self.ctxt, **min_bw_rule_data['minimum_bandwidth_rule'])
|
|
# add a rule to the policy
|
|
setattr(policy, "rules", [min_bw_rule])
|
|
with mock.patch.object(
|
|
QoSPolicy, 'get_object', return_value=policy),\
|
|
mock.patch('neutron.objects.db.api.'
|
|
'update_object', return_value=self.dscp_rule_data):
|
|
self.assertRaises(
|
|
exceptions.DriverCallError,
|
|
self.qos_plugin.update_policy_minimum_bandwidth_rule,
|
|
self.ctxt, min_bw_rule.id,
|
|
policy.id, min_bw_rule_data)
|
|
|
|
def test_rule_delete_profile(self):
|
|
# test the profile update when a QoS rule is deleted
|
|
_policy = QoSPolicy(
|
|
self.ctxt, **self.policy_data['policy'])
|
|
# The mock will return the policy without the rule,
|
|
# as if it was deleted
|
|
with mock.patch.object(QoSPolicy, 'get_object', return_value=_policy),\
|
|
mock.patch('vmware_nsxlib.v3.policy.core_resources.'
|
|
'NsxQosProfileApi.'
|
|
'create_or_overwrite') as set_profile:
|
|
setattr(_policy, "rules", [self.rule])
|
|
self.qos_plugin.delete_policy_bandwidth_limit_rule(
|
|
self.ctxt, self.rule.id, self.policy.id)
|
|
# validate the data on the profile
|
|
exp_name = utils.get_name_and_uuid(self.policy.name,
|
|
self.policy.id)
|
|
|
|
set_profile.assert_called_once_with(
|
|
exp_name,
|
|
profile_id=self.policy.id,
|
|
description=self.policy_data["policy"]["description"],
|
|
dscp=None,
|
|
shaper_configurations=[],
|
|
tags=self._get_expected_tags())
|
|
|
|
@mock.patch('neutron.objects.db.api.get_object', return_value=None)
|
|
def test_policy_delete_profile(self, *mocks):
|
|
# test the profile deletion when a QoS policy is deleted
|
|
with mock.patch('vmware_nsxlib.v3.policy.core_resources.'
|
|
'NsxQosProfileApi.delete') as delete_profile:
|
|
self.qos_plugin.delete_policy(self.ctxt, self.policy.id)
|
|
delete_profile.assert_called_once_with(self.policy.id)
|