blob: 45eb9b05d6e11e5135f08c0957aa773abdabbe05 [file] [log] [blame]
# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unittests for config."""
from __future__ import print_function
import copy
import cPickle
from chromite.cbuildbot import config_lib
from chromite.lib import cros_test_lib
class _CustomObject(object):
"""Simple object. For testing deepcopy."""
def __init__(self, x):
self.x = x
def __eq__(self, other):
return self.x == other.x
class _CustomObjectWithSlots(object):
"""Simple object with slots. For testing deepcopy."""
__slots__ = ['x']
def __init__(self, x):
self.x = x
def __eq__(self, other):
return self.x == other.x
class BuildConfigClassTest(cros_test_lib.TestCase):
"""BuildConfig tests."""
def setUp(self):
self.fooConfig = config_lib.BuildConfig(name='foo', value=1)
self.barConfig = config_lib.BuildConfig(name='bar', value=2)
self.deepConfig = config_lib.BuildConfig(
name='deep', nested=[1, 2, 3], value=3,
child_configs=[self.fooConfig, self.barConfig])
self.config = {
'foo': self.fooConfig,
'bar': self.barConfig,
'deep': self.deepConfig,
}
def testValueAccess(self):
self.assertEqual(self.fooConfig.name, 'foo')
self.assertEqual(self.fooConfig.name, self.fooConfig['name'])
self.assertRaises(AttributeError, getattr, self.fooConfig, 'foobar')
# pylint: disable=protected-access
def testDeleteKey(self):
base_config = config_lib.BuildConfig(foo='bar')
inherited_config = base_config.derive(
foo=config_lib.BuildConfig.delete_key())
self.assertTrue('foo' in base_config)
self.assertFalse('foo' in inherited_config)
def testDeleteKeys(self):
base_config = config_lib.BuildConfig(foo='bar', baz='bak')
inherited_config_1 = base_config.derive(qzr='flp')
inherited_config_2 = inherited_config_1.derive(
config_lib.BuildConfig.delete_keys(base_config))
self.assertEqual(inherited_config_2, {'qzr': 'flp'})
def testCallableOverrides(self):
append_foo = lambda x: x + 'foo' if x else 'foo'
base_config = config_lib.BuildConfig()
inherited_config_1 = base_config.derive(foo=append_foo)
inherited_config_2 = inherited_config_1.derive(foo=append_foo)
self.assertEqual(inherited_config_1, {'foo': 'foo'})
self.assertEqual(inherited_config_2, {'foo': 'foofoo'})
def AssertDeepCopy(self, obj1, obj2, obj3):
"""Assert that |obj3| is a deep copy of |obj1|.
Args:
obj1: Object that was copied.
obj2: A true deep copy of obj1 (produced using copy.deepcopy).
obj3: The purported deep copy of obj1.
"""
# Check whether the item was copied by deepcopy. If so, then it
# must have been copied by our algorithm as well.
if obj1 is not obj2:
self.assertIsNot(obj1, obj3)
# Assert the three items are all equal.
self.assertEqual(obj1, obj2)
self.assertEqual(obj1, obj3)
if isinstance(obj1, (tuple, list)):
# Copy tuples and lists item by item.
for i in range(len(obj1)):
self.AssertDeepCopy(obj1[i], obj2[i], obj3[i])
elif isinstance(obj1, set):
# Compare sorted versions of the set.
self.AssertDeepCopy(list(sorted(obj1)), list(sorted(obj2)),
list(sorted(obj3)))
elif isinstance(obj1, dict):
# Copy dicts item by item.
for k in obj1:
self.AssertDeepCopy(obj1[k], obj2[k], obj3[k])
elif hasattr(obj1, '__dict__'):
# Make sure the dicts are copied.
self.AssertDeepCopy(obj1.__dict__, obj2.__dict__, obj3.__dict__)
elif hasattr(obj1, '__slots__'):
# Make sure the slots are copied.
for attr in obj1.__slots__:
self.AssertDeepCopy(getattr(obj1, attr), getattr(obj2, attr),
getattr(obj3, attr))
else:
# This should be an object that copy.deepcopy didn't copy (probably an
# immutable object.) If not, the test needs to be updated to handle this
# kind of object.
self.assertIs(obj1, obj2)
def testDeepCopy(self):
"""Test that we deep copy correctly."""
for cfg in [self.fooConfig, self.barConfig, self.deepConfig]:
self.AssertDeepCopy(cfg, copy.deepcopy(cfg), cfg.deepcopy())
def testAssertDeepCopy(self):
"""Test that we test deep copy correctly."""
test1 = ['foo', 'bar', ['hey']]
tests = [test1,
set([tuple(x) for x in test1]),
dict(zip([tuple(x) for x in test1], test1)),
_CustomObject(test1),
_CustomObjectWithSlots(test1)]
for x in tests + [[tests]]:
copy_x = copy.deepcopy(x)
self.AssertDeepCopy(x, copy_x, copy.deepcopy(x))
self.AssertDeepCopy(x, copy_x, cPickle.loads(cPickle.dumps(x, -1)))
self.assertRaises(AssertionError, self.AssertDeepCopy, x,
copy_x, x)
if not isinstance(x, set):
self.assertRaises(AssertionError, self.AssertDeepCopy, x,
copy_x, copy.copy(x))