blob: ff8c3550b77576a3ffaa1bee74ee5cc2d0d6ffbd [file] [log] [blame]
Roger E. Masse352e1861997-01-16 22:04:10 +00001#! /usr/bin/env python
Raymond Hettingerd55111f2003-09-13 05:51:09 +00002"""Test script for the bsddb C module by Roger E. Masse
3 Adapted to unittest format and expanded scope by Raymond Hettinger
Roger E. Masse352e1861997-01-16 22:04:10 +00004"""
Gregory P. Smithdc113a82003-11-02 09:10:16 +00005import os, sys
Roger E. Masse352e1861997-01-16 22:04:10 +00006import bsddb
Guido van Rossuma35e2ce2001-12-07 16:43:19 +00007import dbhash # Just so we know it's imported
Raymond Hettingerd55111f2003-09-13 05:51:09 +00008import unittest
9from test import test_support
10from sets import Set
Roger E. Masse352e1861997-01-16 22:04:10 +000011
Raymond Hettingerd55111f2003-09-13 05:51:09 +000012class TestBSDDB(unittest.TestCase):
Roger E. Masse352e1861997-01-16 22:04:10 +000013
Raymond Hettingerd55111f2003-09-13 05:51:09 +000014 def setUp(self):
15 self.f = self.openmethod[0](self.fname, 'c')
16 self.d = dict(q='Guido', w='van', e='Rossum', r='invented', t='Python', y='')
17 for k, v in self.d.iteritems():
18 self.f[k] = v
Fred Drake004d5e62000-10-23 17:22:08 +000019
Raymond Hettingerd55111f2003-09-13 05:51:09 +000020 def tearDown(self):
21 self.f.sync()
22 self.f.close()
23 if self.fname is None:
24 return
Anthony Baxter83888952002-04-23 02:11:05 +000025 try:
Raymond Hettingerd55111f2003-09-13 05:51:09 +000026 os.remove(self.fname)
Anthony Baxter83888952002-04-23 02:11:05 +000027 except os.error:
28 pass
Roger E. Masse352e1861997-01-16 22:04:10 +000029
Raymond Hettingerd55111f2003-09-13 05:51:09 +000030 def test_getitem(self):
31 for k, v in self.d.iteritems():
32 self.assertEqual(self.f[k], v)
Roger E. Masse352e1861997-01-16 22:04:10 +000033
Raymond Hettingerd55111f2003-09-13 05:51:09 +000034 def test_len(self):
35 self.assertEqual(len(self.f), len(self.d))
36
37 def test_change(self):
38 self.f['r'] = 'discovered'
39 self.assertEqual(self.f['r'], 'discovered')
40 self.assert_('r' in self.f.keys())
41 self.assert_('discovered' in self.f.values())
42
43 def test_close_and_reopen(self):
44 if self.fname is None:
45 # if we're using an in-memory only db, we can't reopen it
46 # so finish here.
47 return
48 self.f.close()
49 self.f = self.openmethod[0](self.fname, 'w')
50 for k, v in self.d.iteritems():
51 self.assertEqual(self.f[k], v)
52
53 def assertSetEquals(self, seqn1, seqn2):
54 self.assertEqual(Set(seqn1), Set(seqn2))
55
56 def test_mapping_iteration_methods(self):
57 f = self.f
58 d = self.d
59 self.assertSetEquals(d, f)
60 self.assertSetEquals(d.keys(), f.keys())
61 self.assertSetEquals(d.values(), f.values())
62 self.assertSetEquals(d.items(), f.items())
63 self.assertSetEquals(d.iterkeys(), f.iterkeys())
64 self.assertSetEquals(d.itervalues(), f.itervalues())
65 self.assertSetEquals(d.iteritems(), f.iteritems())
66
67 def test_first_next_looping(self):
68 items = [self.f.first()]
69 for i in xrange(1, len(self.f)):
70 items.append(self.f.next())
71 self.assertSetEquals(items, self.d.items())
72
73 def test_previous_last_looping(self):
74 items = [self.f.last()]
75 for i in xrange(1, len(self.f)):
76 items.append(self.f.previous())
77 self.assertSetEquals(items, self.d.items())
78
79 def test_set_location(self):
80 self.assertEqual(self.f.set_location('e'), ('e', self.d['e']))
81
82 def test_contains(self):
83 for k in self.d:
84 self.assert_(k in self.f)
85 self.assert_('not here' not in self.f)
86
87 def test_has_key(self):
88 for k in self.d:
89 self.assert_(self.f.has_key(k))
90 self.assert_(not self.f.has_key('not here'))
91
92 def test_clear(self):
93 self.f.clear()
94 self.assertEqual(len(self.f), 0)
95
Gregory P. Smithdc113a82003-11-02 09:10:16 +000096 def test__no_deadlock_first(self, debug=0):
97 # do this so that testers can see what function we're in in
98 # verbose mode when we deadlock.
99 sys.stdout.flush()
100
101 # in pybsddb's _DBWithCursor this causes an internal DBCursor
102 # object is created. Other test_ methods in this class could
103 # inadvertently cause the deadlock but an explicit test is needed.
104 if debug: print "A"
105 k,v = self.f.first()
106 if debug: print "B", k
107 self.f[k] = "deadlock. do not pass go. do not collect $200."
108 if debug: print "C"
109 # if the bsddb implementation leaves the DBCursor open during
110 # the database write and locking+threading support is enabled
111 # the cursor's read lock will deadlock the write lock request..
112
113 # test the iterator interface (if present)
114 if hasattr(self, 'iteritems'):
115 if debug: print "D"
116 k,v = self.f.iteritems()
117 if debug: print "E"
118 self.f[k] = "please don't deadlock"
119 if debug: print "F"
120 while 1:
121 try:
122 k,v = self.f.iteritems()
123 except StopIteration:
124 break
125 if debug: print "F2"
126
127 i = iter(self.f)
128 if debug: print "G"
129 while i:
130 try:
131 if debug: print "H"
132 k = i.next()
133 if debug: print "I"
134 self.f[k] = "deadlocks-r-us"
135 if debug: print "J"
136 except StopIteration:
137 i = None
138 if debug: print "K"
139
140 # test the legacy cursor interface mixed with writes
141 self.assert_(self.f.first()[0] in self.d)
142 k = self.f.next()[0]
143 self.assert_(k in self.d)
144 self.f[k] = "be gone with ye deadlocks"
145 self.assert_(self.f[k], "be gone with ye deadlocks")
146
Raymond Hettingerd55111f2003-09-13 05:51:09 +0000147 def test_popitem(self):
148 k, v = self.f.popitem()
149 self.assert_(k in self.d)
150 self.assert_(v in self.d.values())
151 self.assert_(k not in self.f)
152 self.assertEqual(len(self.d)-1, len(self.f))
153
154 def test_pop(self):
155 k = 'w'
156 v = self.f.pop(k)
157 self.assertEqual(v, self.d[k])
158 self.assert_(k not in self.f)
159 self.assert_(v not in self.f.values())
160 self.assertEqual(len(self.d)-1, len(self.f))
161
162 def test_get(self):
163 self.assertEqual(self.f.get('NotHere'), None)
164 self.assertEqual(self.f.get('NotHere', 'Default'), 'Default')
165 self.assertEqual(self.f.get('q', 'Default'), self.d['q'])
166
167 def test_setdefault(self):
168 self.assertEqual(self.f.setdefault('new', 'dog'), 'dog')
169 self.assertEqual(self.f.setdefault('r', 'cat'), self.d['r'])
170
171 def test_update(self):
172 new = dict(y='life', u='of', i='brian')
173 self.f.update(new)
174 self.d.update(new)
175 for k, v in self.d.iteritems():
176 self.assertEqual(self.f[k], v)
177
178 def test_keyordering(self):
179 if self.openmethod[0] is not bsddb.btopen:
180 return
181 keys = self.d.keys()
182 keys.sort()
183 self.assertEqual(self.f.first()[0], keys[0])
184 self.assertEqual(self.f.next()[0], keys[1])
185 self.assertEqual(self.f.last()[0], keys[-1])
186 self.assertEqual(self.f.previous()[0], keys[-2])
187 self.assertEqual(list(self.f), keys)
188
189class TestBTree(TestBSDDB):
190 fname = test_support.TESTFN
191 openmethod = [bsddb.btopen]
192
193class TestBTree_InMemory(TestBSDDB):
194 fname = None
195 openmethod = [bsddb.btopen]
196
197class TestHashTable(TestBSDDB):
198 fname = test_support.TESTFN
199 openmethod = [bsddb.hashopen]
200
201class TestHashTable_InMemory(TestBSDDB):
202 fname = None
203 openmethod = [bsddb.hashopen]
204
205## # (bsddb.rnopen,'Record Numbers'), 'put' for RECNO for bsddb 1.85
206## # appears broken... at least on
207## # Solaris Intel - rmasse 1/97
208
209def test_main(verbose=None):
210 test_support.run_unittest(
211 TestBTree,
212 TestHashTable,
213 TestBTree_InMemory,
214 TestHashTable_InMemory,
215 )
216
217if __name__ == "__main__":
218 test_main(verbose=True)