From 834681659f514040d7c78675affeb7350a0d1539 Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Mon, 3 Mar 2025 11:24:51 +0000 Subject: [PATCH] [QoS] QoS rule check also considers the direction The method ``check_bandwidth_rule_conflict`` now takes into account the rules direction when checking the compatibility between bandwidth limit and minimum bandwidth rules. Closes-Bug: #2100853 Change-Id: I21244595f501e35919a97fd048b643f951b18500 (cherry picked from commit b658c52d83fb144faee97007781fc6a16bfdb2fc) --- neutron/objects/qos/qos_policy_validator.py | 5 ++ .../objects/qos/test_qos_policy_validator.py | 53 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 neutron/tests/unit/objects/qos/test_qos_policy_validator.py diff --git a/neutron/objects/qos/qos_policy_validator.py b/neutron/objects/qos/qos_policy_validator.py index b7acfadb0d8..1a36eb9cece 100644 --- a/neutron/objects/qos/qos_policy_validator.py +++ b/neutron/objects/qos/qos_policy_validator.py @@ -25,10 +25,15 @@ def check_bandwidth_rule_conflict(policy, rule_data): doesn't conflict with the existing rules. Raises an exception if conflict is identified. """ + direction = rule_data.get('direction') for rule in policy.rules: if rule.rule_type == qos_consts.RULE_TYPE_DSCP_MARKING: # Skip checks if Rule is DSCP continue + if direction and rule.direction != direction: + # Rule check must be done within the same direction. + # DSCP rules have no direction. + continue if rule.rule_type == qos_consts.RULE_TYPE_MINIMUM_BANDWIDTH: if "max_kbps" in rule_data and ( int(rule.min_kbps) > int(rule_data["max_kbps"])): diff --git a/neutron/tests/unit/objects/qos/test_qos_policy_validator.py b/neutron/tests/unit/objects/qos/test_qos_policy_validator.py new file mode 100644 index 00000000000..7b08f9fa71a --- /dev/null +++ b/neutron/tests/unit/objects/qos/test_qos_policy_validator.py @@ -0,0 +1,53 @@ +# Copyright (c) 2025 Red Hat 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 neutron_lib import constants as lib_consts +from neutron_lib import context +from neutron_lib.exceptions import qos as qos_exc +from neutron_lib.services.qos import constants as qos_consts + +from neutron.objects.qos import policy +from neutron.objects.qos import qos_policy_validator +from neutron.objects.qos import rule +from neutron.tests.unit import testlib_api + + +class TestCheckBandwidthRuleConflict(testlib_api.SqlTestCase): + + def setUp(self): + super().setUp() + self.context = context.get_admin_context() + self.qos_policy = policy.QosPolicy(self.context) + self.qos_policy.create() + self.max_bw_egress = 10000 + self.max_bw_rule = rule.QosBandwidthLimitRule( + self.context, qos_policy_id=self.qos_policy.id, + max_kbps=self.max_bw_egress, + direction=lib_consts.EGRESS_DIRECTION) + self.max_bw_rule.create() + self.qos_policy.rules = [self.max_bw_rule] + + def test_check_bandwidth_rule_conflict_different_direction(self): + rule_data = {qos_consts.DIRECTION: lib_consts.INGRESS_DIRECTION, + qos_consts.MIN_KBPS: self.max_bw_egress + 1} + qos_policy_validator.check_bandwidth_rule_conflict( + self.qos_policy, rule_data) + + def test_check_bandwidth_rule_conflict_same_direction(self): + rule_data = {qos_consts.DIRECTION: lib_consts.EGRESS_DIRECTION, + qos_consts.MIN_KBPS: self.max_bw_egress + 1} + self.assertRaises(qos_exc.QoSRuleParameterConflict, + qos_policy_validator.check_bandwidth_rule_conflict, + self.qos_policy, rule_data)