Add StableObjectJsonFixture and use it in our base test class

This will ensure that our object JSON is stable during unit tests.
Specifically, the changes field, which is listified from a set, which
can vary in order.

Closes-Bug: #1545177
Change-Id: Ib40ca16c41d5422c18f4fc7d658273a8059100ab
This commit is contained in:
Dan Smith
2016-02-11 11:48:13 -08:00
parent 7ba2f29463
commit b8296d82a0
3 changed files with 44 additions and 0 deletions

View File

@@ -226,6 +226,8 @@ class TestCase(testtools.TestCase):
objects_base.NovaObjectRegistry._registry._obj_classes)
self.addCleanup(self._restore_obj_registry)
self.useFixture(nova_fixtures.StableObjectJsonFixture())
# NOTE(mnaser): All calls to utils.is_neutron() are cached in
# nova.utils._IS_NEUTRON. We set it to None to avoid any
# caching of that value.

View File

@@ -446,3 +446,31 @@ class BannedDBSchemaOperations(fixtures.Fixture):
self.useFixture(fixtures.MonkeyPatch(
'sqlalchemy.%s.alter' % thing,
lambda *a, **k: self._explode(thing, 'alter')))
class StableObjectJsonFixture(fixtures.Fixture):
"""Fixture that makes sure we get stable JSON object representations.
Since objects contain things like set(), which can't be converted to
JSON, we have some situations where the representation isn't fully
deterministic. This doesn't matter at all at runtime, but does to
unit tests that try to assert things at a low level.
This fixture mocks the obj_to_primitive() call and makes sure to
sort the list of changed fields (which came from a set) before
returning it to the caller.
"""
def __init__(self):
self._original_otp = obj_base.NovaObject.obj_to_primitive
def setUp(self):
super(StableObjectJsonFixture, self).setUp()
def _doit(obj, *args, **kwargs):
result = self._original_otp(obj, *args, **kwargs)
if 'nova_object.changes' in result:
result['nova_object.changes'].sort()
return result
self.useFixture(fixtures.MonkeyPatch(
'nova.objects.base.NovaObject.obj_to_primitive', _doit))

View File

@@ -331,3 +331,17 @@ class TestBannedDBSchemaOperations(testtools.TestCase):
table.drop)
self.assertRaises(exception.DBNotAllowed,
table.alter)
class TestStableObjectJsonFixture(testtools.TestCase):
def test_changes_sort(self):
class TestObject(obj_base.NovaObject):
def obj_what_changed(self):
return ['z', 'a']
obj = TestObject()
self.assertEqual(['z', 'a'],
obj.obj_to_primitive()['nova_object.changes'])
with fixtures.StableObjectJsonFixture():
self.assertEqual(['a', 'z'],
obj.obj_to_primitive()['nova_object.changes'])