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.ascii_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.ascii_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') |
---|