PyXR

c:\python24\lib \ bsddb \ test \ test_basics.py



0001 """
0002 Basic TestCases for BTree and hash DBs, with and without a DBEnv, with
0003 various DB flags, etc.
0004 """
0005 
0006 import os
0007 import sys
0008 import errno
0009 import shutil
0010 import string
0011 import tempfile
0012 from pprint import pprint
0013 import unittest
0014 
0015 try:
0016     # For Pythons w/distutils pybsddb
0017     from bsddb3 import db
0018 except ImportError:
0019     # For Python 2.3
0020     from bsddb import db
0021 
0022 from test_all import verbose
0023 
0024 DASH = '-'
0025 
0026 
0027 #----------------------------------------------------------------------
0028 
0029 class VersionTestCase(unittest.TestCase):
0030     def test00_version(self):
0031         info = db.version()
0032         if verbose:
0033             print '\n', '-=' * 20
0034             print 'bsddb.db.version(): %s' % (info, )
0035             print db.DB_VERSION_STRING
0036             print '-=' * 20
0037         assert info == (db.DB_VERSION_MAJOR, db.DB_VERSION_MINOR,
0038                         db.DB_VERSION_PATCH)
0039 
0040 #----------------------------------------------------------------------
0041 
0042 class BasicTestCase(unittest.TestCase):
0043     dbtype       = db.DB_UNKNOWN  # must be set in derived class
0044     dbopenflags  = 0
0045     dbsetflags   = 0
0046     dbmode       = 0660
0047     dbname       = None
0048     useEnv       = 0
0049     envflags     = 0
0050     envsetflags  = 0
0051 
0052     _numKeys      = 1002    # PRIVATE.  NOTE: must be an even value
0053 
0054     def setUp(self):
0055         if self.useEnv:
0056             homeDir = os.path.join(os.path.dirname(sys.argv[0]), 'db_home')
0057             self.homeDir = homeDir
0058             try:
0059                 shutil.rmtree(homeDir)
0060             except OSError, e:
0061                 # unix returns ENOENT, windows returns ESRCH
0062                 if e.errno not in (errno.ENOENT, errno.ESRCH): raise
0063             os.mkdir(homeDir)
0064             try:
0065                 self.env = db.DBEnv()
0066                 self.env.set_lg_max(1024*1024)
0067                 self.env.set_flags(self.envsetflags, 1)
0068                 self.env.open(homeDir, self.envflags | db.DB_CREATE)
0069                 tempfile.tempdir = homeDir
0070                 self.filename = os.path.split(tempfile.mktemp())[1]
0071                 tempfile.tempdir = None
0072             # Yes, a bare except is intended, since we're re-raising the exc.
0073             except:
0074                 shutil.rmtree(homeDir)
0075                 raise
0076         else:
0077             self.env = None
0078             self.filename = tempfile.mktemp()
0079 
0080         # create and open the DB
0081         self.d = db.DB(self.env)
0082         self.d.set_flags(self.dbsetflags)
0083         if self.dbname:
0084             self.d.open(self.filename, self.dbname, self.dbtype,
0085                         self.dbopenflags|db.DB_CREATE, self.dbmode)
0086         else:
0087             self.d.open(self.filename,   # try out keyword args
0088                         mode = self.dbmode,
0089                         dbtype = self.dbtype,
0090                         flags = self.dbopenflags|db.DB_CREATE)
0091 
0092         self.populateDB()
0093 
0094 
0095     def tearDown(self):
0096         self.d.close()
0097         if self.env is not None:
0098             self.env.close()
0099             shutil.rmtree(self.homeDir)
0100             ## Make a new DBEnv to remove the env files from the home dir.
0101             ## (It can't be done while the env is open, nor after it has been
0102             ## closed, so we make a new one to do it.)
0103             #e = db.DBEnv()
0104             #e.remove(self.homeDir)
0105             #os.remove(os.path.join(self.homeDir, self.filename))
0106         else:
0107             os.remove(self.filename)
0108 
0109 
0110 
0111     def populateDB(self, _txn=None):
0112         d = self.d
0113 
0114         for x in range(self._numKeys/2):
0115             key = '%04d' % (self._numKeys - x)  # insert keys in reverse order
0116             data = self.makeData(key)
0117             d.put(key, data, _txn)
0118 
0119         d.put('empty value', '', _txn)
0120 
0121         for x in range(self._numKeys/2-1):
0122             key = '%04d' % x  # and now some in forward order
0123             data = self.makeData(key)
0124             d.put(key, data, _txn)
0125 
0126         if _txn:
0127             _txn.commit()
0128 
0129         num = len(d)
0130         if verbose:
0131             print "created %d records" % num
0132 
0133 
0134     def makeData(self, key):
0135         return DASH.join([key] * 5)
0136 
0137 
0138 
0139     #----------------------------------------
0140 
0141     def test01_GetsAndPuts(self):
0142         d = self.d
0143 
0144         if verbose:
0145             print '\n', '-=' * 30
0146             print "Running %s.test01_GetsAndPuts..." % self.__class__.__name__
0147 
0148         for key in ['0001', '0100', '0400', '0700', '0999']:
0149             data = d.get(key)
0150             if verbose:
0151                 print data
0152 
0153         assert d.get('0321') == '0321-0321-0321-0321-0321'
0154 
0155         # By default non-existant keys return None...
0156         assert d.get('abcd') == None
0157 
0158         # ...but they raise exceptions in other situations.  Call
0159         # set_get_returns_none() to change it.
0160         try:
0161             d.delete('abcd')
0162         except db.DBNotFoundError, val:
0163             assert val[0] == db.DB_NOTFOUND
0164             if verbose: print val
0165         else:
0166             self.fail("expected exception")
0167 
0168 
0169         d.put('abcd', 'a new record')
0170         assert d.get('abcd') == 'a new record'
0171 
0172         d.put('abcd', 'same key')
0173         if self.dbsetflags & db.DB_DUP:
0174             assert d.get('abcd') == 'a new record'
0175         else:
0176             assert d.get('abcd') == 'same key'
0177 
0178 
0179         try:
0180             d.put('abcd', 'this should fail', flags=db.DB_NOOVERWRITE)
0181         except db.DBKeyExistError, val:
0182             assert val[0] == db.DB_KEYEXIST
0183             if verbose: print val
0184         else:
0185             self.fail("expected exception")
0186 
0187         if self.dbsetflags & db.DB_DUP:
0188             assert d.get('abcd') == 'a new record'
0189         else:
0190             assert d.get('abcd') == 'same key'
0191 
0192 
0193         d.sync()
0194         d.close()
0195         del d
0196 
0197         self.d = db.DB(self.env)
0198         if self.dbname:
0199             self.d.open(self.filename, self.dbname)
0200         else:
0201             self.d.open(self.filename)
0202         d = self.d
0203 
0204         assert d.get('0321') == '0321-0321-0321-0321-0321'
0205         if self.dbsetflags & db.DB_DUP:
0206             assert d.get('abcd') == 'a new record'
0207         else:
0208             assert d.get('abcd') == 'same key'
0209 
0210         rec = d.get_both('0555', '0555-0555-0555-0555-0555')
0211         if verbose:
0212             print rec
0213 
0214         assert d.get_both('0555', 'bad data') == None
0215 
0216         # test default value
0217         data = d.get('bad key', 'bad data')
0218         assert data == 'bad data'
0219 
0220         # any object can pass through
0221         data = d.get('bad key', self)
0222         assert data == self
0223 
0224         s = d.stat()
0225         assert type(s) == type({})
0226         if verbose:
0227             print 'd.stat() returned this dictionary:'
0228             pprint(s)
0229 
0230 
0231     #----------------------------------------
0232 
0233     def test02_DictionaryMethods(self):
0234         d = self.d
0235 
0236         if verbose:
0237             print '\n', '-=' * 30
0238             print "Running %s.test02_DictionaryMethods..." % \
0239                   self.__class__.__name__
0240 
0241         for key in ['0002', '0101', '0401', '0701', '0998']:
0242             data = d[key]
0243             assert data == self.makeData(key)
0244             if verbose:
0245                 print data
0246 
0247         assert len(d) == self._numKeys
0248         keys = d.keys()
0249         assert len(keys) == self._numKeys
0250         assert type(keys) == type([])
0251 
0252         d['new record'] = 'a new record'
0253         assert len(d) == self._numKeys+1
0254         keys = d.keys()
0255         assert len(keys) == self._numKeys+1
0256 
0257         d['new record'] = 'a replacement record'
0258         assert len(d) == self._numKeys+1
0259         keys = d.keys()
0260         assert len(keys) == self._numKeys+1
0261 
0262         if verbose:
0263             print "the first 10 keys are:"
0264             pprint(keys[:10])
0265 
0266         assert d['new record'] == 'a replacement record'
0267 
0268         assert d.has_key('0001') == 1
0269         assert d.has_key('spam') == 0
0270 
0271         items = d.items()
0272         assert len(items) == self._numKeys+1
0273         assert type(items) == type([])
0274         assert type(items[0]) == type(())
0275         assert len(items[0]) == 2
0276 
0277         if verbose:
0278             print "the first 10 items are:"
0279             pprint(items[:10])
0280 
0281         values = d.values()
0282         assert len(values) == self._numKeys+1
0283         assert type(values) == type([])
0284 
0285         if verbose:
0286             print "the first 10 values are:"
0287             pprint(values[:10])
0288 
0289 
0290 
0291     #----------------------------------------
0292 
0293     def test03_SimpleCursorStuff(self, get_raises_error=0, set_raises_error=0):
0294         if verbose:
0295             print '\n', '-=' * 30
0296             print "Running %s.test03_SimpleCursorStuff (get_error %s, set_error %s)..." % \
0297                   (self.__class__.__name__, get_raises_error, set_raises_error)
0298 
0299         if self.env and self.dbopenflags & db.DB_AUTO_COMMIT:
0300             txn = self.env.txn_begin()
0301         else:
0302             txn = None
0303         c = self.d.cursor(txn=txn)
0304 
0305         rec = c.first()
0306         count = 0
0307         while rec is not None:
0308             count = count + 1
0309             if verbose and count % 100 == 0:
0310                 print rec
0311             try:
0312                 rec = c.next()
0313             except db.DBNotFoundError, val:
0314                 if get_raises_error:
0315                     assert val[0] == db.DB_NOTFOUND
0316                     if verbose: print val
0317                     rec = None
0318                 else:
0319                     self.fail("unexpected DBNotFoundError")
0320             assert c.get_current_size() == len(c.current()[1]), "%s != len(%r)" % (c.get_current_size(), c.current()[1])
0321 
0322         assert count == self._numKeys
0323 
0324 
0325         rec = c.last()
0326         count = 0
0327         while rec is not None:
0328             count = count + 1
0329             if verbose and count % 100 == 0:
0330                 print rec
0331             try:
0332                 rec = c.prev()
0333             except db.DBNotFoundError, val:
0334                 if get_raises_error:
0335                     assert val[0] == db.DB_NOTFOUND
0336                     if verbose: print val
0337                     rec = None
0338                 else:
0339                     self.fail("unexpected DBNotFoundError")
0340 
0341         assert count == self._numKeys
0342 
0343         rec = c.set('0505')
0344         rec2 = c.current()
0345         assert rec == rec2
0346         assert rec[0] == '0505'
0347         assert rec[1] == self.makeData('0505')
0348         assert c.get_current_size() == len(rec[1])
0349 
0350         # make sure we get empty values properly
0351         rec = c.set('empty value')
0352         assert rec[1] == ''
0353         assert c.get_current_size() == 0
0354 
0355         try:
0356             n = c.set('bad key')
0357         except db.DBNotFoundError, val:
0358             assert val[0] == db.DB_NOTFOUND
0359             if verbose: print val
0360         else:
0361             if set_raises_error:
0362                 self.fail("expected exception")
0363             if n != None:
0364                 self.fail("expected None: %r" % (n,))
0365 
0366         rec = c.get_both('0404', self.makeData('0404'))
0367         assert rec == ('0404', self.makeData('0404'))
0368 
0369         try:
0370             n = c.get_both('0404', 'bad data')
0371         except db.DBNotFoundError, val:
0372             assert val[0] == db.DB_NOTFOUND
0373             if verbose: print val
0374         else:
0375             if get_raises_error:
0376                 self.fail("expected exception")
0377             if n != None:
0378                 self.fail("expected None: %r" % (n,))
0379 
0380         if self.d.get_type() == db.DB_BTREE:
0381             rec = c.set_range('011')
0382             if verbose:
0383                 print "searched for '011', found: ", rec
0384 
0385             rec = c.set_range('011',dlen=0,doff=0)
0386             if verbose:
0387                 print "searched (partial) for '011', found: ", rec
0388             if rec[1] != '': self.fail('expected empty data portion')
0389 
0390             ev = c.set_range('empty value')
0391             if verbose:
0392                 print "search for 'empty value' returned", ev
0393             if ev[1] != '': self.fail('empty value lookup failed')
0394 
0395         c.set('0499')
0396         c.delete()
0397         try:
0398             rec = c.current()
0399         except db.DBKeyEmptyError, val:
0400             assert val[0] == db.DB_KEYEMPTY
0401             if verbose: print val
0402         else:
0403             self.fail('exception expected')
0404 
0405         c.next()
0406         c2 = c.dup(db.DB_POSITION)
0407         assert c.current() == c2.current()
0408 
0409         c2.put('', 'a new value', db.DB_CURRENT)
0410         assert c.current() == c2.current()
0411         assert c.current()[1] == 'a new value'
0412 
0413         c2.put('', 'er', db.DB_CURRENT, dlen=0, doff=5)
0414         assert c2.current()[1] == 'a newer value'
0415 
0416         c.close()
0417         c2.close()
0418         if txn:
0419             txn.commit()
0420 
0421         # time to abuse the closed cursors and hope we don't crash
0422         methods_to_test = {
0423             'current': (),
0424             'delete': (),
0425             'dup': (db.DB_POSITION,),
0426             'first': (),
0427             'get': (0,),
0428             'next': (),
0429             'prev': (),
0430             'last': (),
0431             'put':('', 'spam', db.DB_CURRENT),
0432             'set': ("0505",),
0433         }
0434         for method, args in methods_to_test.items():
0435             try:
0436                 if verbose:
0437                     print "attempting to use a closed cursor's %s method" % \
0438                           method
0439                 # a bug may cause a NULL pointer dereference...
0440                 apply(getattr(c, method), args)
0441             except db.DBError, val:
0442                 assert val[0] == 0
0443                 if verbose: print val
0444             else:
0445                 self.fail("no exception raised when using a buggy cursor's"
0446                           "%s method" % method)
0447 
0448         #
0449         # free cursor referencing a closed database, it should not barf:
0450         #
0451         oldcursor = self.d.cursor(txn=txn)
0452         self.d.close()
0453 
0454         # this would originally cause a segfault when the cursor for a
0455         # closed database was cleaned up.  it should not anymore.
0456         # SF pybsddb bug id 667343
0457         del oldcursor
0458 
0459     def test03b_SimpleCursorWithoutGetReturnsNone0(self):
0460         # same test but raise exceptions instead of returning None
0461         if verbose:
0462             print '\n', '-=' * 30
0463             print "Running %s.test03b_SimpleCursorStuffWithoutGetReturnsNone..." % \
0464                   self.__class__.__name__
0465 
0466         old = self.d.set_get_returns_none(0)
0467         assert old == 2
0468         self.test03_SimpleCursorStuff(get_raises_error=1, set_raises_error=1)
0469 
0470     def test03b_SimpleCursorWithGetReturnsNone1(self):
0471         # same test but raise exceptions instead of returning None
0472         if verbose:
0473             print '\n', '-=' * 30
0474             print "Running %s.test03b_SimpleCursorStuffWithoutGetReturnsNone..." % \
0475                   self.__class__.__name__
0476 
0477         old = self.d.set_get_returns_none(1)
0478         self.test03_SimpleCursorStuff(get_raises_error=0, set_raises_error=1)
0479 
0480 
0481     def test03c_SimpleCursorGetReturnsNone2(self):
0482         # same test but raise exceptions instead of returning None
0483         if verbose:
0484             print '\n', '-=' * 30
0485             print "Running %s.test03c_SimpleCursorStuffWithoutSetReturnsNone..." % \
0486                   self.__class__.__name__
0487 
0488         old = self.d.set_get_returns_none(1)
0489         assert old == 2
0490         old = self.d.set_get_returns_none(2)
0491         assert old == 1
0492         self.test03_SimpleCursorStuff(get_raises_error=0, set_raises_error=0)
0493 
0494     #----------------------------------------
0495 
0496     def test04_PartialGetAndPut(self):
0497         d = self.d
0498         if verbose:
0499             print '\n', '-=' * 30
0500             print "Running %s.test04_PartialGetAndPut..." % \
0501                   self.__class__.__name__
0502 
0503         key = "partialTest"
0504         data = "1" * 1000 + "2" * 1000
0505         d.put(key, data)
0506         assert d.get(key) == data
0507         assert d.get(key, dlen=20, doff=990) == ("1" * 10) + ("2" * 10)
0508 
0509         d.put("partialtest2", ("1" * 30000) + "robin" )
0510         assert d.get("partialtest2", dlen=5, doff=30000) == "robin"
0511 
0512         # There seems to be a bug in DB here...  Commented out the test for
0513         # now.
0514         ##assert d.get("partialtest2", dlen=5, doff=30010) == ""
0515 
0516         if self.dbsetflags != db.DB_DUP:
0517             # Partial put with duplicate records requires a cursor
0518             d.put(key, "0000", dlen=2000, doff=0)
0519             assert d.get(key) == "0000"
0520 
0521             d.put(key, "1111", dlen=1, doff=2)
0522             assert d.get(key) == "0011110"
0523 
0524     #----------------------------------------
0525 
0526     def test05_GetSize(self):
0527         d = self.d
0528         if verbose:
0529             print '\n', '-=' * 30
0530             print "Running %s.test05_GetSize..." % self.__class__.__name__
0531 
0532         for i in range(1, 50000, 500):
0533             key = "size%s" % i
0534             #print "before ", i,
0535             d.put(key, "1" * i)
0536             #print "after",
0537             assert d.get_size(key) == i
0538             #print "done"
0539 
0540     #----------------------------------------
0541 
0542     def test06_Truncate(self):
0543         if db.version() < (3,3):
0544             # truncate is a feature of BerkeleyDB 3.3 and above
0545             return
0546 
0547         d = self.d
0548         if verbose:
0549             print '\n', '-=' * 30
0550             print "Running %s.test99_Truncate..." % self.__class__.__name__
0551 
0552         d.put("abcde", "ABCDE");
0553         num = d.truncate()
0554         assert num >= 1, "truncate returned <= 0 on non-empty database"
0555         num = d.truncate()
0556         assert num == 0, "truncate on empty DB returned nonzero (%r)" % (num,)
0557 
0558 #----------------------------------------------------------------------
0559 
0560 
0561 class BasicBTreeTestCase(BasicTestCase):
0562     dbtype = db.DB_BTREE
0563 
0564 
0565 class BasicHashTestCase(BasicTestCase):
0566     dbtype = db.DB_HASH
0567 
0568 
0569 class BasicBTreeWithThreadFlagTestCase(BasicTestCase):
0570     dbtype = db.DB_BTREE
0571     dbopenflags = db.DB_THREAD
0572 
0573 
0574 class BasicHashWithThreadFlagTestCase(BasicTestCase):
0575     dbtype = db.DB_HASH
0576     dbopenflags = db.DB_THREAD
0577 
0578 
0579 class BasicBTreeWithEnvTestCase(BasicTestCase):
0580     dbtype = db.DB_BTREE
0581     dbopenflags = db.DB_THREAD
0582     useEnv = 1
0583     envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
0584 
0585 
0586 class BasicHashWithEnvTestCase(BasicTestCase):
0587     dbtype = db.DB_HASH
0588     dbopenflags = db.DB_THREAD
0589     useEnv = 1
0590     envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
0591 
0592 
0593 #----------------------------------------------------------------------
0594 
0595 class BasicTransactionTestCase(BasicTestCase):
0596     dbopenflags = db.DB_THREAD | db.DB_AUTO_COMMIT
0597     useEnv = 1
0598     envflags = (db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK |
0599                 db.DB_INIT_TXN)
0600     envsetflags = db.DB_AUTO_COMMIT
0601 
0602 
0603     def tearDown(self):
0604         self.txn.commit()
0605         BasicTestCase.tearDown(self)
0606 
0607 
0608     def populateDB(self):
0609         txn = self.env.txn_begin()
0610         BasicTestCase.populateDB(self, _txn=txn)
0611 
0612         self.txn = self.env.txn_begin()
0613 
0614 
0615 
0616     def test06_Transactions(self):
0617         d = self.d
0618         if verbose:
0619             print '\n', '-=' * 30
0620             print "Running %s.test06_Transactions..." % self.__class__.__name__
0621 
0622         assert d.get('new rec', txn=self.txn) == None
0623         d.put('new rec', 'this is a new record', self.txn)
0624         assert d.get('new rec', txn=self.txn) == 'this is a new record'
0625         self.txn.abort()
0626         assert d.get('new rec') == None
0627 
0628         self.txn = self.env.txn_begin()
0629 
0630         assert d.get('new rec', txn=self.txn) == None
0631         d.put('new rec', 'this is a new record', self.txn)
0632         assert d.get('new rec', txn=self.txn) == 'this is a new record'
0633         self.txn.commit()
0634         assert d.get('new rec') == 'this is a new record'
0635 
0636         self.txn = self.env.txn_begin()
0637         c = d.cursor(self.txn)
0638         rec = c.first()
0639         count = 0
0640         while rec is not None:
0641             count = count + 1
0642             if verbose and count % 100 == 0:
0643                 print rec
0644             rec = c.next()
0645         assert count == self._numKeys+1
0646 
0647         c.close()                # Cursors *MUST* be closed before commit!
0648         self.txn.commit()
0649 
0650         # flush pending updates
0651         try:
0652             self.env.txn_checkpoint (0, 0, 0)
0653         except db.DBIncompleteError:
0654             pass
0655 
0656         # must have at least one log file present:
0657         logs = self.env.log_archive(db.DB_ARCH_ABS | db.DB_ARCH_LOG)
0658         assert logs != None
0659         for log in logs:
0660             if verbose:
0661                 print 'log file: ' + log
0662 
0663         self.txn = self.env.txn_begin()
0664 
0665     #----------------------------------------
0666 
0667     def test07_TxnTruncate(self):
0668         if db.version() < (3,3):
0669             # truncate is a feature of BerkeleyDB 3.3 and above
0670             return
0671 
0672         d = self.d
0673         if verbose:
0674             print '\n', '-=' * 30
0675             print "Running %s.test07_TxnTruncate..." % self.__class__.__name__
0676 
0677         d.put("abcde", "ABCDE");
0678         txn = self.env.txn_begin()
0679         num = d.truncate(txn)
0680         assert num >= 1, "truncate returned <= 0 on non-empty database"
0681         num = d.truncate(txn)
0682         assert num == 0, "truncate on empty DB returned nonzero (%r)" % (num,)
0683         txn.commit()
0684 
0685     #----------------------------------------
0686 
0687     def test08_TxnLateUse(self):
0688         txn = self.env.txn_begin()
0689         txn.abort()
0690         try:
0691             txn.abort()
0692         except db.DBError, e:
0693             pass
0694         else:
0695             raise RuntimeError, "DBTxn.abort() called after DB_TXN no longer valid w/o an exception"
0696 
0697         txn = self.env.txn_begin()
0698         txn.commit()
0699         try:
0700             txn.commit()
0701         except db.DBError, e:
0702             pass
0703         else:
0704             raise RuntimeError, "DBTxn.commit() called after DB_TXN no longer valid w/o an exception"
0705 
0706 
0707 class BTreeTransactionTestCase(BasicTransactionTestCase):
0708     dbtype = db.DB_BTREE
0709 
0710 class HashTransactionTestCase(BasicTransactionTestCase):
0711     dbtype = db.DB_HASH
0712 
0713 
0714 
0715 #----------------------------------------------------------------------
0716 
0717 class BTreeRecnoTestCase(BasicTestCase):
0718     dbtype     = db.DB_BTREE
0719     dbsetflags = db.DB_RECNUM
0720 
0721     def test07_RecnoInBTree(self):
0722         d = self.d
0723         if verbose:
0724             print '\n', '-=' * 30
0725             print "Running %s.test07_RecnoInBTree..." % self.__class__.__name__
0726 
0727         rec = d.get(200)
0728         assert type(rec) == type(())
0729         assert len(rec) == 2
0730         if verbose:
0731             print "Record #200 is ", rec
0732 
0733         c = d.cursor()
0734         c.set('0200')
0735         num = c.get_recno()
0736         assert type(num) == type(1)
0737         if verbose:
0738             print "recno of d['0200'] is ", num
0739 
0740         rec = c.current()
0741         assert c.set_recno(num) == rec
0742 
0743         c.close()
0744 
0745 
0746 
0747 class BTreeRecnoWithThreadFlagTestCase(BTreeRecnoTestCase):
0748     dbopenflags = db.DB_THREAD
0749 
0750 #----------------------------------------------------------------------
0751 
0752 class BasicDUPTestCase(BasicTestCase):
0753     dbsetflags = db.DB_DUP
0754 
0755     def test08_DuplicateKeys(self):
0756         d = self.d
0757         if verbose:
0758             print '\n', '-=' * 30
0759             print "Running %s.test08_DuplicateKeys..." % \
0760                   self.__class__.__name__
0761 
0762         d.put("dup0", "before")
0763         for x in "The quick brown fox jumped over the lazy dog.".split():
0764             d.put("dup1", x)
0765         d.put("dup2", "after")
0766 
0767         data = d.get("dup1")
0768         assert data == "The"
0769         if verbose:
0770             print data
0771 
0772         c = d.cursor()
0773         rec = c.set("dup1")
0774         assert rec == ('dup1', 'The')
0775 
0776         next = c.next()
0777         assert next == ('dup1', 'quick')
0778 
0779         rec = c.set("dup1")
0780         count = c.count()
0781         assert count == 9
0782 
0783         next_dup = c.next_dup()
0784         assert next_dup == ('dup1', 'quick')
0785 
0786         rec = c.set('dup1')
0787         while rec is not None:
0788             if verbose:
0789                 print rec
0790             rec = c.next_dup()
0791 
0792         c.set('dup1')
0793         rec = c.next_nodup()
0794         assert rec[0] != 'dup1'
0795         if verbose:
0796             print rec
0797 
0798         c.close()
0799 
0800 
0801 
0802 class BTreeDUPTestCase(BasicDUPTestCase):
0803     dbtype = db.DB_BTREE
0804 
0805 class HashDUPTestCase(BasicDUPTestCase):
0806     dbtype = db.DB_HASH
0807 
0808 class BTreeDUPWithThreadTestCase(BasicDUPTestCase):
0809     dbtype = db.DB_BTREE
0810     dbopenflags = db.DB_THREAD
0811 
0812 class HashDUPWithThreadTestCase(BasicDUPTestCase):
0813     dbtype = db.DB_HASH
0814     dbopenflags = db.DB_THREAD
0815 
0816 
0817 #----------------------------------------------------------------------
0818 
0819 class BasicMultiDBTestCase(BasicTestCase):
0820     dbname = 'first'
0821 
0822     def otherType(self):
0823         if self.dbtype == db.DB_BTREE:
0824             return db.DB_HASH
0825         else:
0826             return db.DB_BTREE
0827 
0828     def test09_MultiDB(self):
0829         d1 = self.d
0830         if verbose:
0831             print '\n', '-=' * 30
0832             print "Running %s.test09_MultiDB..." % self.__class__.__name__
0833 
0834         d2 = db.DB(self.env)
0835         d2.open(self.filename, "second", self.dbtype,
0836                 self.dbopenflags|db.DB_CREATE)
0837         d3 = db.DB(self.env)
0838         d3.open(self.filename, "third", self.otherType(),
0839                 self.dbopenflags|db.DB_CREATE)
0840 
0841         for x in "The quick brown fox jumped over the lazy dog".split():
0842             d2.put(x, self.makeData(x))
0843 
0844         for x in string.letters:
0845             d3.put(x, x*70)
0846 
0847         d1.sync()
0848         d2.sync()
0849         d3.sync()
0850         d1.close()
0851         d2.close()
0852         d3.close()
0853 
0854         self.d = d1 = d2 = d3 = None
0855 
0856         self.d = d1 = db.DB(self.env)
0857         d1.open(self.filename, self.dbname, flags = self.dbopenflags)
0858         d2 = db.DB(self.env)
0859         d2.open(self.filename, "second",  flags = self.dbopenflags)
0860         d3 = db.DB(self.env)
0861         d3.open(self.filename, "third", flags = self.dbopenflags)
0862 
0863         c1 = d1.cursor()
0864         c2 = d2.cursor()
0865         c3 = d3.cursor()
0866 
0867         count = 0
0868         rec = c1.first()
0869         while rec is not None:
0870             count = count + 1
0871             if verbose and (count % 50) == 0:
0872                 print rec
0873             rec = c1.next()
0874         assert count == self._numKeys
0875 
0876         count = 0
0877         rec = c2.first()
0878         while rec is not None:
0879             count = count + 1
0880             if verbose:
0881                 print rec
0882             rec = c2.next()
0883         assert count == 9
0884 
0885         count = 0
0886         rec = c3.first()
0887         while rec is not None:
0888             count = count + 1
0889             if verbose:
0890                 print rec
0891             rec = c3.next()
0892         assert count == 52
0893 
0894 
0895         c1.close()
0896         c2.close()
0897         c3.close()
0898 
0899         d2.close()
0900         d3.close()
0901 
0902 
0903 
0904 # Strange things happen if you try to use Multiple DBs per file without a
0905 # DBEnv with MPOOL and LOCKing...
0906 
0907 class BTreeMultiDBTestCase(BasicMultiDBTestCase):
0908     dbtype = db.DB_BTREE
0909     dbopenflags = db.DB_THREAD
0910     useEnv = 1
0911     envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
0912 
0913 class HashMultiDBTestCase(BasicMultiDBTestCase):
0914     dbtype = db.DB_HASH
0915     dbopenflags = db.DB_THREAD
0916     useEnv = 1
0917     envflags = db.DB_THREAD | db.DB_INIT_MPOOL | db.DB_INIT_LOCK
0918 
0919 
0920 #----------------------------------------------------------------------
0921 #----------------------------------------------------------------------
0922 
0923 def test_suite():
0924     suite = unittest.TestSuite()
0925 
0926     suite.addTest(unittest.makeSuite(VersionTestCase))
0927     suite.addTest(unittest.makeSuite(BasicBTreeTestCase))
0928     suite.addTest(unittest.makeSuite(BasicHashTestCase))
0929     suite.addTest(unittest.makeSuite(BasicBTreeWithThreadFlagTestCase))
0930     suite.addTest(unittest.makeSuite(BasicHashWithThreadFlagTestCase))
0931     suite.addTest(unittest.makeSuite(BasicBTreeWithEnvTestCase))
0932     suite.addTest(unittest.makeSuite(BasicHashWithEnvTestCase))
0933     suite.addTest(unittest.makeSuite(BTreeTransactionTestCase))
0934     suite.addTest(unittest.makeSuite(HashTransactionTestCase))
0935     suite.addTest(unittest.makeSuite(BTreeRecnoTestCase))
0936     suite.addTest(unittest.makeSuite(BTreeRecnoWithThreadFlagTestCase))
0937     suite.addTest(unittest.makeSuite(BTreeDUPTestCase))
0938     suite.addTest(unittest.makeSuite(HashDUPTestCase))
0939     suite.addTest(unittest.makeSuite(BTreeDUPWithThreadTestCase))
0940     suite.addTest(unittest.makeSuite(HashDUPWithThreadTestCase))
0941     suite.addTest(unittest.makeSuite(BTreeMultiDBTestCase))
0942     suite.addTest(unittest.makeSuite(HashMultiDBTestCase))
0943 
0944     return suite
0945 
0946 
0947 if __name__ == '__main__':
0948     unittest.main(defaultTest='test_suite')
0949 

Generated by PyXR 0.9.4
SourceForge.net Logo