diff --git a/neutron/objects/qos/rule.py b/neutron/objects/qos/rule.py index 67b332e9e4d..3f188fe67e4 100644 --- a/neutron/objects/qos/rule.py +++ b/neutron/objects/qos/rule.py @@ -17,7 +17,9 @@ import abc import sys from neutron_lib import constants +from oslo_utils import versionutils from oslo_versionedobjects import base as obj_base +from oslo_versionedobjects import exception from oslo_versionedobjects import fields as obj_fields import six @@ -107,4 +109,11 @@ class QosDscpMarkingRule(QosRule): DSCP_MARK: common_types.DscpMarkField(), } - rule_type = qos_consts.RULE_TYPE_DSCP_MARK + rule_type = qos_consts.RULE_TYPE_DSCP_MARKING + + def obj_make_compatible(self, primitive, target_version): + _target_version = versionutils.convert_version_to_tuple(target_version) + if _target_version < (1, 1): + raise exception.IncompatibleObjectVersion( + objver=target_version, + objname="QosDscpMarkingRule") diff --git a/neutron/objects/qos/rule_type.py b/neutron/objects/qos/rule_type.py index 8014a2edd45..6e1da707bf4 100644 --- a/neutron/objects/qos/rule_type.py +++ b/neutron/objects/qos/rule_type.py @@ -32,7 +32,6 @@ class QosRuleType(base.NeutronObject): # Version 1.1: Added DscpMarkingRule VERSION = '1.1' - #TODO(davidsha) add obj_make_compatible and associated tests. fields = { 'type': RuleTypeField(), } diff --git a/neutron/plugins/ml2/drivers/openvswitch/mech_driver/mech_openvswitch.py b/neutron/plugins/ml2/drivers/openvswitch/mech_driver/mech_openvswitch.py index 22c8ad451a0..88740debf78 100644 --- a/neutron/plugins/ml2/drivers/openvswitch/mech_driver/mech_openvswitch.py +++ b/neutron/plugins/ml2/drivers/openvswitch/mech_driver/mech_openvswitch.py @@ -42,7 +42,7 @@ class OpenvswitchMechanismDriver(mech_agent.SimpleAgentMechanismDriverBase): """ supported_qos_rule_types = [qos_consts.RULE_TYPE_BANDWIDTH_LIMIT, - qos_consts.RULE_TYPE_DSCP_MARK] + qos_consts.RULE_TYPE_DSCP_MARKING] def __init__(self): sg_enabled = securitygroups_rpc.is_firewall_enabled() diff --git a/neutron/services/qos/qos_consts.py b/neutron/services/qos/qos_consts.py index 662857a893d..3f3d864257e 100644 --- a/neutron/services/qos/qos_consts.py +++ b/neutron/services/qos/qos_consts.py @@ -14,8 +14,8 @@ # under the License. RULE_TYPE_BANDWIDTH_LIMIT = 'bandwidth_limit' -RULE_TYPE_DSCP_MARK = 'dscp_marking' -VALID_RULE_TYPES = [RULE_TYPE_BANDWIDTH_LIMIT, RULE_TYPE_DSCP_MARK] +RULE_TYPE_DSCP_MARKING = 'dscp_marking' +VALID_RULE_TYPES = [RULE_TYPE_BANDWIDTH_LIMIT, RULE_TYPE_DSCP_MARKING] QOS_POLICY_ID = 'qos_policy_id' diff --git a/neutron/tests/fullstack/test_qos.py b/neutron/tests/fullstack/test_qos.py index 3662f7eba84..98816c13809 100644 --- a/neutron/tests/fullstack/test_qos.py +++ b/neutron/tests/fullstack/test_qos.py @@ -190,7 +190,7 @@ class TestDscpMarkingQoS(BaseQoSRuleTestCase): rule = self.safe_client.create_dscp_marking_rule( self.tenant_id, qos_policy_id, dscp_mark) # Make it consistent with GET reply - rule['type'] = qos_consts.RULE_TYPE_DSCP_MARK + rule['type'] = qos_consts.RULE_TYPE_DSCP_MARKING rule['qos_policy_id'] = qos_policy_id qos_policy['rules'].append(rule) diff --git a/neutron/tests/tempest/api/test_qos.py b/neutron/tests/tempest/api/test_qos.py index 6c6a95a5842..313715d042c 100644 --- a/neutron/tests/tempest/api/test_qos.py +++ b/neutron/tests/tempest/api/test_qos.py @@ -737,7 +737,7 @@ class QosDscpMarkingRuleTestJSON(base.BaseAdminNetworkTest): policy_rules = retrieved_policy['policy']['rules'] self.assertEqual(1, len(policy_rules)) self.assertEqual(rule['id'], policy_rules[0]['id']) - self.assertEqual(qos_consts.RULE_TYPE_DSCP_MARK, + self.assertEqual(qos_consts.RULE_TYPE_DSCP_MARKING, policy_rules[0]['type']) @test.idempotent_id('08553ffe-030f-4037-b486-7e0b8fb9385a') diff --git a/neutron/tests/unit/objects/qos/test_policy.py b/neutron/tests/unit/objects/qos/test_policy.py index 51336a65bdb..81725afda7e 100644 --- a/neutron/tests/unit/objects/qos/test_policy.py +++ b/neutron/tests/unit/objects/qos/test_policy.py @@ -384,10 +384,10 @@ class QosPolicyDbObjectTestCase(test_base.BaseDbObjectTestCase, self.assertIn(rule_obj_band, policy_obj_v1_1.rules) self.assertIn(rule_obj_dscp, policy_obj_v1_1.rules) - self.assertEqual(policy_obj.VERSION, '1.1') - #TODO(davidsha) add testing for object version incrementation def test_object_version_degradation_1_1_to_1_0(self): + #NOTE(mangelajo): we should not check .VERSION, since that's the + # local version on the class definition policy_obj, rule_obj_band, rule_obj_dscp = ( self._create_test_policy_with_bw_and_dscp()) @@ -395,8 +395,6 @@ class QosPolicyDbObjectTestCase(test_base.BaseDbObjectTestCase, self.assertIn(rule_obj_band, policy_obj_v1_0.rules) self.assertNotIn(rule_obj_dscp, policy_obj_v1_0.rules) - #NOTE(mangelajo): we should not check .VERSION, since that's the - # local version on the class definition def test_filter_by_shared(self): policy_obj = policy.QosPolicy( diff --git a/neutron/tests/unit/objects/qos/test_rule.py b/neutron/tests/unit/objects/qos/test_rule.py index 60c56e290f9..18d7b69a29a 100644 --- a/neutron/tests/unit/objects/qos/test_rule.py +++ b/neutron/tests/unit/objects/qos/test_rule.py @@ -12,6 +12,8 @@ from neutron_lib import constants +from oslo_versionedobjects import exception + from neutron.objects.qos import policy from neutron.objects.qos import rule from neutron.services.qos import qos_consts @@ -91,6 +93,19 @@ class QosDscpMarkingRuleObjectTestCase(test_base.BaseObjectIfaceTestCase): _test_class = rule.QosDscpMarkingRule + def test_dscp_object_version_degradation(self): + dscp_rule = rule.QosDscpMarkingRule() + + self.assertRaises(exception.IncompatibleObjectVersion, + dscp_rule.obj_to_primitive, '1.0') + + def test_dscp_object_version(self): + dscp_rule = rule.QosDscpMarkingRule() + + prim = dscp_rule.obj_to_primitive('1.1') + + self.assertTrue(prim) + class QosDscpMarkingRuleDbObjectTestCase(test_base.BaseDbObjectTestCase, testlib_api.SqlTestCase): diff --git a/neutron/tests/unit/objects/qos/test_rule_type.py b/neutron/tests/unit/objects/qos/test_rule_type.py index b9a31590395..67fc0ef3089 100644 --- a/neutron/tests/unit/objects/qos/test_rule_type.py +++ b/neutron/tests/unit/objects/qos/test_rule_type.py @@ -44,3 +44,19 @@ class QosRuleTypeObjectTestCase(test_base.BaseTestCase): def test_wrong_type(self): self.assertRaises(ValueError, rule_type.QosRuleType, type='bad_type') + + @staticmethod + def _policy_through_version(obj, version): + primitive = obj.obj_to_primitive(target_version=version) + return rule_type.QosRuleType.clean_obj_from_primitive(primitive) + + def test_object_version(self): + qos_rule_type = rule_type.QosRuleType() + rule_type_v1_1 = self._policy_through_version(qos_rule_type, '1.1') + + self.assertIn(qos_consts.RULE_TYPE_BANDWIDTH_LIMIT, + tuple(rule_type_v1_1.fields['type'].AUTO_TYPE. + _valid_values)) + self.assertIn(qos_consts.RULE_TYPE_DSCP_MARKING, + tuple(rule_type_v1_1.fields['type'].AUTO_TYPE. + _valid_values)) diff --git a/releasenotes/notes/dscp-qos-77ea9b27d3762e48.yaml b/releasenotes/notes/dscp-qos-77ea9b27d3762e48.yaml index 85664d9cbdc..5b4a1f2fab1 100644 --- a/releasenotes/notes/dscp-qos-77ea9b27d3762e48.yaml +++ b/releasenotes/notes/dscp-qos-77ea9b27d3762e48.yaml @@ -6,6 +6,6 @@ prelude: > features: - Neutron can apply a QoS rule to ports that mark outgoing traffic's type of service packet header field. - - The Open vSwitch Neutron agent has been extended to mark the type of - service packet header field of packets egressing from the VM when the + - The Open vSwitch Neutron agent has been extended to mark the Type of + Service IP header field of packets egressing from the VM when the QoS rule has been applied.