[Zope3-checkins] CVS: Zope3/src/zodb/btrees/tests - test_check.py:1.1 test_btrees.py:1.3
Tim Peters
tim.one@comcast.net
Tue, 14 Jan 2003 16:51:49 -0500
Update of /cvs-repository/Zope3/src/zodb/btrees/tests
In directory cvs.zope.org:/tmp/cvs-serv5838/src/zodb/btrees/tests
Modified Files:
test_btrees.py
Added Files:
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 Zope3/src/zodb/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 zodb.btrees.OOBTree import OOBTree
from zodb.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 testKeysSwappedl(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)
=== Zope3/src/zodb/btrees/tests/test_btrees.py 1.2 => 1.3 ===
--- Zope3/src/zodb/btrees/tests/test_btrees.py:1.2 Wed Dec 25 09:12:17 2002
+++ Zope3/src/zodb/btrees/tests/test_btrees.py Tue Jan 14 16:51:46 2003
@@ -16,6 +16,9 @@
from zodb.btrees.IIBTree import IIBTree, IIBucket, IISet, IITreeSet
from zodb.btrees.OIBTree import OIBTree, OIBucket, OISet, OITreeSet
+from zodb.btrees.check import check
+
+
from transaction import get_transaction
from glob import glob
@@ -646,6 +649,7 @@
def tearDown(self):
self.t._check()
+ check(self.t)
MappingBase.tearDown(self)
def testDeleteNoChildrenWorks(self):
@@ -1072,6 +1076,7 @@
t = ts()
t.__setstate__(((tree13, 4, tree5711), bucket1))
t._check()
+ check(t)
return t, [1, 3, 5, 7, 11]
def testBasicOps(self):
@@ -1133,6 +1138,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)