aboutsummaryrefslogtreecommitdiffstats
path: root/lib/bb/tests
diff options
context:
space:
mode:
authorChris Laplante <chris.laplante@agilent.com>2020-08-27 16:38:39 -0400
committerRichard Purdie <richard.purdie@linuxfoundation.org>2020-08-28 07:18:37 +0100
commita73d45cb6010e14bf93fec857303bc7ff321066f (patch)
tree95163c2107e4bc0b95294d25de64c9094a78acd5 /lib/bb/tests
parentd2b202e04cd4837992283577747475fa7d9e34e5 (diff)
downloadbitbake-a73d45cb6010e14bf93fec857303bc7ff321066f.tar.gz
COW: migrate test suite into tests/cow
Convert the test suite that was in COW.py into something that will actually run as part of bitbake-selftest. This is in preparation for some cleanups I plan in COW.py. Signed-off-by: Chris Laplante <chris.laplante@agilent.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'lib/bb/tests')
-rw-r--r--lib/bb/tests/cow.py218
1 files changed, 206 insertions, 12 deletions
diff --git a/lib/bb/tests/cow.py b/lib/bb/tests/cow.py
index bf6e79fce..75142649c 100644
--- a/lib/bb/tests/cow.py
+++ b/lib/bb/tests/cow.py
@@ -4,9 +4,17 @@
# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright 2006 Holger Freyther <freyther@handhelds.org>
+# Copyright (C) 2020 Agilent Technologies, Inc.
#
+import io
+import re
+import sys
import unittest
+import contextlib
+import collections
+
+from bb.COW import COWDictBase, COWSetBase, COWDictMeta, COWSetMeta
class COWTestCase(unittest.TestCase):
@@ -14,11 +22,61 @@ class COWTestCase(unittest.TestCase):
Test case for the COW module from mithro
"""
+ def setUp(self):
+ self._track_warnings = False
+ self._warning_file = io.StringIO()
+ self._unhandled_warnings = collections.deque()
+ COWDictBase.__warn__ = self._warning_file
+
+ def tearDown(self):
+ COWDictBase.__warn__ = sys.stderr
+ if self._track_warnings:
+ self._checkAllWarningsRead()
+
+ def trackWarnings(self):
+ self._track_warnings = True
+
+ def _collectWarnings(self):
+ self._warning_file.seek(0)
+ for warning in self._warning_file:
+ self._unhandled_warnings.append(warning.rstrip("\n"))
+ self._warning_file.truncate(0)
+ self._warning_file.seek(0)
+
+ def _checkAllWarningsRead(self):
+ self._collectWarnings()
+ self.assertSequenceEqual(self._unhandled_warnings, [])
+
+ @contextlib.contextmanager
+ def checkReportsWarning(self, expected_warning):
+ self._checkAllWarningsRead()
+ yield
+ self._collectWarnings()
+ warning = self._unhandled_warnings.popleft()
+ self.assertEqual(warning, expected_warning)
+
+ def checkStrOutput(self, obj, expected_levels, expected_keys):
+ if obj.__class__ is COWDictMeta:
+ expected_class_name = "COWDict"
+ elif obj.__class__ is COWSetMeta:
+ expected_class_name = "COWSet"
+ else:
+ self.fail("obj is of unknown type {0}".format(type(obj)))
+ s = str(obj)
+ regex = re.compile(r"<(\w+) Level: (\d+) Current Keys: (\d+)>")
+ match = regex.match(s)
+ self.assertIsNotNone(match, "bad str output: '{0}'".format(s))
+ class_name = match.group(1)
+ self.assertEqual(class_name, expected_class_name)
+ levels = int(match.group(2))
+ self.assertEqual(levels, expected_levels, "wrong # levels in str: '{0}'".format(s))
+ keys = int(match.group(3))
+ self.assertEqual(keys, expected_keys, "wrong # keys in str: '{0}'".format(s))
+
def testGetSet(self):
"""
Test and set
"""
- from bb.COW import COWDictBase
a = COWDictBase.copy()
self.assertEqual(False, 'a' in a)
@@ -27,16 +85,14 @@ class COWTestCase(unittest.TestCase):
a['b'] = 'b'
self.assertEqual(True, 'a' in a)
self.assertEqual(True, 'b' in a)
- self.assertEqual('a', a['a'] )
- self.assertEqual('b', a['b'] )
+ self.assertEqual('a', a['a'])
+ self.assertEqual('b', a['b'])
def testCopyCopy(self):
"""
Test the copy of copies
"""
- from bb.COW import COWDictBase
-
# create two COW dict 'instances'
b = COWDictBase.copy()
c = COWDictBase.copy()
@@ -94,30 +150,168 @@ class COWTestCase(unittest.TestCase):
self.assertEqual(False, 'e' in b_2)
def testCow(self):
- from bb.COW import COWDictBase
+ self.trackWarnings()
+
c = COWDictBase.copy()
c['123'] = 1027
c['other'] = 4711
- c['d'] = { 'abc' : 10, 'bcd' : 20 }
+ c['d'] = {'abc': 10, 'bcd': 20}
copy = c.copy()
self.assertEqual(1027, c['123'])
self.assertEqual(4711, c['other'])
- self.assertEqual({'abc':10, 'bcd':20}, c['d'])
+ self.assertEqual({'abc': 10, 'bcd': 20}, c['d'])
self.assertEqual(1027, copy['123'])
self.assertEqual(4711, copy['other'])
- self.assertEqual({'abc':10, 'bcd':20}, copy['d'])
+ with self.checkReportsWarning("Warning: Doing a copy because d is a mutable type."):
+ self.assertEqual({'abc': 10, 'bcd': 20}, copy['d'])
# cow it now
copy['123'] = 1028
copy['other'] = 4712
copy['d']['abc'] = 20
-
self.assertEqual(1027, c['123'])
self.assertEqual(4711, c['other'])
- self.assertEqual({'abc':10, 'bcd':20}, c['d'])
+ self.assertEqual({'abc': 10, 'bcd': 20}, c['d'])
self.assertEqual(1028, copy['123'])
self.assertEqual(4712, copy['other'])
- self.assertEqual({'abc':20, 'bcd':20}, copy['d'])
+ self.assertEqual({'abc': 20, 'bcd': 20}, copy['d'])
+
+ def testOriginalTestSuite(self):
+ # This test suite is a port of the original one from COW.py
+ self.trackWarnings()
+
+ a = COWDictBase.copy()
+ self.checkStrOutput(a, 1, 0)
+
+ a['a'] = 'a'
+ a['b'] = 'b'
+ a['dict'] = {}
+ self.checkStrOutput(a, 1, 4) # 4th member is dict__mutable__
+
+ b = a.copy()
+ self.checkStrOutput(b, 2, 0)
+ b['c'] = 'b'
+ self.checkStrOutput(b, 2, 1)
+
+ with self.checkReportsWarning("Warning: If you aren't going to change any of the values call with True."):
+ self.assertListEqual(list(a.iteritems()),
+ [('a', 'a'),
+ ('b', 'b'),
+ ('dict', {})
+ ])
+
+ with self.checkReportsWarning("Warning: If you aren't going to change any of the values call with True."):
+ b_gen = b.iteritems()
+ self.assertTupleEqual(next(b_gen), ('a', 'a'))
+ self.assertTupleEqual(next(b_gen), ('b', 'b'))
+ self.assertTupleEqual(next(b_gen), ('c', 'b'))
+ with self.checkReportsWarning("Warning: Doing a copy because dict is a mutable type."):
+ self.assertTupleEqual(next(b_gen), ('dict', {}))
+ with self.assertRaises(StopIteration):
+ next(b_gen)
+
+ b['dict']['a'] = 'b'
+ b['a'] = 'c'
+
+ self.checkStrOutput(a, 1, 4)
+ self.checkStrOutput(b, 2, 3)
+
+ with self.checkReportsWarning("Warning: If you aren't going to change any of the values call with True."):
+ self.assertListEqual(list(a.iteritems()),
+ [('a', 'a'),
+ ('b', 'b'),
+ ('dict', {})
+ ])
+
+ with self.checkReportsWarning("Warning: If you aren't going to change any of the values call with True."):
+ b_gen = b.iteritems()
+ self.assertTupleEqual(next(b_gen), ('a', 'c'))
+ self.assertTupleEqual(next(b_gen), ('b', 'b'))
+ self.assertTupleEqual(next(b_gen), ('c', 'b'))
+ self.assertTupleEqual(next(b_gen), ('dict', {'a': 'b'}))
+ with self.assertRaises(StopIteration):
+ next(b_gen)
+
+ with self.assertRaises(KeyError):
+ print(b["dict2"])
+
+ a['set'] = COWSetBase()
+ a['set'].add("o1")
+ a['set'].add("o1")
+ a['set'].add("o2")
+ self.assertSetEqual(set(a['set'].itervalues()), {"o1", "o2"})
+ self.assertSetEqual(set(b['set'].itervalues()), {"o1", "o2"})
+
+ b['set'].add('o3')
+ self.assertSetEqual(set(a['set'].itervalues()), {"o1", "o2"})
+ self.assertSetEqual(set(b['set'].itervalues()), {"o1", "o2", "o3"})
+
+ a['set2'] = set()
+ a['set2'].add("o1")
+ a['set2'].add("o1")
+ a['set2'].add("o2")
+
+ # We don't expect 'a' to change anymore
+ def check_a():
+ with self.checkReportsWarning("Warning: If you aren't going to change any of the values call with True."):
+ a_gen = a.iteritems()
+ self.assertTupleEqual(next(a_gen), ('a', 'a'))
+ self.assertTupleEqual(next(a_gen), ('b', 'b'))
+ self.assertTupleEqual(next(a_gen), ('dict', {}))
+ self.assertTupleEqual(next(a_gen), ('set2', {'o1', 'o2'}))
+ a_sub_set = next(a_gen)
+ self.assertEqual(a_sub_set[0], 'set')
+ self.checkStrOutput(a_sub_set[1], 1, 2)
+ self.assertSetEqual(set(a_sub_set[1].itervalues()), {'o1', 'o2'})
+
+ check_a()
+
+ b_gen = b.iteritems(readonly=True)
+ self.assertTupleEqual(next(b_gen), ('a', 'c'))
+ self.assertTupleEqual(next(b_gen), ('b', 'b'))
+ self.assertTupleEqual(next(b_gen), ('c', 'b'))
+ self.assertTupleEqual(next(b_gen), ('dict', {'a': 'b'}))
+ self.assertTupleEqual(next(b_gen), ('set2', {'o1', 'o2'}))
+ b_sub_set = next(b_gen)
+ self.assertEqual(b_sub_set[0], 'set')
+ self.checkStrOutput(b_sub_set[1], 2, 1)
+ self.assertSetEqual(set(b_sub_set[1].itervalues()), {'o1', 'o2', 'o3'})
+
+ del b['b']
+ with self.assertRaises(KeyError):
+ print(b['b'])
+ self.assertFalse('b' in b)
+
+ check_a()
+
+ b.__revertitem__('b')
+ check_a()
+ self.assertEqual(b['b'], 'b')
+ self.assertTrue('b' in b)
+
+ b.__revertitem__('dict')
+ check_a()
+
+ b_gen = b.iteritems(readonly=True)
+ self.assertTupleEqual(next(b_gen), ('a', 'c'))
+ self.assertTupleEqual(next(b_gen), ('b', 'b'))
+ self.assertTupleEqual(next(b_gen), ('c', 'b'))
+ self.assertTupleEqual(next(b_gen), ('dict', {}))
+ self.assertTupleEqual(next(b_gen), ('set2', {'o1', 'o2'}))
+ b_sub_set = next(b_gen)
+ self.assertEqual(b_sub_set[0], 'set')
+ self.checkStrOutput(b_sub_set[1], 2, 1)
+ self.assertSetEqual(set(b_sub_set[1].itervalues()), {'o1', 'o2', 'o3'})
+
+ self.checkStrOutput(a, 1, 6)
+ self.checkStrOutput(b, 2, 3)
+
+ def testSetMethods(self):
+ s = COWSetBase()
+ with self.assertRaises(TypeError):
+ print(s.iteritems())
+ with self.assertRaises(TypeError):
+ print(s.iterkeys())