From 32da7aa3d95e5a761ea33f84268ae4a842bb55c2 Mon Sep 17 00:00:00 2001 From: Yunhong Jiang Date: Thu, 17 Apr 2014 10:57:33 -0700 Subject: [PATCH] Check object's field A nova object should have all fields as instance of fields.Field. This patch adds a check on the metaclass to make sure of it. This check happens only when class import so should have no runtime performance impact. Change-Id: I2cdf7eb097fb6907cbd048fa73138b352ab547d7 --- nova/exception.py | 4 ++++ nova/objects/base.py | 3 +++ nova/tests/objects/test_objects.py | 13 +++++++++++++ 3 files changed, 20 insertions(+) diff --git a/nova/exception.py b/nova/exception.py index ae723491f2..e2834cf106 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -1381,6 +1381,10 @@ class ObjectActionError(NovaException): msg_fmt = _('Object action %(action)s failed because: %(reason)s') +class ObjectFieldInvalid(NovaException): + msg_fmt = _('Field %(field)s of %(objname)s is not an instance of Field') + + class CoreAPIMissing(NovaException): msg_fmt = _("Core API extensions are missing: %(missing_apis)s") diff --git a/nova/objects/base.py b/nova/objects/base.py index c453fa011b..007c60f560 100644 --- a/nova/objects/base.py +++ b/nova/objects/base.py @@ -56,6 +56,9 @@ def make_class_properties(cls): if name not in cls.fields: cls.fields[name] = field for name, field in cls.fields.iteritems(): + if not isinstance(field, fields.Field): + raise exception.ObjectFieldInvalid( + field=name, objname=cls.obj_name()) def getter(self, name=name): attrname = get_attrname(name) diff --git a/nova/tests/objects/test_objects.py b/nova/tests/objects/test_objects.py index 1726fcf855..14eab6f140 100644 --- a/nova/tests/objects/test_objects.py +++ b/nova/tests/objects/test_objects.py @@ -138,6 +138,19 @@ class TestMetaclass(test.TestCase): self.assertEqual(expected, Test1._obj_classes) self.assertEqual(expected, Test2._obj_classes) + def test_field_checking(self): + def create_class(field): + class TestField(base.NovaObject): + VERSION = '1.5' + fields = {'foo': field()} + return TestField + + cls = create_class(fields.IPV4AndV6AddressField) + self.assertRaises(exception.ObjectFieldInvalid, + create_class, fields.IPV4AndV6Address) + self.assertRaises(exception.ObjectFieldInvalid, + create_class, int) + class TestObjToPrimitive(test.TestCase):