Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / src / nas,5.n2.os.2 / lib / python / lib / python2.4 / bsddb / test / test_basics.py
CommitLineData
86530b38
AT
1"""
2Basic TestCases for BTree and hash DBs, with and without a DBEnv, with
3various DB flags, etc.
4"""
5
6import os
7import sys
8import errno
9import shutil
10import string
11import tempfile
12from pprint import pprint
13import unittest
14
15try:
16 # For Pythons w/distutils pybsddb
17 from bsddb3 import db
18except ImportError:
19 # For Python 2.3
20 from bsddb import db
21
22from test_all import verbose
23
24DASH = '-'
25
26
27#----------------------------------------------------------------------
28
29class VersionTestCase(unittest.TestCase):
30 def test00_version(self):
31 info = db.version()
32 if verbose:
33 print '\n', '-=' * 20
34 print 'bsddb.db.version(): %s' % (info, )
35 print db.DB_VERSION_STRING
36 print '-=' * 20
37 assert info == (db.DB_VERSION_MAJOR, db.DB_VERSION_MINOR,
38 db.DB_VERSION_PATCH)
39
40#----------------------------------------------------------------------
41
42class BasicTestCase(unittest.TestCase):
43 dbtype = db.DB_UNKNOWN # must be set in derived class
44 dbopenflags = 0
45 dbsetflags = 0
46 dbmode = 0660
47 dbname = None
48 useEnv = 0
49 envflags = 0
50 envsetflags = 0
51
52 _numKeys = 1002 # PRIVATE. NOTE: must be an even value
53
54 def setUp(self):
55 if self.useEnv:
56 homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
57 self.homeDir = homeDir
58 try:
59 shutil.rmtree(homeDir)
60 except OSError, e:
61 # unix returns ENOENT, windows returns ESRCH
62 if e.errno not in (errno.ENOENT, errno.ESRCH): raise
63 os.mkdir(homeDir)
64 try:
65 self.env = db.DBEnv()
66 self.env.set_lg_max(1024*1024)
67 self.env.set_flags(self.envsetflags, 1)
68 self.env.open(homeDir, self.envflags | db.DB_CREATE)
69 tempfile.tempdir = homeDir
70 self.filename = os.path.split(tempfile.mktemp())[1]
71 tempfile.tempdir = None
72 # Yes, a bare except is intended, since we're re-raising the exc.
73 except:
74 shutil.rmtree(homeDir)
75 raise
76 else:
77 self.env = None
78 self.filename = tempfile.mktemp()
79
80 # create and open the DB
81 self.d = db.DB(self.env)
82 self.d.set_flags(self.dbsetflags)
83 if self.dbname:
84 self.d.open(self.filename, self.dbname, self.dbtype,
85 self.dbopenflags|db.DB_CREATE, self.dbmode)
86 else:
87 self.d.open(self.filename, # try out keyword args
88 mode = self.dbmode,
89 dbtype = self.dbtype,
90 flags = self.dbopenflags|db.DB_CREATE)
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 shutil.rmtree(self.homeDir)
100 ## Make a new DBEnv to remove the env files from the home dir.
101 ## (It can't be done while the env is open, nor after it has been
102 ## closed, so we make a new one to do it.)
103 #e = db.DBEnv()
104 #e.remove(self.homeDir)
105 #os.remove(os.path.join(self.homeDir, self.filename))
106 else:
107 os.remove(self.filename)
108
109
110
111 def populateDB(self, _txn=None):
112 d = self.d
113
114 for x in range(self._numKeys/2):
115 key = '%04d' % (self._numKeys - x) # insert keys in reverse order
116 data = self.makeData(key)
117 d.put(key, data, _txn)
118
119 d.put('empty value', '', _txn)
120
121 for x in range(self._numKeys/2-1):
122 key = '%04d' % x # and now some in forward order
123 data = self.makeData(key)
124 d.put(key, data, _txn)
125
126 if _txn:
127 _txn.commit()
128
129 num = len(d)
130 if verbose:
131 print "created %d records" % num
132
133
134 def makeData(self, key):
135 return DASH.join([key] * 5)
136
137
138
139 #----------------------------------------
140
141 def test01_GetsAndPuts(self):
142 d = self.d
143
144 if verbose:
145 print '\n', '-=' * 30
146 print "Running %s.test01_GetsAndPuts..." % self.__class__.__name__
147
148 for key in ['0001', '0100', '0400', '0700', '0999']:
149 data = d.get(key)
150 if verbose:
151 print data
152
153 assert d.get('0321') == '0321-0321-0321-0321-0321'
154
155 # By default non-existant keys return None...
156 assert d.get('abcd') == None
157
158 # ...but they raise exceptions in other situations. Call
159 # set_get_returns_none() to change it.
160 try:
161 d.delete('abcd')
162 except db.DBNotFoundError, val:
163 assert val[0] == db.DB_NOTFOUND
164 if verbose: print val
165 else:
166 self.fail("expected exception")
167
168
169 d.put('abcd', 'a new record')
170 assert d.get('abcd') == 'a new record'
171
172 d.put('abcd', 'same key')
173 if self.dbsetflags & db.DB_DUP:
174 assert d.get('abcd') == 'a new record'
175 else:
176 assert d.get('abcd') == 'same key'
177
178
179 try:
180 d.put('abcd', 'this should fail', flags=db.DB_NOOVERWRITE)
181 except db.DBKeyExistError, val:
182 assert val[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 assert d.get('abcd') == 'a new record'
189 else:
190 assert 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 assert d.get('0321') == '0321-0321-0321-0321-0321'
205 if self.dbsetflags & db.DB_DUP:
206 assert d.get('abcd') == 'a new record'
207 else:
208 assert 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 assert d.get_both('0555', 'bad data') == None
215
216 # test default value
217 data = d.get('bad key', 'bad data')
218 assert data == 'bad data'
219
220 # any object can pass through
221 data = d.get('bad key', self)
222 assert data == self
223
224 s = d.stat()
225 assert 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 assert data == self.makeData(key)
244 if verbose:
245 print data
246
247 assert len(d) == self._numKeys
248 keys = d.keys()
249 assert len(keys) == self._numKeys
250 assert type(keys) == type([])
251
252 d['new record'] = 'a new record'
253 assert len(d) == self._numKeys+1
254 keys = d.keys()
255 assert len(keys) == self._numKeys+1
256
257 d['new record'] = 'a replacement record'
258 assert len(d) == self._numKeys+1
259 keys = d.keys()
260 assert len(keys) == self._numKeys+1
261
262 if verbose:
263 print "the first 10 keys are:"
264 pprint(keys[:10])
265
266 assert d['new record'] == 'a replacement record'
267
268 assert d.has_key('0001') == 1
269 assert d.has_key('spam') == 0
270
271 items = d.items()
272 assert len(items) == self._numKeys+1
273 assert type(items) == type([])
274 assert type(items[0]) == type(())
275 assert len(items[0]) == 2
276
277 if verbose:
278 print "the first 10 items are:"
279 pprint(items[:10])
280
281 values = d.values()
282 assert len(values) == self._numKeys+1
283 assert type(values) == type([])
284
285 if verbose:
286 print "the first 10 values are:"
287 pprint(values[:10])
288
289
290
291 #----------------------------------------
292
293 def test03_SimpleCursorStuff(self, get_raises_error=0, set_raises_error=0):
294 if verbose:
295 print '\n', '-=' * 30
296 print "Running %s.test03_SimpleCursorStuff (get_error %s, set_error %s)..." % \
297 (self.__class__.__name__, get_raises_error, set_raises_error)
298
299 if self.env and self.dbopenflags & db.DB_AUTO_COMMIT:
300 txn = self.env.txn_begin()
301 else:
302 txn = None
303 c = self.d.cursor(txn=txn)
304
305 rec = c.first()
306 count = 0
307 while rec is not None:
308 count = count + 1
309 if verbose and count % 100 == 0:
310 print rec
311 try:
312 rec = c.next()
313 except db.DBNotFoundError, val:
314 if get_raises_error:
315 assert val[0] == db.DB_NOTFOUND
316 if verbose: print val
317 rec = None
318 else:
319 self.fail("unexpected DBNotFoundError")
320 assert c.get_current_size() == len(c.current()[1]), "%s != len(%r)" % (c.get_current_size(), c.current()[1])
321
322 assert count == self._numKeys
323
324
325 rec = c.last()
326 count = 0
327 while rec is not None:
328 count = count + 1
329 if verbose and count % 100 == 0:
330 print rec
331 try:
332 rec = c.prev()
333 except db.DBNotFoundError, val:
334 if get_raises_error:
335 assert val[0] == db.DB_NOTFOUND
336 if verbose: print val
337 rec = None
338 else:
339 self.fail("unexpected DBNotFoundError")
340
341 assert count == self._numKeys
342
343 rec = c.set('0505')
344 rec2 = c.current()
345 assert rec == rec2
346 assert rec[0] == '0505'
347 assert rec[1] == self.makeData('0505')
348 assert c.get_current_size() == len(rec[1])
349
350 # make sure we get empty values properly
351 rec = c.set('empty value')
352 assert rec[1] == ''
353 assert c.get_current_size() == 0
354
355 try:
356 n = c.set('bad key')
357 except db.DBNotFoundError, val:
358 assert val[0] == db.DB_NOTFOUND
359 if verbose: print val
360 else:
361 if set_raises_error:
362 self.fail("expected exception")
363 if n != None:
364 self.fail("expected None: %r" % (n,))
365
366 rec = c.get_both('0404', self.makeData('0404'))
367 assert rec == ('0404', self.makeData('0404'))
368
369 try:
370 n = c.get_both('0404', 'bad data')
371 except db.DBNotFoundError, val:
372 assert val[0] == db.DB_NOTFOUND
373 if verbose: print val
374 else:
375 if get_raises_error:
376 self.fail("expected exception")
377 if n != None:
378 self.fail("expected None: %r" % (n,))
379
380 if self.d.get_type() == db.DB_BTREE:
381 rec = c.set_range('011')
382 if verbose:
383 print "searched for '011', found: ", rec
384
385 rec = c.set_range('011',dlen=0,doff=0)
386 if verbose:
387 print "searched (partial) for '011', found: ", rec
388 if rec[1] != '': self.fail('expected empty data portion')
389
390 ev = c.set_range('empty value')
391 if verbose:
392 print "search for 'empty value' returned", ev
393 if ev[1] != '': self.fail('empty value lookup failed')
394
395 c.set('0499')
396 c.delete()
397 try:
398 rec = c.current()
399 except db.DBKeyEmptyError, val:
400 assert val[0] == db.DB_KEYEMPTY
401 if verbose: print val
402 else:
403 self.fail('exception expected')
404
405 c.next()
406 c2 = c.dup(db.DB_POSITION)
407 assert c.current() == c2.current()
408
409 c2.put('', 'a new value', db.DB_CURRENT)
410 assert c.current() == c2.current()
411 assert c.current()[1] == 'a new value'
412
413 c2.put('', 'er', db.DB_CURRENT, dlen=0, doff=5)
414 assert c2.current()[1] == 'a newer value'
415
416 c.close()
417 c2.close()
418 if txn:
419 txn.commit()
420
421 # time to abuse the closed cursors and hope we don't crash
422 methods_to_test = {
423 'current': (),
424 'delete': (),
425 'dup': (db.DB_POSITION,),
426 'first': (),
427 'get': (0,),
428 'next': (),
429 'prev': (),
430 'last': (),
431 'put':('', 'spam', db.DB_CURRENT),
432 'set': ("0505",),
433 }
434 for method, args in methods_to_test.items():
435 try:
436 if verbose:
437 print "attempting to use a closed cursor's %s method" % \
438 method
439 # a bug may cause a NULL pointer dereference...
440 apply(getattr(c, method), args)
441 except db.DBError, val:
442 assert val[0] == 0
443 if verbose: print val
444 else:
445 self.fail("no exception raised when using a buggy cursor's"
446 "%s method" % method)
447
448 #
449 # free cursor referencing a closed database, it should not barf:
450 #
451 oldcursor = self.d.cursor(txn=txn)
452 self.d.close()
453
454 # this would originally cause a segfault when the cursor for a
455 # closed database was cleaned up. it should not anymore.
456 # SF pybsddb bug id 667343
457 del oldcursor
458
459 def test03b_SimpleCursorWithoutGetReturnsNone0(self):
460 # same test but raise exceptions instead of returning None
461 if verbose:
462 print '\n', '-=' * 30
463 print "Running %s.test03b_SimpleCursorStuffWithoutGetReturnsNone..." % \
464 self.__class__.__name__
465
466 old = self.d.set_get_returns_none(0)
467 assert old == 2
468 self.test03_SimpleCursorStuff(get_raises_error=1, set_raises_error=1)
469
470 def test03b_SimpleCursorWithGetReturnsNone1(self):
471 # same test but raise exceptions instead of returning None
472 if verbose:
473 print '\n', '-=' * 30
474 print "Running %s.test03b_SimpleCursorStuffWithoutGetReturnsNone..." % \
475 self.__class__.__name__
476
477 old = self.d.set_get_returns_none(1)
478 self.test03_SimpleCursorStuff(get_raises_error=0, set_raises_error=1)
479
480
481 def test03c_SimpleCursorGetReturnsNone2(self):
482 # same test but raise exceptions instead of returning None
483 if verbose:
484 print '\n', '-=' * 30
485 print "Running %s.test03c_SimpleCursorStuffWithoutSetReturnsNone..." % \
486 self.__class__.__name__
487
488 old = self.d.set_get_returns_none(1)
489 assert old == 2
490 old = self.d.set_get_returns_none(2)
491 assert old == 1
492 self.test03_SimpleCursorStuff(get_raises_error=0, set_raises_error=0)
493
494 #----------------------------------------
495
496 def test04_PartialGetAndPut(self):
497 d = self.d
498 if verbose:
499 print '\n', '-=' * 30
500 print "Running %s.test04_PartialGetAndPut..." % \
501 self.__class__.__name__
502
503 key = "partialTest"
504 data = "1" * 1000 + "2" * 1000
505 d.put(key, data)
506 assert d.get(key) == data
507 assert d.get(key, dlen=20, doff=990) == ("1" * 10) + ("2" * 10)
508
509 d.put("partialtest2", ("1" * 30000) + "robin" )
510 assert d.get("partialtest2", dlen=5, doff=30000) == "robin"
511
512 # There seems to be a bug in DB here... Commented out the test for
513 # now.
514 ##assert d.get("partialtest2", dlen=5, doff=30010) == ""
515
516 if self.dbsetflags != db.DB_DUP:
517 # Partial put with duplicate records requires a cursor
518 d.put(key, "0000", dlen=2000, doff=0)
519 assert d.get(key) == "0000"
520
521 d.put(key, "1111", dlen=1, doff=2)
522 assert d.get(key) == "0011110"
523
524 #----------------------------------------
525
526 def test05_GetSize(self):
527 d = self.d
528 if verbose:
529 print '\n', '-=' * 30
530 print "Running %s.test05_GetSize..." % self.__class__.__name__
531
532 for i in range(1, 50000, 500):
533 key = "size%s" % i
534 #print "before ", i,
535 d.put(key, "1" * i)
536 #print "after",
537 assert d.get_size(key) == i
538 #print "done"
539
540 #----------------------------------------
541
542 def test06_Truncate(self):
543 if db.version() < (3,3):
544 # truncate is a feature of BerkeleyDB 3.3 and above
545 return
546
547 d = self.d
548 if verbose:
549 print '\n', '-=' * 30
550 print "Running %s.test99_Truncate..." % self.__class__.__name__
551
552 d.put("abcde", "ABCDE");
553 num = d.truncate()
554 assert num >= 1, "truncate returned <= 0 on non-empty database"
555 num = d.truncate()
556 assert num == 0, "truncate on empty DB returned nonzero (%r)" % (num,)
557
558#----------------------------------------------------------------------
559
560
561class BasicBTreeTestCase(BasicTestCase):
562 dbtype = db.DB_BTREE
563
564
565class BasicHashTestCase(BasicTestCase):
566 dbtype = db.DB_HASH
567
568
569class BasicBTreeWithThreadFlagTestCase(BasicTestCase):
570 dbtype = db.DB_BTREE
571 dbopenflags = db.DB_THREAD
572
573
574class BasicHashWithThreadFlagTestCase(BasicTestCase):
575 dbtype = db.DB_HASH
576 dbopenflags = db.DB_THREAD
577
578
579class BasicBTreeWithEnvTestCase(BasicTestCase):
580 dbtype = db.DB_BTREE
581 dbopenflags = db.DB_THREAD
582 useEnv = 1
583 envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
584
585
586class BasicHashWithEnvTestCase(BasicTestCase):
587 dbtype = db.DB_HASH
588 dbopenflags = db.DB_THREAD
589 useEnv = 1
590 envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
591
592
593#----------------------------------------------------------------------
594
595class BasicTransactionTestCase(BasicTestCase):
596 dbopenflags = db.DB_THREAD | db.DB_AUTO_COMMIT
597 useEnv = 1
598 envflags = (db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK |
599 db.DB_INIT_TXN)
600 envsetflags = db.DB_AUTO_COMMIT
601
602
603 def tearDown(self):
604 self.txn.commit()
605 BasicTestCase.tearDown(self)
606
607
608 def populateDB(self):
609 txn = self.env.txn_begin()
610 BasicTestCase.populateDB(self, _txn=txn)
611
612 self.txn = self.env.txn_begin()
613
614
615
616 def test06_Transactions(self):
617 d = self.d
618 if verbose:
619 print '\n', '-=' * 30
620 print "Running %s.test06_Transactions..." % self.__class__.__name__
621
622 assert d.get('new rec', txn=self.txn) == None
623 d.put('new rec', 'this is a new record', self.txn)
624 assert d.get('new rec', txn=self.txn) == 'this is a new record'
625 self.txn.abort()
626 assert d.get('new rec') == None
627
628 self.txn = self.env.txn_begin()
629
630 assert d.get('new rec', txn=self.txn) == None
631 d.put('new rec', 'this is a new record', self.txn)
632 assert d.get('new rec', txn=self.txn) == 'this is a new record'
633 self.txn.commit()
634 assert d.get('new rec') == 'this is a new record'
635
636 self.txn = self.env.txn_begin()
637 c = d.cursor(self.txn)
638 rec = c.first()
639 count = 0
640 while rec is not None:
641 count = count + 1
642 if verbose and count % 100 == 0:
643 print rec
644 rec = c.next()
645 assert count == self._numKeys+1
646
647 c.close() # Cursors *MUST* be closed before commit!
648 self.txn.commit()
649
650 # flush pending updates
651 try:
652 self.env.txn_checkpoint (0, 0, 0)
653 except db.DBIncompleteError:
654 pass
655
656 # must have at least one log file present:
657 logs = self.env.log_archive(db.DB_ARCH_ABS | db.DB_ARCH_LOG)
658 assert logs != None
659 for log in logs:
660 if verbose:
661 print 'log file: ' + log
662
663 self.txn = self.env.txn_begin()
664
665 #----------------------------------------
666
667 def test07_TxnTruncate(self):
668 if db.version() < (3,3):
669 # truncate is a feature of BerkeleyDB 3.3 and above
670 return
671
672 d = self.d
673 if verbose:
674 print '\n', '-=' * 30
675 print "Running %s.test07_TxnTruncate..." % self.__class__.__name__
676
677 d.put("abcde", "ABCDE");
678 txn = self.env.txn_begin()
679 num = d.truncate(txn)
680 assert num >= 1, "truncate returned <= 0 on non-empty database"
681 num = d.truncate(txn)
682 assert num == 0, "truncate on empty DB returned nonzero (%r)" % (num,)
683 txn.commit()
684
685 #----------------------------------------
686
687 def test08_TxnLateUse(self):
688 txn = self.env.txn_begin()
689 txn.abort()
690 try:
691 txn.abort()
692 except db.DBError, e:
693 pass
694 else:
695 raise RuntimeError, "DBTxn.abort() called after DB_TXN no longer valid w/o an exception"
696
697 txn = self.env.txn_begin()
698 txn.commit()
699 try:
700 txn.commit()
701 except db.DBError, e:
702 pass
703 else:
704 raise RuntimeError, "DBTxn.commit() called after DB_TXN no longer valid w/o an exception"
705
706
707class BTreeTransactionTestCase(BasicTransactionTestCase):
708 dbtype = db.DB_BTREE
709
710class HashTransactionTestCase(BasicTransactionTestCase):
711 dbtype = db.DB_HASH
712
713
714
715#----------------------------------------------------------------------
716
717class BTreeRecnoTestCase(BasicTestCase):
718 dbtype = db.DB_BTREE
719 dbsetflags = db.DB_RECNUM
720
721 def test07_RecnoInBTree(self):
722 d = self.d
723 if verbose:
724 print '\n', '-=' * 30
725 print "Running %s.test07_RecnoInBTree..." % self.__class__.__name__
726
727 rec = d.get(200)
728 assert type(rec) == type(())
729 assert len(rec) == 2
730 if verbose:
731 print "Record #200 is ", rec
732
733 c = d.cursor()
734 c.set('0200')
735 num = c.get_recno()
736 assert type(num) == type(1)
737 if verbose:
738 print "recno of d['0200'] is ", num
739
740 rec = c.current()
741 assert c.set_recno(num) == rec
742
743 c.close()
744
745
746
747class BTreeRecnoWithThreadFlagTestCase(BTreeRecnoTestCase):
748 dbopenflags = db.DB_THREAD
749
750#----------------------------------------------------------------------
751
752class BasicDUPTestCase(BasicTestCase):
753 dbsetflags = db.DB_DUP
754
755 def test08_DuplicateKeys(self):
756 d = self.d
757 if verbose:
758 print '\n', '-=' * 30
759 print "Running %s.test08_DuplicateKeys..." % \
760 self.__class__.__name__
761
762 d.put("dup0", "before")
763 for x in "The quick brown fox jumped over the lazy dog.".split():
764 d.put("dup1", x)
765 d.put("dup2", "after")
766
767 data = d.get("dup1")
768 assert data == "The"
769 if verbose:
770 print data
771
772 c = d.cursor()
773 rec = c.set("dup1")
774 assert rec == ('dup1', 'The')
775
776 next = c.next()
777 assert next == ('dup1', 'quick')
778
779 rec = c.set("dup1")
780 count = c.count()
781 assert count == 9
782
783 next_dup = c.next_dup()
784 assert next_dup == ('dup1', 'quick')
785
786 rec = c.set('dup1')
787 while rec is not None:
788 if verbose:
789 print rec
790 rec = c.next_dup()
791
792 c.set('dup1')
793 rec = c.next_nodup()
794 assert rec[0] != 'dup1'
795 if verbose:
796 print rec
797
798 c.close()
799
800
801
802class BTreeDUPTestCase(BasicDUPTestCase):
803 dbtype = db.DB_BTREE
804
805class HashDUPTestCase(BasicDUPTestCase):
806 dbtype = db.DB_HASH
807
808class BTreeDUPWithThreadTestCase(BasicDUPTestCase):
809 dbtype = db.DB_BTREE
810 dbopenflags = db.DB_THREAD
811
812class HashDUPWithThreadTestCase(BasicDUPTestCase):
813 dbtype = db.DB_HASH
814 dbopenflags = db.DB_THREAD
815
816
817#----------------------------------------------------------------------
818
819class BasicMultiDBTestCase(BasicTestCase):
820 dbname = 'first'
821
822 def otherType(self):
823 if self.dbtype == db.DB_BTREE:
824 return db.DB_HASH
825 else:
826 return db.DB_BTREE
827
828 def test09_MultiDB(self):
829 d1 = self.d
830 if verbose:
831 print '\n', '-=' * 30
832 print "Running %s.test09_MultiDB..." % self.__class__.__name__
833
834 d2 = db.DB(self.env)
835 d2.open(self.filename, "second", self.dbtype,
836 self.dbopenflags|db.DB_CREATE)
837 d3 = db.DB(self.env)
838 d3.open(self.filename, "third", self.otherType(),
839 self.dbopenflags|db.DB_CREATE)
840
841 for x in "The quick brown fox jumped over the lazy dog".split():
842 d2.put(x, self.makeData(x))
843
844 for x in string.letters:
845 d3.put(x, x*70)
846
847 d1.sync()
848 d2.sync()
849 d3.sync()
850 d1.close()
851 d2.close()
852 d3.close()
853
854 self.d = d1 = d2 = d3 = None
855
856 self.d = d1 = db.DB(self.env)
857 d1.open(self.filename, self.dbname, flags = self.dbopenflags)
858 d2 = db.DB(self.env)
859 d2.open(self.filename, "second", flags = self.dbopenflags)
860 d3 = db.DB(self.env)
861 d3.open(self.filename, "third", flags = self.dbopenflags)
862
863 c1 = d1.cursor()
864 c2 = d2.cursor()
865 c3 = d3.cursor()
866
867 count = 0
868 rec = c1.first()
869 while rec is not None:
870 count = count + 1
871 if verbose and (count % 50) == 0:
872 print rec
873 rec = c1.next()
874 assert count == self._numKeys
875
876 count = 0
877 rec = c2.first()
878 while rec is not None:
879 count = count + 1
880 if verbose:
881 print rec
882 rec = c2.next()
883 assert count == 9
884
885 count = 0
886 rec = c3.first()
887 while rec is not None:
888 count = count + 1
889 if verbose:
890 print rec
891 rec = c3.next()
892 assert count == 52
893
894
895 c1.close()
896 c2.close()
897 c3.close()
898
899 d2.close()
900 d3.close()
901
902
903
904# Strange things happen if you try to use Multiple DBs per file without a
905# DBEnv with MPOOL and LOCKing...
906
907class BTreeMultiDBTestCase(BasicMultiDBTestCase):
908 dbtype = db.DB_BTREE
909 dbopenflags = db.DB_THREAD
910 useEnv = 1
911 envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
912
913class HashMultiDBTestCase(BasicMultiDBTestCase):
914 dbtype = db.DB_HASH
915 dbopenflags = db.DB_THREAD
916 useEnv = 1
917 envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
918
919
920#----------------------------------------------------------------------
921#----------------------------------------------------------------------
922
923def test_suite():
924 suite = unittest.TestSuite()
925
926 suite.addTest(unittest.makeSuite(VersionTestCase))
927 suite.addTest(unittest.makeSuite(BasicBTreeTestCase))
928 suite.addTest(unittest.makeSuite(BasicHashTestCase))
929 suite.addTest(unittest.makeSuite(BasicBTreeWithThreadFlagTestCase))
930 suite.addTest(unittest.makeSuite(BasicHashWithThreadFlagTestCase))
931 suite.addTest(unittest.makeSuite(BasicBTreeWithEnvTestCase))
932 suite.addTest(unittest.makeSuite(BasicHashWithEnvTestCase))
933 suite.addTest(unittest.makeSuite(BTreeTransactionTestCase))
934 suite.addTest(unittest.makeSuite(HashTransactionTestCase))
935 suite.addTest(unittest.makeSuite(BTreeRecnoTestCase))
936 suite.addTest(unittest.makeSuite(BTreeRecnoWithThreadFlagTestCase))
937 suite.addTest(unittest.makeSuite(BTreeDUPTestCase))
938 suite.addTest(unittest.makeSuite(HashDUPTestCase))
939 suite.addTest(unittest.makeSuite(BTreeDUPWithThreadTestCase))
940 suite.addTest(unittest.makeSuite(HashDUPWithThreadTestCase))
941 suite.addTest(unittest.makeSuite(BTreeMultiDBTestCase))
942 suite.addTest(unittest.makeSuite(HashMultiDBTestCase))
943
944 return suite
945
946
947if __name__ == '__main__':
948 unittest.main(defaultTest='test_suite')