[Zodb-checkins] CVS: ZODB3/BTrees/tests - test_check.py:1.1.2.1 testBTrees.py:1.48.4.1
Tim Peters
tim.one@comcast.net
Tue, 14 Jan 2003 17:25:17 -0500
Update of /cvs-repository/ZODB3/BTrees/tests
In directory cvs.zope.org:/tmp/cvs-serv11036/BTrees/tests
Modified Files:
Tag: ZODB3-3_1-branch
testBTrees.py
Added Files:
Tag: ZODB3-3_1-branch
test_check.py
Log Message:
New btrees module check.py (and test program). The primary new function
is check.check(btree), which performs value-based sanity checks on a BTree
(or TreeSet) that the btree._check() method doesn't do. The new checks
include that all the bucket keys are in sorted order, and that all the
keys within each bucket, and within each internal BTree node, lie within
the range necessary for that node. That last is a subtle invariant that
can't be checked locally: it requires propagating range info down the
tree, and modifying it for each child and each level. This *should* catch
any BTree B for which iterating over the keys yields a key K for which
B.has_key(K) returns false.
Another function check.display(btree) prints the internal structure of
a BTree (or TreeSet, Bucket, or Set) to stdout. If check.check(B)
ever complains, a clearer picture of the damage can be gotten by
staring at check.display(B)'s output.
Also beefed up the regular BTree tests by calling check.check() in key
places. No surprises (the tests still pass).
=== Added File ZODB3/BTrees/tests/test_check.py ===
##############################################################################
#
# Copyright (c) 2003 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Test the BTree check.check() function."""
import unittest
from BTrees.OOBTree import OOBTree
from BTrees.check import check
class CheckTest(unittest.TestCase):
def setUp(self):
self.t = t = OOBTree()
for i in range(31):
t[i] = 2*i
self.state = t.__getstate__()
def testNormal(self):
s = self.state
# Looks like (state, first_bucket)
# where state looks like (bucket0, 15, bucket1).
self.assertEqual(len(s), 2)
self.assertEqual(len(s[0]), 3)
self.assertEqual(s[0][1], 15)
self.t._check() # shouldn't blow up
check(self.t) # shouldn't blow up
def testKeyTooLarge(self):
# Damage an invariant by dropping the BTree key to 14.
s = self.state
news = (s[0][0], 14, s[0][2]), s[1]
self.t.__setstate__(news)
self.t._check() # not caught
try:
# Expecting "... key %r >= upper bound %r at index %d"
check(self.t)
except AssertionError, detail:
self.failUnless(str(detail).find(">= upper bound") > 0)
else:
self.fail("expected self.t_check() to catch the problem")
def testKeyTooSmall(self):
# Damage an invariant by bumping the BTree key to 16.
s = self.state
news = (s[0][0], 16, s[0][2]), s[1]
self.t.__setstate__(news)
self.t._check() # not caught
try:
# Expecting "... key %r < lower bound %r at index %d"
check(self.t)
except AssertionError, detail:
self.failUnless(str(detail).find("< lower bound") > 0)
else:
self.fail("expected self.t_check() to catch the problem")
def testKeysSwapped(self):
# Damage an invariant by swapping two key/value pairs.
s = self.state
# Looks like (state, first_bucket)
# where state looks like (bucket0, 15, bucket1).
(b0, num, b1), firstbucket = s
self.assertEqual(b0[4], 8)
self.assertEqual(b0[5], 10)
b0state = b0.__getstate__()
self.assertEqual(len(b0state), 2)
# b0state looks like
# ((k0, v0, k1, v1, ...), nextbucket)
pairs, nextbucket = b0state
self.assertEqual(pairs[8], 4)
self.assertEqual(pairs[9], 8)
self.assertEqual(pairs[10], 5)
self.assertEqual(pairs[11], 10)
newpairs = pairs[:8] + (5, 10, 4, 8) + pairs[12:]
b0.__setstate__((newpairs, nextbucket))
self.t._check() # not caught
try:
check(self.t)
except AssertionError, detail:
self.failUnless(str(detail).find(
"key 5 at index 4 >= key 4 at index 5") > 0)
else:
self.fail("expected self.t_check() to catch the problem")
def test_suite():
return unittest.makeSuite(CheckTest)
=== ZODB3/BTrees/tests/testBTrees.py 1.48 => 1.48.4.1 ===
--- ZODB3/BTrees/tests/testBTrees.py:1.48 Tue Aug 27 14:37:07 2002
+++ ZODB3/BTrees/tests/testBTrees.py Tue Jan 14 17:25:13 2003
@@ -18,6 +18,9 @@
from BTrees.IOBTree import IOBTree, IOBucket, IOSet, IOTreeSet
from BTrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet
from BTrees.OIBTree import OIBTree, OIBucket, OISet, OITreeSet
+
+from BTrees.check import check
+
from unittest import TestCase, TestSuite, TextTestRunner, makeSuite
from glob import glob
@@ -524,6 +527,7 @@
def tearDown(self):
self.t._check()
+ check(self.t)
MappingBase.tearDown(self)
def testDeleteNoChildrenWorks(self):
@@ -981,6 +985,7 @@
t = ts()
t.__setstate__(((tree13, 4, tree5711), bucket1))
t._check()
+ check(t)
return t, [1, 3, 5, 7, 11]
def testDegenerateBasicOps(self):
@@ -1042,6 +1047,7 @@
t.remove(key)
keys.remove(key)
t._check()
+ check(t)
self._checkRanges(t, keys)
# We removed all the keys, so the tree should be empty now.
self.assertEqual(t.__getstate__(), None)