Merge "Add ability to pass args/kwargs to obj_class init"

This commit is contained in:
Jenkins 2016-01-29 21:09:43 +00:00 committed by Gerrit Code Review
commit 8e5a40a977
3 changed files with 79 additions and 10 deletions

@ -299,7 +299,10 @@ class ObjectVersionChecker(object):
return expected, actual
def _test_object_compatibility(self, obj_class, manifest=None):
def _test_object_compatibility(self, obj_class, manifest=None,
init_args=None, init_kwargs=None):
init_args = init_args or []
init_kwargs = init_kwargs or {}
version = vutils.convert_version_to_tuple(obj_class.VERSION)
kwargs = {'version_manifest': manifest} if manifest else {}
for n in range(version[1] + 1):
@ -307,14 +310,31 @@ class ObjectVersionChecker(object):
LOG.info('testing obj: %s version: %s' %
(obj_class.obj_name(), test_version))
kwargs['target_version'] = test_version
obj_class().obj_to_primitive(**kwargs)
obj_class(*init_args, **init_kwargs).obj_to_primitive(**kwargs)
def test_compatibility_routines(self, use_manifest=False):
def test_compatibility_routines(self, use_manifest=False, init_args=None,
init_kwargs=None):
"""Test obj_make_compatible() on all object classes.
:param use_manifest: a boolean that determines if the version
manifest should be passed to obj_make_compatible
:param init_args: a dictionary of the format {obj_class: [arg1, arg2]}
that will be used to pass arguments to init on the
given obj_class. If no args are needed, the
obj_class does not need to be added to the dict
:param init_kwargs: a dictionary of the format
{obj_class: {'kwarg1': val1}} that will be used to
pass kwargs to init on the given obj_class. If no
kwargs are needed, the obj_class does not need to
be added to the dict
"""
# Iterate all object classes and verify that we can run
# obj_make_compatible with every older version than current.
# This doesn't actually test the data conversions, but it at least
# makes sure the method doesn't blow up on something basic like
# expecting the wrong version format.
init_args = init_args or {}
init_kwargs = init_kwargs or {}
for obj_name in self.obj_classes:
obj_classes = self.obj_classes[obj_name]
if use_manifest:
@ -323,7 +343,11 @@ class ObjectVersionChecker(object):
manifest = None
for obj_class in obj_classes:
self._test_object_compatibility(obj_class, manifest=manifest)
args_for_init = init_args.get(obj_class, [])
kwargs_for_init = init_kwargs.get(obj_class, {})
self._test_object_compatibility(obj_class, manifest=manifest,
init_args=args_for_init,
init_kwargs=kwargs_for_init)
def _test_relationships_in_order(self, obj_class):
for field, versions in obj_class.obj_relationships.items():

@ -354,7 +354,8 @@ class TestObjectVersionChecker(test.TestCase):
with mock.patch.object(self.ovc, '_test_object_compatibility') as toc:
self.ovc.test_compatibility_routines()
toc.assert_called_once_with(MyObject, manifest=None)
toc.assert_called_once_with(MyObject, manifest=None, init_args=[],
init_kwargs={})
def test_test_compatibility_routines_with_manifest(self):
# Make sure test_compatibility_routines() uses the version manifest
@ -368,7 +369,21 @@ class TestObjectVersionChecker(test.TestCase):
self.ovc.test_compatibility_routines(use_manifest=True)
otgv.assert_called_once_with(MyObject.__name__)
toc.assert_called_once_with(MyObject, manifest=man)
toc.assert_called_once_with(MyObject, manifest=man, init_args=[],
init_kwargs={})
def test_test_compatibility_routines_with_args_kwargs(self):
# Make sure test_compatibility_routines() uses init args/kwargs
del self.ovc.obj_classes[MyObject2.__name__]
init_args = {MyObject: [1]}
init_kwargs = {MyObject: {'foo': 'bar'}}
with mock.patch.object(self.ovc, '_test_object_compatibility') as toc:
self.ovc.test_compatibility_routines(init_args=init_args,
init_kwargs=init_kwargs)
toc.assert_called_once_with(MyObject, manifest=None, init_args=[1],
init_kwargs={'foo': 'bar'})
def test_test_relationships_in_order(self):
# Make sure test_relationships_in_order() tests the relationships
@ -547,6 +562,32 @@ class TestObjectVersionChecker(test.TestCase):
"_test_object_compatibility() did not test "
"obj_to_primitive() on the correct target versions")
def test_test_object_compatibility_args_kwargs(self):
# Make sure _test_object_compatibility() tests obj_to_primitive()
# with the correct args and kwargs to init
to_prim = mock.MagicMock(spec=callable)
MyObject.obj_to_primitive = to_prim
MyObject.VERSION = '1.1'
args = [1]
kwargs = {'foo': 'bar'}
with mock.patch.object(MyObject, '__init__',
return_value=None) as mock_init:
self.ovc._test_object_compatibility(MyObject, init_args=args,
init_kwargs=kwargs)
expected_init = ((1,), {'foo': 'bar'})
expected_init_calls = [expected_init, expected_init]
self.assertEqual(expected_init_calls, mock_init.call_args_list,
"_test_object_compatibility() did not call "
"__init__() properly on the object")
expected_to_prim = [((), {'target_version': '1.0'}),
((), {'target_version': '1.1'})]
self.assertEqual(expected_to_prim, to_prim.call_args_list,
"_test_object_compatibility() did not test "
"obj_to_primitive() on the correct target versions")
def _add_class(self, obj_classes, cls):
obj_classes[cls.__name__] = [cls]

@ -596,10 +596,14 @@ class TestFixture(_BaseTestCase):
def test(mock_compat):
checker.test_compatibility_routines()
mock_compat.assert_has_calls(
[mock.call(mock.sentinel.impl_one_one, manifest=None),
mock.call(mock.sentinel.impl_one_two, manifest=None),
mock.call(mock.sentinel.impl_two_one, manifest=None),
mock.call(mock.sentinel.impl_two_two, manifest=None)],
[mock.call(mock.sentinel.impl_one_one, manifest=None,
init_args=[], init_kwargs={}),
mock.call(mock.sentinel.impl_one_two, manifest=None,
init_args=[], init_kwargs={}),
mock.call(mock.sentinel.impl_two_one, manifest=None,
init_args=[], init_kwargs={}),
mock.call(mock.sentinel.impl_two_two, manifest=None,
init_args=[], init_kwargs={})],
any_order=True)
test()