Add test for Neutron object versions

Adds a test to Neutron to check object versions for any changes
to objects. It prompts the developer to update the version of the
changed object. It uses oslo.versionedobjects.

Change-Id: I99454b28ae0b5fa663354eeccdf709d4030a280b
Co-Authored-By: Ryan Rossiter <rlrossit@us.ibm.com>
This commit is contained in:
Martin Hickey 2015-12-15 17:42:39 +00:00
parent b01e3084d1
commit 074268f74c
8 changed files with 81 additions and 3 deletions

View File

@ -27,6 +27,8 @@ from neutron.objects.qos import rule as rule_obj_impl
@obj_base.VersionedObjectRegistry.register
class QosPolicy(base.NeutronDbObject):
# Version 1.0: Initial version
VERSION = '1.0'
db_model = qos_db_model.QosPolicy

View File

@ -77,6 +77,8 @@ class QosRule(base.NeutronDbObject):
@obj_base.VersionedObjectRegistry.register
class QosBandwidthLimitRule(QosRule):
# Version 1.0: Initial version
VERSION = '1.0'
db_model = qos_db_model.QosBandwidthLimitRule

View File

@ -28,6 +28,8 @@ class RuleTypeField(obj_fields.BaseEnumField):
@obj_base.VersionedObjectRegistry.register
class QosRuleType(base.NeutronObject):
# Version 1.0: Initial version
VERSION = '1.0'
fields = {
'type': RuleTypeField(),

View File

@ -13,6 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import copy
import mock
from oslo_versionedobjects import base as obj_base
from oslo_versionedobjects import fields as obj_fields
@ -38,8 +40,9 @@ def _create_test_resource(context=None):
return resource
@obj_base.VersionedObjectRegistry.register
class FakeResource(objects_base.NeutronObject):
# Version 1.0: Initial version
VERSION = '1.0'
fields = {
'id': obj_fields.UUIDField(),
@ -55,8 +58,22 @@ class ResourcesRpcBaseTestCase(base.BaseTestCase):
def setUp(self):
super(ResourcesRpcBaseTestCase, self).setUp()
# TODO(mhickey) This is using temp registry pattern. The
# pattern solution is to backup the object registry, register
# a class locally, and then restore the original registry.
# Refer to https://review.openstack.org/#/c/263800/ for more
# details. This code should be updated when the patch is merged.
self._base_test_backup = copy.copy(
obj_base.VersionedObjectRegistry._registry._obj_classes)
self.addCleanup(self._restore_obj_registry)
self.context = context.get_admin_context()
def _restore_obj_registry(self):
obj_base.VersionedObjectRegistry._registry._obj_classes = (
self._base_test_backup)
class _ValidateResourceTypeTestCase(base.BaseTestCase):
def setUp(self):
@ -103,6 +120,7 @@ class ResourcesPullRpcApiTestCase(ResourcesRpcBaseTestCase):
self.assertIs(self.rpc, resources_rpc.ResourcesPullRpcApi())
def test_pull(self):
obj_base.VersionedObjectRegistry.register(FakeResource)
expected_obj = _create_test_resource(self.context)
resource_id = expected_obj.id
self.cctxt_mock.call.return_value = expected_obj.obj_to_primitive()
@ -128,6 +146,7 @@ class ResourcesPullRpcCallbackTestCase(ResourcesRpcBaseTestCase):
def setUp(self):
super(ResourcesPullRpcCallbackTestCase, self).setUp()
obj_base.VersionedObjectRegistry.register(FakeResource)
self.callbacks = resources_rpc.ResourcesPullRpcCallback()
self.resource_obj = _create_test_resource(self.context)
@ -207,6 +226,7 @@ class ResourcesPushRpcCallbackTestCase(ResourcesRpcBaseTestCase):
@mock.patch.object(resources_rpc.cons_registry, 'push')
def test_push(self, reg_push_mock):
obj_base.VersionedObjectRegistry.register(FakeResource)
self.callbacks.push(self.context, self.resource_prim, 'TYPE')
reg_push_mock.assert_called_once_with(self.resource_obj.obj_name(),
self.resource_obj, 'TYPE')

View File

@ -36,8 +36,10 @@ class FakeModel(object):
pass
@obj_base.VersionedObjectRegistry.register
@obj_base.VersionedObjectRegistry.register_if(False)
class FakeNeutronObject(base.NeutronDbObject):
# Version 1.0: Initial version
VERSION = '1.0'
db_model = FakeModel

View File

@ -0,0 +1,48 @@
# Copyright 2015 IBM Corp.
#
# 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 os
import pprint
from oslo_versionedobjects import base as obj_base
from oslo_versionedobjects import fixture
from neutron.tests import base as test_base
# NOTE: The hashes in this list should only be changed if they come with a
# corresponding version bump in the affected objects.
object_data = {
'QosBandwidthLimitRule': '1.0-4e44a8f5c2895ab1278399f87b40a13d',
'QosRuleType': '1.0-d0df298d49eeffab91af18d1a4cf7eaf',
'QosPolicy': '1.0-721fa60ea8f0e8f15d456d6e917dfe59',
}
class TestObjectVersions(test_base.BaseTestCase):
def test_versions(self):
checker = fixture.ObjectVersionChecker(
obj_base.VersionedObjectRegistry.obj_classes())
fingerprints = checker.get_hashes()
if os.getenv('GENERATE_HASHES'):
file('object_hashes.txt', 'w').write(
pprint.pformat(fingerprints))
expected, actual = checker.test_hashes(object_data)
self.assertEqual(expected, actual,
'Some objects have changed; please make sure the '
'versions have been bumped, and then update their '
'hashes in the object_data map in this test module.')

View File

@ -14,6 +14,8 @@ ignore_regexes=(
# The following vendor plugins are not required to confrm to the
# structural requirements.
"^plugins/ibm.*$"
# The following test is required for oslo.versionedobjects
"^objects/test_objects.py$"
# The following open source plugin tests are not actually unit
# tests and are ignored pending their relocation to the functional
# test tree.

View File

@ -5,7 +5,7 @@ skipsdist = True
[testenv]
setenv = VIRTUAL_ENV={envdir}
passenv = TRACE_FAILONLY
passenv = TRACE_FAILONLY GENERATE_HASHES
usedevelop = True
install_command =
constraints: {[testenv:common-constraints]install_command}