1 | """
|
---|
2 | Basic TestCases for BTree and hash DBs, with and without a DBEnv, with
|
---|
3 | various DB flags, etc.
|
---|
4 | """
|
---|
5 |
|
---|
6 | import os
|
---|
7 | import errno
|
---|
8 | import string
|
---|
9 | from pprint import pprint
|
---|
10 | import unittest
|
---|
11 | import time
|
---|
12 | import sys
|
---|
13 |
|
---|
14 | from test_all import db, test_support, verbose, get_new_environment_path, \
|
---|
15 | get_new_database_path
|
---|
16 |
|
---|
17 | DASH = '-'
|
---|
18 |
|
---|
19 |
|
---|
20 | #----------------------------------------------------------------------
|
---|
21 |
|
---|
22 | class VersionTestCase(unittest.TestCase):
|
---|
23 | def test00_version(self):
|
---|
24 | info = db.version()
|
---|
25 | if verbose:
|
---|
26 | print '\n', '-=' * 20
|
---|
27 | print 'bsddb.db.version(): %s' % (info, )
|
---|
28 | print db.DB_VERSION_STRING
|
---|
29 | print '-=' * 20
|
---|
30 | self.assertEqual(info, (db.DB_VERSION_MAJOR, db.DB_VERSION_MINOR,
|
---|
31 | db.DB_VERSION_PATCH))
|
---|
32 |
|
---|
33 | #----------------------------------------------------------------------
|
---|
34 |
|
---|
35 | class BasicTestCase(unittest.TestCase):
|
---|
36 | dbtype = db.DB_UNKNOWN # must be set in derived class
|
---|
37 | cachesize = (0, 1024*1024, 1)
|
---|
38 | dbopenflags = 0
|
---|
39 | dbsetflags = 0
|
---|
40 | dbmode = 0660
|
---|
41 | dbname = None
|
---|
42 | useEnv = 0
|
---|
43 | envflags = 0
|
---|
44 | envsetflags = 0
|
---|
45 |
|
---|
46 | _numKeys = 1002 # PRIVATE. NOTE: must be an even value
|
---|
47 |
|
---|
48 | def setUp(self):
|
---|
49 | if self.useEnv:
|
---|
50 | self.homeDir=get_new_environment_path()
|
---|
51 | try:
|
---|
52 | self.env = db.DBEnv()
|
---|
53 | self.env.set_lg_max(1024*1024)
|
---|
54 | self.env.set_tx_max(30)
|
---|
55 | self._t = int(time.time())
|
---|
56 | self.env.set_tx_timestamp(self._t)
|
---|
57 | self.env.set_flags(self.envsetflags, 1)
|
---|
58 | self.env.open(self.homeDir, self.envflags | db.DB_CREATE)
|
---|
59 | self.filename = "test"
|
---|
60 | # Yes, a bare except is intended, since we're re-raising the exc.
|
---|
61 | except:
|
---|
62 | test_support.rmtree(self.homeDir)
|
---|
63 | raise
|
---|
64 | else:
|
---|
65 | self.env = None
|
---|
66 | self.filename = get_new_database_path()
|
---|
67 |
|
---|
68 | # create and open the DB
|
---|
69 | self.d = db.DB(self.env)
|
---|
70 | if not self.useEnv :
|
---|
71 | self.d.set_cachesize(*self.cachesize)
|
---|
72 | cachesize = self.d.get_cachesize()
|
---|
73 | self.assertEqual(cachesize[0], self.cachesize[0])
|
---|
74 | self.assertEqual(cachesize[2], self.cachesize[2])
|
---|
75 | # Berkeley DB expands the cache 25% accounting overhead,
|
---|
76 | # if the cache is small.
|
---|
77 | self.assertEqual(125, int(100.0*cachesize[1]/self.cachesize[1]))
|
---|
78 | self.d.set_flags(self.dbsetflags)
|
---|
79 | if self.dbname:
|
---|
80 | self.d.open(self.filename, self.dbname, self.dbtype,
|
---|
81 | self.dbopenflags|db.DB_CREATE, self.dbmode)
|
---|
82 | else:
|
---|
83 | self.d.open(self.filename, # try out keyword args
|
---|
84 | mode = self.dbmode,
|
---|
85 | dbtype = self.dbtype,
|
---|
86 | flags = self.dbopenflags|db.DB_CREATE)
|
---|
87 |
|
---|
88 | if not self.useEnv:
|
---|
89 | self.assertRaises(db.DBInvalidArgError,
|
---|
90 | self.d.set_cachesize, *self.cachesize)
|
---|
91 |
|
---|
92 | self.populateDB()
|
---|
93 |
|
---|
94 |
|
---|
95 | def tearDown(self):
|
---|
96 | self.d.close()
|
---|
97 | if self.env is not None:
|
---|
98 | self.env.close()
|
---|
99 | test_support.rmtree(self.homeDir)
|
---|
100 | else:
|
---|
101 | os.remove(self.filename)
|
---|
102 |
|
---|
103 |
|
---|
104 |
|
---|
105 | def populateDB(self, _txn=None):
|
---|
106 | d = self.d
|
---|
107 |
|
---|
108 | for x in range(self._numKeys//2):
|
---|
109 | key = '%04d' % (self._numKeys - x) # insert keys in reverse order
|
---|
110 | data = self.makeData(key)
|
---|
111 | d.put(key, data, _txn)
|
---|
112 |
|
---|
113 | d.put('empty value', '', _txn)
|
---|
114 |
|
---|
115 | for x in range(self._numKeys//2-1):
|
---|
116 | key = '%04d' % x # and now some in forward order
|
---|
117 | data = self.makeData(key)
|
---|
118 | d.put(key, data, _txn)
|
---|
119 |
|
---|
120 | if _txn:
|
---|
121 | _txn.commit()
|
---|
122 |
|
---|
123 | num = len(d)
|
---|
124 | if verbose:
|
---|
125 | print "created %d records" % num
|
---|
126 |
|
---|
127 |
|
---|
128 | def makeData(self, key):
|
---|
129 | return DASH.join([key] * 5)
|
---|
130 |
|
---|
131 |
|
---|
132 |
|
---|
133 | #----------------------------------------
|
---|
134 |
|
---|
135 | def test01_GetsAndPuts(self):
|
---|
136 | d = self.d
|
---|
137 |
|
---|
138 | if verbose:
|
---|
139 | print '\n', '-=' * 30
|
---|
140 | print "Running %s.test01_GetsAndPuts..." % self.__class__.__name__
|
---|
141 |
|
---|
142 | for key in ['0001', '0100', '0400', '0700', '0999']:
|
---|
143 | data = d.get(key)
|
---|
144 | if verbose:
|
---|
145 | print data
|
---|
146 |
|
---|
147 | self.assertEqual(d.get('0321'), '0321-0321-0321-0321-0321')
|
---|
148 |
|
---|
149 | # By default non-existent keys return None...
|
---|
150 | self.assertEqual(d.get('abcd'), None)
|
---|
151 |
|
---|
152 | # ...but they raise exceptions in other situations. Call
|
---|
153 | # set_get_returns_none() to change it.
|
---|
154 | try:
|
---|
155 | d.delete('abcd')
|
---|
156 | except db.DBNotFoundError, val:
|
---|
157 | if sys.version_info < (2, 6) :
|
---|
158 | self.assertEqual(val[0], db.DB_NOTFOUND)
|
---|
159 | else :
|
---|
160 | self.assertEqual(val.args[0], db.DB_NOTFOUND)
|
---|
161 | if verbose: print val
|
---|
162 | else:
|
---|
163 | self.fail("expected exception")
|
---|
164 |
|
---|
165 |
|
---|
166 | d.put('abcd', 'a new record')
|
---|
167 | self.assertEqual(d.get('abcd'), 'a new record')
|
---|
168 |
|
---|
169 | d.put('abcd', 'same key')
|
---|
170 | if self.dbsetflags & db.DB_DUP:
|
---|
171 | self.assertEqual(d.get('abcd'), 'a new record')
|
---|
172 | else:
|
---|
173 | self.assertEqual(d.get('abcd'), 'same key')
|
---|
174 |
|
---|
175 |
|
---|
176 | try:
|
---|
177 | d.put('abcd', 'this should fail', flags=db.DB_NOOVERWRITE)
|
---|
178 | except db.DBKeyExistError, val:
|
---|
179 | if sys.version_info < (2, 6) :
|
---|
180 | self.assertEqual(val[0], db.DB_KEYEXIST)
|
---|
181 | else :
|
---|
182 | self.assertEqual(val.args[0], db.DB_KEYEXIST)
|
---|
183 | if verbose: print val
|
---|
184 | else:
|
---|
185 | self.fail("expected exception")
|
---|
186 |
|
---|
187 | if self.dbsetflags & db.DB_DUP:
|
---|
188 | self.assertEqual(d.get('abcd'), 'a new record')
|
---|
189 | else:
|
---|
190 | self.assertEqual(d.get('abcd'), 'same key')
|
---|
191 |
|
---|
192 |
|
---|
193 | d.sync()
|
---|
194 | d.close()
|
---|
195 | del d
|
---|
196 |
|
---|
197 | self.d = db.DB(self.env)
|
---|
198 | if self.dbname:
|
---|
199 | self.d.open(self.filename, self.dbname)
|
---|
200 | else:
|
---|
201 | self.d.open(self.filename)
|
---|
202 | d = self.d
|
---|
203 |
|
---|
204 | self.assertEqual(d.get('0321'), '0321-0321-0321-0321-0321')
|
---|
205 | if self.dbsetflags & db.DB_DUP:
|
---|
206 | self.assertEqual(d.get('abcd'), 'a new record')
|
---|
207 | else:
|
---|
208 | self.assertEqual(d.get('abcd'), 'same key')
|
---|
209 |
|
---|
210 | rec = d.get_both('0555', '0555-0555-0555-0555-0555')
|
---|
211 | if verbose:
|
---|
212 | print rec
|
---|
213 |
|
---|
214 | self.assertEqual(d.get_both('0555', 'bad data'), None)
|
---|
215 |
|
---|
216 | # test default value
|
---|
217 | data = d.get('bad key', 'bad data')
|
---|
218 | self.assertEqual(data, 'bad data')
|
---|
219 |
|
---|
220 | # any object can pass through
|
---|
221 | data = d.get('bad key', self)
|
---|
222 | self.assertEqual(data, self)
|
---|
223 |
|
---|
224 | s = d.stat()
|
---|
225 | self.assertEqual(type(s), type({}))
|
---|
226 | if verbose:
|
---|
227 | print 'd.stat() returned this dictionary:'
|
---|
228 | pprint(s)
|
---|
229 |
|
---|
230 |
|
---|
231 | #----------------------------------------
|
---|
232 |
|
---|
233 | def test02_DictionaryMethods(self):
|
---|
234 | d = self.d
|
---|
235 |
|
---|
236 | if verbose:
|
---|
237 | print '\n', '-=' * 30
|
---|
238 | print "Running %s.test02_DictionaryMethods..." % \
|
---|
239 | self.__class__.__name__
|
---|
240 |
|
---|
241 | for key in ['0002', '0101', '0401', '0701', '0998']:
|
---|
242 | data = d[key]
|
---|
243 | self.assertEqual(data, self.makeData(key))
|
---|
244 | if verbose:
|
---|
245 | print data
|
---|
246 |
|
---|
247 | self.assertEqual(len(d), self._numKeys)
|
---|
248 | keys = d.keys()
|
---|
249 | self.assertEqual(len(keys), self._numKeys)
|
---|
250 | self.assertEqual(type(keys), type([]))
|
---|
251 |
|
---|
252 | d['new record'] = 'a new record'
|
---|
253 | self.assertEqual(len(d), self._numKeys+1)
|
---|
254 | keys = d.keys()
|
---|
255 | self.assertEqual(len(keys), self._numKeys+1)
|
---|
256 |
|
---|
257 | d['new record'] = 'a replacement record'
|
---|
258 | self.assertEqual(len(d), self._numKeys+1)
|
---|
259 | keys = d.keys()
|
---|
260 | self.assertEqual(len(keys), self._numKeys+1)
|
---|
261 |
|
---|
262 | if verbose:
|
---|
263 | print "the first 10 keys are:"
|
---|
264 | pprint(keys[:10])
|
---|
265 |
|
---|
266 | self.assertEqual(d['new record'], 'a replacement record')
|
---|
267 |
|
---|
268 | # We check also the positional parameter
|
---|
269 | self.assertEqual(d.has_key('0001', None), 1)
|
---|
270 | # We check also the keyword parameter
|
---|
271 | self.assertEqual(d.has_key('spam', txn=None), 0)
|
---|
272 |
|
---|
273 | items = d.items()
|
---|
274 | self.assertEqual(len(items), self._numKeys+1)
|
---|
275 | self.assertEqual(type(items), type([]))
|
---|
276 | self.assertEqual(type(items[0]), type(()))
|
---|
277 | self.assertEqual(len(items[0]), 2)
|
---|
278 |
|
---|
279 | if verbose:
|
---|
280 | print "the first 10 items are:"
|
---|
281 | pprint(items[:10])
|
---|
282 |
|
---|
283 | values = d.values()
|
---|
284 | self.assertEqual(len(values), self._numKeys+1)
|
---|
285 | self.assertEqual(type(values), type([]))
|
---|
286 |
|
---|
287 | if verbose:
|
---|
288 | print "the first 10 values are:"
|
---|
289 | pprint(values[:10])
|
---|
290 |
|
---|
291 |
|
---|
292 | #----------------------------------------
|
---|
293 |
|
---|
294 | def test02b_SequenceMethods(self):
|
---|
295 | d = self.d
|
---|
296 |
|
---|
297 | for key in ['0002', '0101', '0401', '0701', '0998']:
|
---|
298 | data = d[key]
|
---|
299 | self.assertEqual(data, self.makeData(key))
|
---|
300 | if verbose:
|
---|
301 | print data
|
---|
302 |
|
---|
303 | self.assertTrue(hasattr(d, "__contains__"))
|
---|
304 | self.assertTrue("0401" in d)
|
---|
305 | self.assertFalse("1234" in d)
|
---|
306 |
|
---|
307 |
|
---|
308 | #----------------------------------------
|
---|
309 |
|
---|
310 | def test03_SimpleCursorStuff(self, get_raises_error=0, set_raises_error=0):
|
---|
311 | if verbose:
|
---|
312 | print '\n', '-=' * 30
|
---|
313 | print "Running %s.test03_SimpleCursorStuff (get_error %s, set_error %s)..." % \
|
---|
314 | (self.__class__.__name__, get_raises_error, set_raises_error)
|
---|
315 |
|
---|
316 | if self.env and self.dbopenflags & db.DB_AUTO_COMMIT:
|
---|
317 | txn = self.env.txn_begin()
|
---|
318 | else:
|
---|
319 | txn = None
|
---|
320 | c = self.d.cursor(txn=txn)
|
---|
321 |
|
---|
322 | rec = c.first()
|
---|
323 | count = 0
|
---|
324 | while rec is not None:
|
---|
325 | count = count + 1
|
---|
326 | if verbose and count % 100 == 0:
|
---|
327 | print rec
|
---|
328 | try:
|
---|
329 | rec = c.next()
|
---|
330 | except db.DBNotFoundError, val:
|
---|
331 | if get_raises_error:
|
---|
332 | if sys.version_info < (2, 6) :
|
---|
333 | self.assertEqual(val[0], db.DB_NOTFOUND)
|
---|
334 | else :
|
---|
335 | self.assertEqual(val.args[0], db.DB_NOTFOUND)
|
---|
336 | if verbose: print val
|
---|
337 | rec = None
|
---|
338 | else:
|
---|
339 | self.fail("unexpected DBNotFoundError")
|
---|
340 | self.assertEqual(c.get_current_size(), len(c.current()[1]),
|
---|
341 | "%s != len(%r)" % (c.get_current_size(), c.current()[1]))
|
---|
342 |
|
---|
343 | self.assertEqual(count, self._numKeys)
|
---|
344 |
|
---|
345 |
|
---|
346 | rec = c.last()
|
---|
347 | count = 0
|
---|
348 | while rec is not None:
|
---|
349 | count = count + 1
|
---|
350 | if verbose and count % 100 == 0:
|
---|
351 | print rec
|
---|
352 | try:
|
---|
353 | rec = c.prev()
|
---|
354 | except db.DBNotFoundError, val:
|
---|
355 | if get_raises_error:
|
---|
356 | if sys.version_info < (2, 6) :
|
---|
357 | self.assertEqual(val[0], db.DB_NOTFOUND)
|
---|
358 | else :
|
---|
359 | self.assertEqual(val.args[0], db.DB_NOTFOUND)
|
---|
360 | if verbose: print val
|
---|
361 | rec = None
|
---|
362 | else:
|
---|
363 | self.fail("unexpected DBNotFoundError")
|
---|
364 |
|
---|
365 | self.assertEqual(count, self._numKeys)
|
---|
366 |
|
---|
367 | rec = c.set('0505')
|
---|
368 | rec2 = c.current()
|
---|
369 | self.assertEqual(rec, rec2)
|
---|
370 | self.assertEqual(rec[0], '0505')
|
---|
371 | self.assertEqual(rec[1], self.makeData('0505'))
|
---|
372 | self.assertEqual(c.get_current_size(), len(rec[1]))
|
---|
373 |
|
---|
374 | # make sure we get empty values properly
|
---|
375 | rec = c.set('empty value')
|
---|
376 | self.assertEqual(rec[1], '')
|
---|
377 | self.assertEqual(c.get_current_size(), 0)
|
---|
378 |
|
---|
379 | try:
|
---|
380 | n = c.set('bad key')
|
---|
381 | except db.DBNotFoundError, val:
|
---|
382 | if sys.version_info < (2, 6) :
|
---|
383 | self.assertEqual(val[0], db.DB_NOTFOUND)
|
---|
384 | else :
|
---|
385 | self.assertEqual(val.args[0], db.DB_NOTFOUND)
|
---|
386 | if verbose: print val
|
---|
387 | else:
|
---|
388 | if set_raises_error:
|
---|
389 | self.fail("expected exception")
|
---|
390 | if n is not None:
|
---|
391 | self.fail("expected None: %r" % (n,))
|
---|
392 |
|
---|
393 | rec = c.get_both('0404', self.makeData('0404'))
|
---|
394 | self.assertEqual(rec, ('0404', self.makeData('0404')))
|
---|
395 |
|
---|
396 | try:
|
---|
397 | n = c.get_both('0404', 'bad data')
|
---|
398 | except db.DBNotFoundError, val:
|
---|
399 | if sys.version_info < (2, 6) :
|
---|
400 | self.assertEqual(val[0], db.DB_NOTFOUND)
|
---|
401 | else :
|
---|
402 | self.assertEqual(val.args[0], db.DB_NOTFOUND)
|
---|
403 | if verbose: print val
|
---|
404 | else:
|
---|
405 | if get_raises_error:
|
---|
406 | self.fail("expected exception")
|
---|
407 | if n is not None:
|
---|
408 | self.fail("expected None: %r" % (n,))
|
---|
409 |
|
---|
410 | if self.d.get_type() == db.DB_BTREE:
|
---|
411 | rec = c.set_range('011')
|
---|
412 | if verbose:
|
---|
413 | print "searched for '011', found: ", rec
|
---|
414 |
|
---|
415 | rec = c.set_range('011',dlen=0,doff=0)
|
---|
416 | if verbose:
|
---|
417 | print "searched (partial) for '011', found: ", rec
|
---|
418 | if rec[1] != '': self.fail('expected empty data portion')
|
---|
419 |
|
---|
420 | ev = c.set_range('empty value')
|
---|
421 | if verbose:
|
---|
422 | print "search for 'empty value' returned", ev
|
---|
423 | if ev[1] != '': self.fail('empty value lookup failed')
|
---|
424 |
|
---|
425 | c.set('0499')
|
---|
426 | c.delete()
|
---|
427 | try:
|
---|
428 | rec = c.current()
|
---|
429 | except db.DBKeyEmptyError, val:
|
---|
430 | if get_raises_error:
|
---|
431 | if sys.version_info < (2, 6) :
|
---|
432 | self.assertEqual(val[0], db.DB_KEYEMPTY)
|
---|
433 | else :
|
---|
434 | self.assertEqual(val.args[0], db.DB_KEYEMPTY)
|
---|
435 | if verbose: print val
|
---|
436 | else:
|
---|
437 | self.fail("unexpected DBKeyEmptyError")
|
---|
438 | else:
|
---|
439 | if get_raises_error:
|
---|
440 | self.fail('DBKeyEmptyError exception expected')
|
---|
441 |
|
---|
442 | c.next()
|
---|
443 | c2 = c.dup(db.DB_POSITION)
|
---|
444 | self.assertEqual(c.current(), c2.current())
|
---|
445 |
|
---|
446 | c2.put('', 'a new value', db.DB_CURRENT)
|
---|
447 | self.assertEqual(c.current(), c2.current())
|
---|
448 | self.assertEqual(c.current()[1], 'a new value')
|
---|
449 |
|
---|
450 | c2.put('', 'er', db.DB_CURRENT, dlen=0, doff=5)
|
---|
451 | self.assertEqual(c2.current()[1], 'a newer value')
|
---|
452 |
|
---|
453 | c.close()
|
---|
454 | c2.close()
|
---|
455 | if txn:
|
---|
456 | txn.commit()
|
---|
457 |
|
---|
458 | # time to abuse the closed cursors and hope we don't crash
|
---|
459 | methods_to_test = {
|
---|
460 | 'current': (),
|
---|
461 | 'delete': (),
|
---|
462 | 'dup': (db.DB_POSITION,),
|
---|
463 | 'first': (),
|
---|
464 | 'get': (0,),
|
---|
465 | 'next': (),
|
---|
466 | 'prev': (),
|
---|
467 | 'last': (),
|
---|
468 | 'put':('', 'spam', db.DB_CURRENT),
|
---|
469 | 'set': ("0505",),
|
---|
470 | }
|
---|
471 | for method, args in methods_to_test.items():
|
---|
472 | try:
|
---|
473 | if verbose:
|
---|
474 | print "attempting to use a closed cursor's %s method" % \
|
---|
475 | method
|
---|
476 | # a bug may cause a NULL pointer dereference...
|
---|
477 | getattr(c, method)(*args)
|
---|
478 | except db.DBError, val:
|
---|
479 | if sys.version_info < (2, 6) :
|
---|
480 | self.assertEqual(val[0], 0)
|
---|
481 | else :
|
---|
482 | self.assertEqual(val.args[0], 0)
|
---|
483 | if verbose: print val
|
---|
484 | else:
|
---|
485 | self.fail("no exception raised when using a buggy cursor's"
|
---|
486 | "%s method" % method)
|
---|
487 |
|
---|
488 | #
|
---|
489 | # free cursor referencing a closed database, it should not barf:
|
---|
490 | #
|
---|
491 | oldcursor = self.d.cursor(txn=txn)
|
---|
492 | self.d.close()
|
---|
493 |
|
---|
494 | # this would originally cause a segfault when the cursor for a
|
---|
495 | # closed database was cleaned up. it should not anymore.
|
---|
496 | # SF pybsddb bug id 667343
|
---|
497 | del oldcursor
|
---|
498 |
|
---|
499 | def test03b_SimpleCursorWithoutGetReturnsNone0(self):
|
---|
500 | # same test but raise exceptions instead of returning None
|
---|
501 | if verbose:
|
---|
502 | print '\n', '-=' * 30
|
---|
503 | print "Running %s.test03b_SimpleCursorStuffWithoutGetReturnsNone..." % \
|
---|
504 | self.__class__.__name__
|
---|
505 |
|
---|
506 | old = self.d.set_get_returns_none(0)
|
---|
507 | self.assertEqual(old, 2)
|
---|
508 | self.test03_SimpleCursorStuff(get_raises_error=1, set_raises_error=1)
|
---|
509 |
|
---|
510 | def test03b_SimpleCursorWithGetReturnsNone1(self):
|
---|
511 | # same test but raise exceptions instead of returning None
|
---|
512 | if verbose:
|
---|
513 | print '\n', '-=' * 30
|
---|
514 | print "Running %s.test03b_SimpleCursorStuffWithoutGetReturnsNone..." % \
|
---|
515 | self.__class__.__name__
|
---|
516 |
|
---|
517 | old = self.d.set_get_returns_none(1)
|
---|
518 | self.test03_SimpleCursorStuff(get_raises_error=0, set_raises_error=1)
|
---|
519 |
|
---|
520 |
|
---|
521 | def test03c_SimpleCursorGetReturnsNone2(self):
|
---|
522 | # same test but raise exceptions instead of returning None
|
---|
523 | if verbose:
|
---|
524 | print '\n', '-=' * 30
|
---|
525 | print "Running %s.test03c_SimpleCursorStuffWithoutSetReturnsNone..." % \
|
---|
526 | self.__class__.__name__
|
---|
527 |
|
---|
528 | old = self.d.set_get_returns_none(1)
|
---|
529 | self.assertEqual(old, 2)
|
---|
530 | old = self.d.set_get_returns_none(2)
|
---|
531 | self.assertEqual(old, 1)
|
---|
532 | self.test03_SimpleCursorStuff(get_raises_error=0, set_raises_error=0)
|
---|
533 |
|
---|
534 | if db.version() >= (4, 6):
|
---|
535 | def test03d_SimpleCursorPriority(self) :
|
---|
536 | c = self.d.cursor()
|
---|
537 | c.set_priority(db.DB_PRIORITY_VERY_LOW) # Positional
|
---|
538 | self.assertEqual(db.DB_PRIORITY_VERY_LOW, c.get_priority())
|
---|
539 | c.set_priority(priority=db.DB_PRIORITY_HIGH) # Keyword
|
---|
540 | self.assertEqual(db.DB_PRIORITY_HIGH, c.get_priority())
|
---|
541 | c.close()
|
---|
542 |
|
---|
543 | #----------------------------------------
|
---|
544 |
|
---|
545 | def test04_PartialGetAndPut(self):
|
---|
546 | d = self.d
|
---|
547 | if verbose:
|
---|
548 | print '\n', '-=' * 30
|
---|
549 | print "Running %s.test04_PartialGetAndPut..." % \
|
---|
550 | self.__class__.__name__
|
---|
551 |
|
---|
552 | key = "partialTest"
|
---|
553 | data = "1" * 1000 + "2" * 1000
|
---|
554 | d.put(key, data)
|
---|
555 | self.assertEqual(d.get(key), data)
|
---|
556 | self.assertEqual(d.get(key, dlen=20, doff=990),
|
---|
557 | ("1" * 10) + ("2" * 10))
|
---|
558 |
|
---|
559 | d.put("partialtest2", ("1" * 30000) + "robin" )
|
---|
560 | self.assertEqual(d.get("partialtest2", dlen=5, doff=30000), "robin")
|
---|
561 |
|
---|
562 | # There seems to be a bug in DB here... Commented out the test for
|
---|
563 | # now.
|
---|
564 | ##self.assertEqual(d.get("partialtest2", dlen=5, doff=30010), "")
|
---|
565 |
|
---|
566 | if self.dbsetflags != db.DB_DUP:
|
---|
567 | # Partial put with duplicate records requires a cursor
|
---|
568 | d.put(key, "0000", dlen=2000, doff=0)
|
---|
569 | self.assertEqual(d.get(key), "0000")
|
---|
570 |
|
---|
571 | d.put(key, "1111", dlen=1, doff=2)
|
---|
572 | self.assertEqual(d.get(key), "0011110")
|
---|
573 |
|
---|
574 | #----------------------------------------
|
---|
575 |
|
---|
576 | def test05_GetSize(self):
|
---|
577 | d = self.d
|
---|
578 | if verbose:
|
---|
579 | print '\n', '-=' * 30
|
---|
580 | print "Running %s.test05_GetSize..." % self.__class__.__name__
|
---|
581 |
|
---|
582 | for i in range(1, 50000, 500):
|
---|
583 | key = "size%s" % i
|
---|
584 | #print "before ", i,
|
---|
585 | d.put(key, "1" * i)
|
---|
586 | #print "after",
|
---|
587 | self.assertEqual(d.get_size(key), i)
|
---|
588 | #print "done"
|
---|
589 |
|
---|
590 | #----------------------------------------
|
---|
591 |
|
---|
592 | def test06_Truncate(self):
|
---|
593 | d = self.d
|
---|
594 | if verbose:
|
---|
595 | print '\n', '-=' * 30
|
---|
596 | print "Running %s.test06_Truncate..." % self.__class__.__name__
|
---|
597 |
|
---|
598 | d.put("abcde", "ABCDE");
|
---|
599 | num = d.truncate()
|
---|
600 | self.assertTrue(num >= 1, "truncate returned <= 0 on non-empty database")
|
---|
601 | num = d.truncate()
|
---|
602 | self.assertEqual(num, 0,
|
---|
603 | "truncate on empty DB returned nonzero (%r)" % (num,))
|
---|
604 |
|
---|
605 | #----------------------------------------
|
---|
606 |
|
---|
607 | def test07_verify(self):
|
---|
608 | # Verify bug solved in 4.7.3pre8
|
---|
609 | self.d.close()
|
---|
610 | d = db.DB(self.env)
|
---|
611 | d.verify(self.filename)
|
---|
612 |
|
---|
613 |
|
---|
614 | #----------------------------------------
|
---|
615 |
|
---|
616 | if db.version() >= (4, 6):
|
---|
617 | def test08_exists(self) :
|
---|
618 | self.d.put("abcde", "ABCDE")
|
---|
619 | self.assertTrue(self.d.exists("abcde") == True,
|
---|
620 | "DB->exists() returns wrong value")
|
---|
621 | self.assertTrue(self.d.exists("x") == False,
|
---|
622 | "DB->exists() returns wrong value")
|
---|
623 |
|
---|
624 | #----------------------------------------
|
---|
625 |
|
---|
626 | if db.version() >= (4, 7):
|
---|
627 | def test_compact(self) :
|
---|
628 | d = self.d
|
---|
629 | self.assertEqual(0, d.compact(flags=db.DB_FREELIST_ONLY))
|
---|
630 | self.assertEqual(0, d.compact(flags=db.DB_FREELIST_ONLY))
|
---|
631 | d.put("abcde", "ABCDE");
|
---|
632 | d.put("bcde", "BCDE");
|
---|
633 | d.put("abc", "ABC");
|
---|
634 | d.put("monty", "python");
|
---|
635 | d.delete("abc")
|
---|
636 | d.delete("bcde")
|
---|
637 | d.compact(start='abcde', stop='monty', txn=None,
|
---|
638 | compact_fillpercent=42, compact_pages=1,
|
---|
639 | compact_timeout=50000000,
|
---|
640 | flags=db.DB_FREELIST_ONLY|db.DB_FREE_SPACE)
|
---|
641 |
|
---|
642 | #----------------------------------------
|
---|
643 |
|
---|
644 | #----------------------------------------------------------------------
|
---|
645 |
|
---|
646 |
|
---|
647 | class BasicBTreeTestCase(BasicTestCase):
|
---|
648 | dbtype = db.DB_BTREE
|
---|
649 |
|
---|
650 |
|
---|
651 | class BasicHashTestCase(BasicTestCase):
|
---|
652 | dbtype = db.DB_HASH
|
---|
653 |
|
---|
654 |
|
---|
655 | class BasicBTreeWithThreadFlagTestCase(BasicTestCase):
|
---|
656 | dbtype = db.DB_BTREE
|
---|
657 | dbopenflags = db.DB_THREAD
|
---|
658 |
|
---|
659 |
|
---|
660 | class BasicHashWithThreadFlagTestCase(BasicTestCase):
|
---|
661 | dbtype = db.DB_HASH
|
---|
662 | dbopenflags = db.DB_THREAD
|
---|
663 |
|
---|
664 |
|
---|
665 | class BasicWithEnvTestCase(BasicTestCase):
|
---|
666 | dbopenflags = db.DB_THREAD
|
---|
667 | useEnv = 1
|
---|
668 | envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
|
---|
669 |
|
---|
670 | #----------------------------------------
|
---|
671 |
|
---|
672 | def test09_EnvRemoveAndRename(self):
|
---|
673 | if not self.env:
|
---|
674 | return
|
---|
675 |
|
---|
676 | if verbose:
|
---|
677 | print '\n', '-=' * 30
|
---|
678 | print "Running %s.test09_EnvRemoveAndRename..." % self.__class__.__name__
|
---|
679 |
|
---|
680 | # can't rename or remove an open DB
|
---|
681 | self.d.close()
|
---|
682 |
|
---|
683 | newname = self.filename + '.renamed'
|
---|
684 | self.env.dbrename(self.filename, None, newname)
|
---|
685 | self.env.dbremove(newname)
|
---|
686 |
|
---|
687 | #----------------------------------------
|
---|
688 |
|
---|
689 | class BasicBTreeWithEnvTestCase(BasicWithEnvTestCase):
|
---|
690 | dbtype = db.DB_BTREE
|
---|
691 |
|
---|
692 |
|
---|
693 | class BasicHashWithEnvTestCase(BasicWithEnvTestCase):
|
---|
694 | dbtype = db.DB_HASH
|
---|
695 |
|
---|
696 |
|
---|
697 | #----------------------------------------------------------------------
|
---|
698 |
|
---|
699 | class BasicTransactionTestCase(BasicTestCase):
|
---|
700 | if (sys.version_info < (2, 7)) or ((sys.version_info >= (3, 0)) and
|
---|
701 | (sys.version_info < (3, 2))) :
|
---|
702 | def assertIn(self, a, b, msg=None) :
|
---|
703 | return self.assertTrue(a in b, msg=msg)
|
---|
704 |
|
---|
705 | dbopenflags = db.DB_THREAD | db.DB_AUTO_COMMIT
|
---|
706 | useEnv = 1
|
---|
707 | envflags = (db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK |
|
---|
708 | db.DB_INIT_TXN)
|
---|
709 | envsetflags = db.DB_AUTO_COMMIT
|
---|
710 |
|
---|
711 |
|
---|
712 | def tearDown(self):
|
---|
713 | self.txn.commit()
|
---|
714 | BasicTestCase.tearDown(self)
|
---|
715 |
|
---|
716 |
|
---|
717 | def populateDB(self):
|
---|
718 | txn = self.env.txn_begin()
|
---|
719 | BasicTestCase.populateDB(self, _txn=txn)
|
---|
720 |
|
---|
721 | self.txn = self.env.txn_begin()
|
---|
722 |
|
---|
723 |
|
---|
724 | def test06_Transactions(self):
|
---|
725 | d = self.d
|
---|
726 | if verbose:
|
---|
727 | print '\n', '-=' * 30
|
---|
728 | print "Running %s.test06_Transactions..." % self.__class__.__name__
|
---|
729 |
|
---|
730 | self.assertEqual(d.get('new rec', txn=self.txn), None)
|
---|
731 | d.put('new rec', 'this is a new record', self.txn)
|
---|
732 | self.assertEqual(d.get('new rec', txn=self.txn),
|
---|
733 | 'this is a new record')
|
---|
734 | self.txn.abort()
|
---|
735 | self.assertEqual(d.get('new rec'), None)
|
---|
736 |
|
---|
737 | self.txn = self.env.txn_begin()
|
---|
738 |
|
---|
739 | self.assertEqual(d.get('new rec', txn=self.txn), None)
|
---|
740 | d.put('new rec', 'this is a new record', self.txn)
|
---|
741 | self.assertEqual(d.get('new rec', txn=self.txn),
|
---|
742 | 'this is a new record')
|
---|
743 | self.txn.commit()
|
---|
744 | self.assertEqual(d.get('new rec'), 'this is a new record')
|
---|
745 |
|
---|
746 | self.txn = self.env.txn_begin()
|
---|
747 | c = d.cursor(self.txn)
|
---|
748 | rec = c.first()
|
---|
749 | count = 0
|
---|
750 | while rec is not None:
|
---|
751 | count = count + 1
|
---|
752 | if verbose and count % 100 == 0:
|
---|
753 | print rec
|
---|
754 | rec = c.next()
|
---|
755 | self.assertEqual(count, self._numKeys+1)
|
---|
756 |
|
---|
757 | c.close() # Cursors *MUST* be closed before commit!
|
---|
758 | self.txn.commit()
|
---|
759 |
|
---|
760 | # flush pending updates
|
---|
761 | self.env.txn_checkpoint (0, 0, 0)
|
---|
762 |
|
---|
763 | statDict = self.env.log_stat(0);
|
---|
764 | self.assertIn('magic', statDict)
|
---|
765 | self.assertIn('version', statDict)
|
---|
766 | self.assertIn('cur_file', statDict)
|
---|
767 | self.assertIn('region_nowait', statDict)
|
---|
768 |
|
---|
769 | # must have at least one log file present:
|
---|
770 | logs = self.env.log_archive(db.DB_ARCH_ABS | db.DB_ARCH_LOG)
|
---|
771 | self.assertNotEqual(logs, None)
|
---|
772 | for log in logs:
|
---|
773 | if verbose:
|
---|
774 | print 'log file: ' + log
|
---|
775 | logs = self.env.log_archive(db.DB_ARCH_REMOVE)
|
---|
776 | self.assertTrue(not logs)
|
---|
777 |
|
---|
778 | self.txn = self.env.txn_begin()
|
---|
779 |
|
---|
780 | #----------------------------------------
|
---|
781 |
|
---|
782 | if db.version() >= (4, 6):
|
---|
783 | def test08_exists(self) :
|
---|
784 | txn = self.env.txn_begin()
|
---|
785 | self.d.put("abcde", "ABCDE", txn=txn)
|
---|
786 | txn.commit()
|
---|
787 | txn = self.env.txn_begin()
|
---|
788 | self.assertTrue(self.d.exists("abcde", txn=txn) == True,
|
---|
789 | "DB->exists() returns wrong value")
|
---|
790 | self.assertTrue(self.d.exists("x", txn=txn) == False,
|
---|
791 | "DB->exists() returns wrong value")
|
---|
792 | txn.abort()
|
---|
793 |
|
---|
794 | #----------------------------------------
|
---|
795 |
|
---|
796 | def test09_TxnTruncate(self):
|
---|
797 | d = self.d
|
---|
798 | if verbose:
|
---|
799 | print '\n', '-=' * 30
|
---|
800 | print "Running %s.test09_TxnTruncate..." % self.__class__.__name__
|
---|
801 |
|
---|
802 | d.put("abcde", "ABCDE");
|
---|
803 | txn = self.env.txn_begin()
|
---|
804 | num = d.truncate(txn)
|
---|
805 | self.assertTrue(num >= 1, "truncate returned <= 0 on non-empty database")
|
---|
806 | num = d.truncate(txn)
|
---|
807 | self.assertEqual(num, 0,
|
---|
808 | "truncate on empty DB returned nonzero (%r)" % (num,))
|
---|
809 | txn.commit()
|
---|
810 |
|
---|
811 | #----------------------------------------
|
---|
812 |
|
---|
813 | def test10_TxnLateUse(self):
|
---|
814 | txn = self.env.txn_begin()
|
---|
815 | txn.abort()
|
---|
816 | try:
|
---|
817 | txn.abort()
|
---|
818 | except db.DBError, e:
|
---|
819 | pass
|
---|
820 | else:
|
---|
821 | raise RuntimeError, "DBTxn.abort() called after DB_TXN no longer valid w/o an exception"
|
---|
822 |
|
---|
823 | txn = self.env.txn_begin()
|
---|
824 | txn.commit()
|
---|
825 | try:
|
---|
826 | txn.commit()
|
---|
827 | except db.DBError, e:
|
---|
828 | pass
|
---|
829 | else:
|
---|
830 | raise RuntimeError, "DBTxn.commit() called after DB_TXN no longer valid w/o an exception"
|
---|
831 |
|
---|
832 |
|
---|
833 | #----------------------------------------
|
---|
834 |
|
---|
835 |
|
---|
836 | if db.version() >= (4, 4):
|
---|
837 | def test_txn_name(self) :
|
---|
838 | txn=self.env.txn_begin()
|
---|
839 | self.assertEqual(txn.get_name(), "")
|
---|
840 | txn.set_name("XXYY")
|
---|
841 | self.assertEqual(txn.get_name(), "XXYY")
|
---|
842 | txn.set_name("")
|
---|
843 | self.assertEqual(txn.get_name(), "")
|
---|
844 | txn.abort()
|
---|
845 |
|
---|
846 | #----------------------------------------
|
---|
847 |
|
---|
848 |
|
---|
849 | def test_txn_set_timeout(self) :
|
---|
850 | txn=self.env.txn_begin()
|
---|
851 | txn.set_timeout(1234567, db.DB_SET_LOCK_TIMEOUT)
|
---|
852 | txn.set_timeout(2345678, flags=db.DB_SET_TXN_TIMEOUT)
|
---|
853 | txn.abort()
|
---|
854 |
|
---|
855 | #----------------------------------------
|
---|
856 |
|
---|
857 | def test_get_tx_max(self) :
|
---|
858 | self.assertEqual(self.env.get_tx_max(), 30)
|
---|
859 |
|
---|
860 | def test_get_tx_timestamp(self) :
|
---|
861 | self.assertEqual(self.env.get_tx_timestamp(), self._t)
|
---|
862 |
|
---|
863 |
|
---|
864 |
|
---|
865 | class BTreeTransactionTestCase(BasicTransactionTestCase):
|
---|
866 | dbtype = db.DB_BTREE
|
---|
867 |
|
---|
868 | class HashTransactionTestCase(BasicTransactionTestCase):
|
---|
869 | dbtype = db.DB_HASH
|
---|
870 |
|
---|
871 |
|
---|
872 |
|
---|
873 | #----------------------------------------------------------------------
|
---|
874 |
|
---|
875 | class BTreeRecnoTestCase(BasicTestCase):
|
---|
876 | dbtype = db.DB_BTREE
|
---|
877 | dbsetflags = db.DB_RECNUM
|
---|
878 |
|
---|
879 | def test09_RecnoInBTree(self):
|
---|
880 | d = self.d
|
---|
881 | if verbose:
|
---|
882 | print '\n', '-=' * 30
|
---|
883 | print "Running %s.test09_RecnoInBTree..." % self.__class__.__name__
|
---|
884 |
|
---|
885 | rec = d.get(200)
|
---|
886 | self.assertEqual(type(rec), type(()))
|
---|
887 | self.assertEqual(len(rec), 2)
|
---|
888 | if verbose:
|
---|
889 | print "Record #200 is ", rec
|
---|
890 |
|
---|
891 | c = d.cursor()
|
---|
892 | c.set('0200')
|
---|
893 | num = c.get_recno()
|
---|
894 | self.assertEqual(type(num), type(1))
|
---|
895 | if verbose:
|
---|
896 | print "recno of d['0200'] is ", num
|
---|
897 |
|
---|
898 | rec = c.current()
|
---|
899 | self.assertEqual(c.set_recno(num), rec)
|
---|
900 |
|
---|
901 | c.close()
|
---|
902 |
|
---|
903 |
|
---|
904 |
|
---|
905 | class BTreeRecnoWithThreadFlagTestCase(BTreeRecnoTestCase):
|
---|
906 | dbopenflags = db.DB_THREAD
|
---|
907 |
|
---|
908 | #----------------------------------------------------------------------
|
---|
909 |
|
---|
910 | class BasicDUPTestCase(BasicTestCase):
|
---|
911 | dbsetflags = db.DB_DUP
|
---|
912 |
|
---|
913 | def test10_DuplicateKeys(self):
|
---|
914 | d = self.d
|
---|
915 | if verbose:
|
---|
916 | print '\n', '-=' * 30
|
---|
917 | print "Running %s.test10_DuplicateKeys..." % \
|
---|
918 | self.__class__.__name__
|
---|
919 |
|
---|
920 | d.put("dup0", "before")
|
---|
921 | for x in "The quick brown fox jumped over the lazy dog.".split():
|
---|
922 | d.put("dup1", x)
|
---|
923 | d.put("dup2", "after")
|
---|
924 |
|
---|
925 | data = d.get("dup1")
|
---|
926 | self.assertEqual(data, "The")
|
---|
927 | if verbose:
|
---|
928 | print data
|
---|
929 |
|
---|
930 | c = d.cursor()
|
---|
931 | rec = c.set("dup1")
|
---|
932 | self.assertEqual(rec, ('dup1', 'The'))
|
---|
933 |
|
---|
934 | next_reg = c.next()
|
---|
935 | self.assertEqual(next_reg, ('dup1', 'quick'))
|
---|
936 |
|
---|
937 | rec = c.set("dup1")
|
---|
938 | count = c.count()
|
---|
939 | self.assertEqual(count, 9)
|
---|
940 |
|
---|
941 | next_dup = c.next_dup()
|
---|
942 | self.assertEqual(next_dup, ('dup1', 'quick'))
|
---|
943 |
|
---|
944 | rec = c.set('dup1')
|
---|
945 | while rec is not None:
|
---|
946 | if verbose:
|
---|
947 | print rec
|
---|
948 | rec = c.next_dup()
|
---|
949 |
|
---|
950 | c.set('dup1')
|
---|
951 | rec = c.next_nodup()
|
---|
952 | self.assertNotEqual(rec[0], 'dup1')
|
---|
953 | if verbose:
|
---|
954 | print rec
|
---|
955 |
|
---|
956 | c.close()
|
---|
957 |
|
---|
958 |
|
---|
959 |
|
---|
960 | class BTreeDUPTestCase(BasicDUPTestCase):
|
---|
961 | dbtype = db.DB_BTREE
|
---|
962 |
|
---|
963 | class HashDUPTestCase(BasicDUPTestCase):
|
---|
964 | dbtype = db.DB_HASH
|
---|
965 |
|
---|
966 | class BTreeDUPWithThreadTestCase(BasicDUPTestCase):
|
---|
967 | dbtype = db.DB_BTREE
|
---|
968 | dbopenflags = db.DB_THREAD
|
---|
969 |
|
---|
970 | class HashDUPWithThreadTestCase(BasicDUPTestCase):
|
---|
971 | dbtype = db.DB_HASH
|
---|
972 | dbopenflags = db.DB_THREAD
|
---|
973 |
|
---|
974 |
|
---|
975 | #----------------------------------------------------------------------
|
---|
976 |
|
---|
977 | class BasicMultiDBTestCase(BasicTestCase):
|
---|
978 | dbname = 'first'
|
---|
979 |
|
---|
980 | def otherType(self):
|
---|
981 | if self.dbtype == db.DB_BTREE:
|
---|
982 | return db.DB_HASH
|
---|
983 | else:
|
---|
984 | return db.DB_BTREE
|
---|
985 |
|
---|
986 | def test11_MultiDB(self):
|
---|
987 | d1 = self.d
|
---|
988 | if verbose:
|
---|
989 | print '\n', '-=' * 30
|
---|
990 | print "Running %s.test11_MultiDB..." % self.__class__.__name__
|
---|
991 |
|
---|
992 | d2 = db.DB(self.env)
|
---|
993 | d2.open(self.filename, "second", self.dbtype,
|
---|
994 | self.dbopenflags|db.DB_CREATE)
|
---|
995 | d3 = db.DB(self.env)
|
---|
996 | d3.open(self.filename, "third", self.otherType(),
|
---|
997 | self.dbopenflags|db.DB_CREATE)
|
---|
998 |
|
---|
999 | for x in "The quick brown fox jumped over the lazy dog".split():
|
---|
1000 | d2.put(x, self.makeData(x))
|
---|
1001 |
|
---|
1002 | for x in string.letters:
|
---|
1003 | d3.put(x, x*70)
|
---|
1004 |
|
---|
1005 | d1.sync()
|
---|
1006 | d2.sync()
|
---|
1007 | d3.sync()
|
---|
1008 | d1.close()
|
---|
1009 | d2.close()
|
---|
1010 | d3.close()
|
---|
1011 |
|
---|
1012 | self.d = d1 = d2 = d3 = None
|
---|
1013 |
|
---|
1014 | self.d = d1 = db.DB(self.env)
|
---|
1015 | d1.open(self.filename, self.dbname, flags = self.dbopenflags)
|
---|
1016 | d2 = db.DB(self.env)
|
---|
1017 | d2.open(self.filename, "second", flags = self.dbopenflags)
|
---|
1018 | d3 = db.DB(self.env)
|
---|
1019 | d3.open(self.filename, "third", flags = self.dbopenflags)
|
---|
1020 |
|
---|
1021 | c1 = d1.cursor()
|
---|
1022 | c2 = d2.cursor()
|
---|
1023 | c3 = d3.cursor()
|
---|
1024 |
|
---|
1025 | count = 0
|
---|
1026 | rec = c1.first()
|
---|
1027 | while rec is not None:
|
---|
1028 | count = count + 1
|
---|
1029 | if verbose and (count % 50) == 0:
|
---|
1030 | print rec
|
---|
1031 | rec = c1.next()
|
---|
1032 | self.assertEqual(count, self._numKeys)
|
---|
1033 |
|
---|
1034 | count = 0
|
---|
1035 | rec = c2.first()
|
---|
1036 | while rec is not None:
|
---|
1037 | count = count + 1
|
---|
1038 | if verbose:
|
---|
1039 | print rec
|
---|
1040 | rec = c2.next()
|
---|
1041 | self.assertEqual(count, 9)
|
---|
1042 |
|
---|
1043 | count = 0
|
---|
1044 | rec = c3.first()
|
---|
1045 | while rec is not None:
|
---|
1046 | count = count + 1
|
---|
1047 | if verbose:
|
---|
1048 | print rec
|
---|
1049 | rec = c3.next()
|
---|
1050 | self.assertEqual(count, len(string.letters))
|
---|
1051 |
|
---|
1052 |
|
---|
1053 | c1.close()
|
---|
1054 | c2.close()
|
---|
1055 | c3.close()
|
---|
1056 |
|
---|
1057 | d2.close()
|
---|
1058 | d3.close()
|
---|
1059 |
|
---|
1060 |
|
---|
1061 |
|
---|
1062 | # Strange things happen if you try to use Multiple DBs per file without a
|
---|
1063 | # DBEnv with MPOOL and LOCKing...
|
---|
1064 |
|
---|
1065 | class BTreeMultiDBTestCase(BasicMultiDBTestCase):
|
---|
1066 | dbtype = db.DB_BTREE
|
---|
1067 | dbopenflags = db.DB_THREAD
|
---|
1068 | useEnv = 1
|
---|
1069 | envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
|
---|
1070 |
|
---|
1071 | class HashMultiDBTestCase(BasicMultiDBTestCase):
|
---|
1072 | dbtype = db.DB_HASH
|
---|
1073 | dbopenflags = db.DB_THREAD
|
---|
1074 | useEnv = 1
|
---|
1075 | envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
|
---|
1076 |
|
---|
1077 |
|
---|
1078 | class PrivateObject(unittest.TestCase) :
|
---|
1079 | def tearDown(self) :
|
---|
1080 | del self.obj
|
---|
1081 |
|
---|
1082 | def test01_DefaultIsNone(self) :
|
---|
1083 | self.assertEqual(self.obj.get_private(), None)
|
---|
1084 |
|
---|
1085 | def test02_assignment(self) :
|
---|
1086 | a = "example of private object"
|
---|
1087 | self.obj.set_private(a)
|
---|
1088 | b = self.obj.get_private()
|
---|
1089 | self.assertTrue(a is b) # Object identity
|
---|
1090 |
|
---|
1091 | def test03_leak_assignment(self) :
|
---|
1092 | a = "example of private object"
|
---|
1093 | refcount = sys.getrefcount(a)
|
---|
1094 | self.obj.set_private(a)
|
---|
1095 | self.assertEqual(refcount+1, sys.getrefcount(a))
|
---|
1096 | self.obj.set_private(None)
|
---|
1097 | self.assertEqual(refcount, sys.getrefcount(a))
|
---|
1098 |
|
---|
1099 | def test04_leak_GC(self) :
|
---|
1100 | a = "example of private object"
|
---|
1101 | refcount = sys.getrefcount(a)
|
---|
1102 | self.obj.set_private(a)
|
---|
1103 | self.obj = None
|
---|
1104 | self.assertEqual(refcount, sys.getrefcount(a))
|
---|
1105 |
|
---|
1106 | class DBEnvPrivateObject(PrivateObject) :
|
---|
1107 | def setUp(self) :
|
---|
1108 | self.obj = db.DBEnv()
|
---|
1109 |
|
---|
1110 | class DBPrivateObject(PrivateObject) :
|
---|
1111 | def setUp(self) :
|
---|
1112 | self.obj = db.DB()
|
---|
1113 |
|
---|
1114 | class CrashAndBurn(unittest.TestCase) :
|
---|
1115 | #def test01_OpenCrash(self) :
|
---|
1116 | # # See http://bugs.python.org/issue3307
|
---|
1117 | # self.assertRaises(db.DBInvalidArgError, db.DB, None, 65535)
|
---|
1118 |
|
---|
1119 | if db.version() < (4, 8) :
|
---|
1120 | def test02_DBEnv_dealloc(self):
|
---|
1121 | # http://bugs.python.org/issue3885
|
---|
1122 | import gc
|
---|
1123 | self.assertRaises(db.DBInvalidArgError, db.DBEnv, ~db.DB_RPCCLIENT)
|
---|
1124 | gc.collect()
|
---|
1125 |
|
---|
1126 |
|
---|
1127 | #----------------------------------------------------------------------
|
---|
1128 | #----------------------------------------------------------------------
|
---|
1129 |
|
---|
1130 | def test_suite():
|
---|
1131 | suite = unittest.TestSuite()
|
---|
1132 |
|
---|
1133 | suite.addTest(unittest.makeSuite(VersionTestCase))
|
---|
1134 | suite.addTest(unittest.makeSuite(BasicBTreeTestCase))
|
---|
1135 | suite.addTest(unittest.makeSuite(BasicHashTestCase))
|
---|
1136 | suite.addTest(unittest.makeSuite(BasicBTreeWithThreadFlagTestCase))
|
---|
1137 | suite.addTest(unittest.makeSuite(BasicHashWithThreadFlagTestCase))
|
---|
1138 | suite.addTest(unittest.makeSuite(BasicBTreeWithEnvTestCase))
|
---|
1139 | suite.addTest(unittest.makeSuite(BasicHashWithEnvTestCase))
|
---|
1140 | suite.addTest(unittest.makeSuite(BTreeTransactionTestCase))
|
---|
1141 | suite.addTest(unittest.makeSuite(HashTransactionTestCase))
|
---|
1142 | suite.addTest(unittest.makeSuite(BTreeRecnoTestCase))
|
---|
1143 | suite.addTest(unittest.makeSuite(BTreeRecnoWithThreadFlagTestCase))
|
---|
1144 | suite.addTest(unittest.makeSuite(BTreeDUPTestCase))
|
---|
1145 | suite.addTest(unittest.makeSuite(HashDUPTestCase))
|
---|
1146 | suite.addTest(unittest.makeSuite(BTreeDUPWithThreadTestCase))
|
---|
1147 | suite.addTest(unittest.makeSuite(HashDUPWithThreadTestCase))
|
---|
1148 | suite.addTest(unittest.makeSuite(BTreeMultiDBTestCase))
|
---|
1149 | suite.addTest(unittest.makeSuite(HashMultiDBTestCase))
|
---|
1150 | suite.addTest(unittest.makeSuite(DBEnvPrivateObject))
|
---|
1151 | suite.addTest(unittest.makeSuite(DBPrivateObject))
|
---|
1152 | suite.addTest(unittest.makeSuite(CrashAndBurn))
|
---|
1153 |
|
---|
1154 | return suite
|
---|
1155 |
|
---|
1156 |
|
---|
1157 | if __name__ == '__main__':
|
---|
1158 | unittest.main(defaultTest='test_suite')
|
---|