Home | History | Annotate | Download | only in test
      1 import unittest
      2 import os, glob
      3 
      4 from test_all import db, test_support, get_new_environment_path, \
      5         get_new_database_path
      6 
      7 #----------------------------------------------------------------------
      8 
      9 class DBEnv(unittest.TestCase):
     10     def setUp(self):
     11         self.homeDir = get_new_environment_path()
     12         self.env = db.DBEnv()
     13 
     14     def tearDown(self):
     15         self.env.close()
     16         del self.env
     17         test_support.rmtree(self.homeDir)
     18 
     19 class DBEnv_general(DBEnv) :
     20     def test_get_open_flags(self) :
     21         flags = db.DB_CREATE | db.DB_INIT_MPOOL
     22         self.env.open(self.homeDir, flags)
     23         self.assertEqual(flags, self.env.get_open_flags())
     24 
     25     def test_get_open_flags2(self) :
     26         flags = db.DB_CREATE | db.DB_INIT_MPOOL | \
     27                 db.DB_INIT_LOCK | db.DB_THREAD
     28         self.env.open(self.homeDir, flags)
     29         self.assertEqual(flags, self.env.get_open_flags())
     30 
     31     if db.version() >= (4, 7) :
     32         def test_lk_partitions(self) :
     33             for i in [10, 20, 40] :
     34                 self.env.set_lk_partitions(i)
     35                 self.assertEqual(i, self.env.get_lk_partitions())
     36 
     37         def test_getset_intermediate_dir_mode(self) :
     38             self.assertEqual(None, self.env.get_intermediate_dir_mode())
     39             for mode in ["rwx------", "rw-rw-rw-", "rw-r--r--"] :
     40                 self.env.set_intermediate_dir_mode(mode)
     41                 self.assertEqual(mode, self.env.get_intermediate_dir_mode())
     42             self.assertRaises(db.DBInvalidArgError,
     43                     self.env.set_intermediate_dir_mode, "abcde")
     44 
     45     if db.version() >= (4, 6) :
     46         def test_thread(self) :
     47             for i in [16, 100, 1000] :
     48                 self.env.set_thread_count(i)
     49                 self.assertEqual(i, self.env.get_thread_count())
     50 
     51         def test_cache_max(self) :
     52             for size in [64, 128] :
     53                 size = size*1024*1024  # Megabytes
     54                 self.env.set_cache_max(0, size)
     55                 size2 = self.env.get_cache_max()
     56                 self.assertEqual(0, size2[0])
     57                 self.assertTrue(size <= size2[1])
     58                 self.assertTrue(2*size > size2[1])
     59 
     60     if db.version() >= (4, 4) :
     61         def test_mutex_stat(self) :
     62             self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL |
     63                     db.DB_INIT_LOCK)
     64             stat = self.env.mutex_stat()
     65             self.assertTrue("mutex_inuse_max" in stat)
     66 
     67         def test_lg_filemode(self) :
     68             for i in [0600, 0660, 0666] :
     69                 self.env.set_lg_filemode(i)
     70                 self.assertEqual(i, self.env.get_lg_filemode())
     71 
     72     def test_mp_max_openfd(self) :
     73         for i in [17, 31, 42] :
     74             self.env.set_mp_max_openfd(i)
     75             self.assertEqual(i, self.env.get_mp_max_openfd())
     76 
     77     def test_mp_max_write(self) :
     78         for i in [100, 200, 300] :
     79             for j in [1, 2, 3] :
     80                 j *= 1000000
     81                 self.env.set_mp_max_write(i, j)
     82                 v=self.env.get_mp_max_write()
     83                 self.assertEqual((i, j), v)
     84 
     85         def test_invalid_txn(self) :
     86             # This environment doesn't support transactions
     87             self.assertRaises(db.DBInvalidArgError, self.env.txn_begin)
     88 
     89         def test_mp_mmapsize(self) :
     90             for i in [16, 32, 64] :
     91                 i *= 1024*1024
     92                 self.env.set_mp_mmapsize(i)
     93                 self.assertEqual(i, self.env.get_mp_mmapsize())
     94 
     95         def test_tmp_dir(self) :
     96             for i in ["a", "bb", "ccc"] :
     97                 self.env.set_tmp_dir(i)
     98                 self.assertEqual(i, self.env.get_tmp_dir())
     99 
    100         def test_flags(self) :
    101             self.env.set_flags(db.DB_AUTO_COMMIT, 1)
    102             self.assertEqual(db.DB_AUTO_COMMIT, self.env.get_flags())
    103             self.env.set_flags(db.DB_TXN_NOSYNC, 1)
    104             self.assertEqual(db.DB_AUTO_COMMIT | db.DB_TXN_NOSYNC,
    105                     self.env.get_flags())
    106             self.env.set_flags(db.DB_AUTO_COMMIT, 0)
    107             self.assertEqual(db.DB_TXN_NOSYNC, self.env.get_flags())
    108             self.env.set_flags(db.DB_TXN_NOSYNC, 0)
    109             self.assertEqual(0, self.env.get_flags())
    110 
    111         def test_lk_max_objects(self) :
    112             for i in [1000, 2000, 3000] :
    113                 self.env.set_lk_max_objects(i)
    114                 self.assertEqual(i, self.env.get_lk_max_objects())
    115 
    116         def test_lk_max_locks(self) :
    117             for i in [1000, 2000, 3000] :
    118                 self.env.set_lk_max_locks(i)
    119                 self.assertEqual(i, self.env.get_lk_max_locks())
    120 
    121         def test_lk_max_lockers(self) :
    122             for i in [1000, 2000, 3000] :
    123                 self.env.set_lk_max_lockers(i)
    124                 self.assertEqual(i, self.env.get_lk_max_lockers())
    125 
    126         def test_lg_regionmax(self) :
    127             for i in [128, 256, 1000] :
    128                 i = i*1024*1024
    129                 self.env.set_lg_regionmax(i)
    130                 j = self.env.get_lg_regionmax()
    131                 self.assertTrue(i <= j)
    132                 self.assertTrue(2*i > j)
    133 
    134         def test_lk_detect(self) :
    135             flags= [db.DB_LOCK_DEFAULT, db.DB_LOCK_EXPIRE, db.DB_LOCK_MAXLOCKS,
    136                     db.DB_LOCK_MINLOCKS, db.DB_LOCK_MINWRITE,
    137                     db.DB_LOCK_OLDEST, db.DB_LOCK_RANDOM, db.DB_LOCK_YOUNGEST]
    138 
    139             flags.append(db.DB_LOCK_MAXWRITE)
    140 
    141             for i in flags :
    142                 self.env.set_lk_detect(i)
    143                 self.assertEqual(i, self.env.get_lk_detect())
    144 
    145         def test_lg_dir(self) :
    146             for i in ["a", "bb", "ccc", "dddd"] :
    147                 self.env.set_lg_dir(i)
    148                 self.assertEqual(i, self.env.get_lg_dir())
    149 
    150         def test_lg_bsize(self) :
    151             log_size = 70*1024
    152             self.env.set_lg_bsize(log_size)
    153             self.assertTrue(self.env.get_lg_bsize() >= log_size)
    154             self.assertTrue(self.env.get_lg_bsize() < 4*log_size)
    155             self.env.set_lg_bsize(4*log_size)
    156             self.assertTrue(self.env.get_lg_bsize() >= 4*log_size)
    157 
    158         def test_setget_data_dirs(self) :
    159             dirs = ("a", "b", "c", "d")
    160             for i in dirs :
    161                 self.env.set_data_dir(i)
    162             self.assertEqual(dirs, self.env.get_data_dirs())
    163 
    164         def test_setget_cachesize(self) :
    165             cachesize = (0, 512*1024*1024, 3)
    166             self.env.set_cachesize(*cachesize)
    167             self.assertEqual(cachesize, self.env.get_cachesize())
    168 
    169             cachesize = (0, 1*1024*1024, 5)
    170             self.env.set_cachesize(*cachesize)
    171             cachesize2 = self.env.get_cachesize()
    172             self.assertEqual(cachesize[0], cachesize2[0])
    173             self.assertEqual(cachesize[2], cachesize2[2])
    174             # Berkeley DB expands the cache 25% accounting overhead,
    175             # if the cache is small.
    176             self.assertEqual(125, int(100.0*cachesize2[1]/cachesize[1]))
    177 
    178             # You can not change configuration after opening
    179             # the environment.
    180             self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
    181             cachesize = (0, 2*1024*1024, 1)
    182             self.assertRaises(db.DBInvalidArgError,
    183                               self.env.set_cachesize, *cachesize)
    184             cachesize3 = self.env.get_cachesize()
    185             self.assertEqual(cachesize2[0], cachesize3[0])
    186             self.assertEqual(cachesize2[2], cachesize3[2])
    187             # In Berkeley DB 5.1, the cachesize can change when opening the Env
    188             self.assertTrue(cachesize2[1] <= cachesize3[1])
    189 
    190         def test_set_cachesize_dbenv_db(self) :
    191             # You can not configure the cachesize using
    192             # the database handle, if you are using an environment.
    193             d = db.DB(self.env)
    194             self.assertRaises(db.DBInvalidArgError,
    195                 d.set_cachesize, 0, 1024*1024, 1)
    196 
    197         def test_setget_shm_key(self) :
    198             shm_key=137
    199             self.env.set_shm_key(shm_key)
    200             self.assertEqual(shm_key, self.env.get_shm_key())
    201             self.env.set_shm_key(shm_key+1)
    202             self.assertEqual(shm_key+1, self.env.get_shm_key())
    203 
    204             # You can not change configuration after opening
    205             # the environment.
    206             self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL)
    207             # If we try to reconfigure cache after opening the
    208             # environment, core dump.
    209             self.assertRaises(db.DBInvalidArgError,
    210                 self.env.set_shm_key, shm_key)
    211             self.assertEqual(shm_key+1, self.env.get_shm_key())
    212 
    213     if db.version() >= (4, 4) :
    214         def test_mutex_setget_max(self) :
    215             v = self.env.mutex_get_max()
    216             v2 = v*2+1
    217 
    218             self.env.mutex_set_max(v2)
    219             self.assertEqual(v2, self.env.mutex_get_max())
    220 
    221             self.env.mutex_set_max(v)
    222             self.assertEqual(v, self.env.mutex_get_max())
    223 
    224             # You can not change configuration after opening
    225             # the environment.
    226             self.env.open(self.homeDir, db.DB_CREATE)
    227             self.assertRaises(db.DBInvalidArgError,
    228                     self.env.mutex_set_max, v2)
    229 
    230         def test_mutex_setget_increment(self) :
    231             v = self.env.mutex_get_increment()
    232             v2 = 127
    233 
    234             self.env.mutex_set_increment(v2)
    235             self.assertEqual(v2, self.env.mutex_get_increment())
    236 
    237             self.env.mutex_set_increment(v)
    238             self.assertEqual(v, self.env.mutex_get_increment())
    239 
    240             # You can not change configuration after opening
    241             # the environment.
    242             self.env.open(self.homeDir, db.DB_CREATE)
    243             self.assertRaises(db.DBInvalidArgError,
    244                     self.env.mutex_set_increment, v2)
    245 
    246         def test_mutex_setget_tas_spins(self) :
    247             self.env.mutex_set_tas_spins(0)  # Default = BDB decides
    248             v = self.env.mutex_get_tas_spins()
    249             v2 = v*2+1
    250 
    251             self.env.mutex_set_tas_spins(v2)
    252             self.assertEqual(v2, self.env.mutex_get_tas_spins())
    253 
    254             self.env.mutex_set_tas_spins(v)
    255             self.assertEqual(v, self.env.mutex_get_tas_spins())
    256 
    257             # In this case, you can change configuration
    258             # after opening the environment.
    259             self.env.open(self.homeDir, db.DB_CREATE)
    260             self.env.mutex_set_tas_spins(v2)
    261 
    262         def test_mutex_setget_align(self) :
    263             v = self.env.mutex_get_align()
    264             v2 = 64
    265             if v == 64 :
    266                 v2 = 128
    267 
    268             self.env.mutex_set_align(v2)
    269             self.assertEqual(v2, self.env.mutex_get_align())
    270 
    271             # Requires a nonzero power of two
    272             self.assertRaises(db.DBInvalidArgError,
    273                     self.env.mutex_set_align, 0)
    274             self.assertRaises(db.DBInvalidArgError,
    275                     self.env.mutex_set_align, 17)
    276 
    277             self.env.mutex_set_align(2*v2)
    278             self.assertEqual(2*v2, self.env.mutex_get_align())
    279 
    280             # You can not change configuration after opening
    281             # the environment.
    282             self.env.open(self.homeDir, db.DB_CREATE)
    283             self.assertRaises(db.DBInvalidArgError,
    284                     self.env.mutex_set_align, v2)
    285 
    286 
    287 class DBEnv_log(DBEnv) :
    288     def setUp(self):
    289         DBEnv.setUp(self)
    290         self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL | db.DB_INIT_LOG)
    291 
    292     def test_log_file(self) :
    293         log_file = self.env.log_file((1, 1))
    294         self.assertEqual("log.0000000001", log_file[-14:])
    295 
    296     if db.version() >= (4, 4) :
    297         # The version with transactions is checked in other test object
    298         def test_log_printf(self) :
    299             msg = "This is a test..."
    300             self.env.log_printf(msg)
    301             logc = self.env.log_cursor()
    302             self.assertTrue(msg in (logc.last()[1]))
    303 
    304     if db.version() >= (4, 7) :
    305         def test_log_config(self) :
    306             self.env.log_set_config(db.DB_LOG_DSYNC | db.DB_LOG_ZERO, 1)
    307             self.assertTrue(self.env.log_get_config(db.DB_LOG_DSYNC))
    308             self.assertTrue(self.env.log_get_config(db.DB_LOG_ZERO))
    309             self.env.log_set_config(db.DB_LOG_ZERO, 0)
    310             self.assertTrue(self.env.log_get_config(db.DB_LOG_DSYNC))
    311             self.assertFalse(self.env.log_get_config(db.DB_LOG_ZERO))
    312 
    313 
    314 class DBEnv_log_txn(DBEnv) :
    315     def setUp(self):
    316         DBEnv.setUp(self)
    317         self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL |
    318                 db.DB_INIT_LOG | db.DB_INIT_TXN)
    319 
    320     if (db.version() >= (4, 5)) and (db.version() < (5, 2)) :
    321         def test_tx_max(self) :
    322             txns=[]
    323             def tx() :
    324                 for i in xrange(self.env.get_tx_max()) :
    325                     txns.append(self.env.txn_begin())
    326 
    327             tx()
    328             self.assertRaises(MemoryError, tx)
    329 
    330             # Abort the transactions before garbage collection,
    331             # to avoid "warnings".
    332             for i in txns :
    333                 i.abort()
    334 
    335     if db.version() >= (4, 4) :
    336         # The version without transactions is checked in other test object
    337         def test_log_printf(self) :
    338             msg = "This is a test..."
    339             txn = self.env.txn_begin()
    340             self.env.log_printf(msg, txn=txn)
    341             txn.commit()
    342             logc = self.env.log_cursor()
    343             logc.last()  # Skip the commit
    344             self.assertTrue(msg in (logc.prev()[1]))
    345 
    346             msg = "This is another test..."
    347             txn = self.env.txn_begin()
    348             self.env.log_printf(msg, txn=txn)
    349             txn.abort()  # Do not store the new message
    350             logc.last()  # Skip the abort
    351             self.assertTrue(msg not in (logc.prev()[1]))
    352 
    353             msg = "This is a third test..."
    354             txn = self.env.txn_begin()
    355             self.env.log_printf(msg, txn=txn)
    356             txn.commit()  # Do not store the new message
    357             logc.last()  # Skip the commit
    358             self.assertTrue(msg in (logc.prev()[1]))
    359 
    360 
    361 class DBEnv_memp(DBEnv):
    362     def setUp(self):
    363         DBEnv.setUp(self)
    364         self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL | db.DB_INIT_LOG)
    365         self.db = db.DB(self.env)
    366         self.db.open("test", db.DB_HASH, db.DB_CREATE, 0660)
    367 
    368     def tearDown(self):
    369         self.db.close()
    370         del self.db
    371         DBEnv.tearDown(self)
    372 
    373     def test_memp_1_trickle(self) :
    374         self.db.put("hi", "bye")
    375         self.assertTrue(self.env.memp_trickle(100) > 0)
    376 
    377 # Preserve the order, do "memp_trickle" test first
    378     def test_memp_2_sync(self) :
    379         self.db.put("hi", "bye")
    380         self.env.memp_sync()  # Full flush
    381         # Nothing to do...
    382         self.assertTrue(self.env.memp_trickle(100) == 0)
    383 
    384         self.db.put("hi", "bye2")
    385         self.env.memp_sync((1, 0))  # NOP, probably
    386         # Something to do... or not
    387         self.assertTrue(self.env.memp_trickle(100) >= 0)
    388 
    389         self.db.put("hi", "bye3")
    390         self.env.memp_sync((123, 99))  # Full flush
    391         # Nothing to do...
    392         self.assertTrue(self.env.memp_trickle(100) == 0)
    393 
    394     def test_memp_stat_1(self) :
    395         stats = self.env.memp_stat()  # No param
    396         self.assertTrue(len(stats)==2)
    397         self.assertTrue("cache_miss" in stats[0])
    398         stats = self.env.memp_stat(db.DB_STAT_CLEAR)  # Positional param
    399         self.assertTrue("cache_miss" in stats[0])
    400         stats = self.env.memp_stat(flags=0)  # Keyword param
    401         self.assertTrue("cache_miss" in stats[0])
    402 
    403     def test_memp_stat_2(self) :
    404         stats=self.env.memp_stat()[1]
    405         self.assertTrue(len(stats))==1
    406         self.assertTrue("test" in stats)
    407         self.assertTrue("page_in" in stats["test"])
    408 
    409 class DBEnv_logcursor(DBEnv):
    410     def setUp(self):
    411         DBEnv.setUp(self)
    412         self.env.open(self.homeDir, db.DB_CREATE | db.DB_INIT_MPOOL |
    413                 db.DB_INIT_LOG | db.DB_INIT_TXN)
    414         txn = self.env.txn_begin()
    415         self.db = db.DB(self.env)
    416         self.db.open("test", db.DB_HASH, db.DB_CREATE, 0660, txn=txn)
    417         txn.commit()
    418         for i in ["2", "8", "20"] :
    419             txn = self.env.txn_begin()
    420             self.db.put(key = i, data = i*int(i), txn=txn)
    421             txn.commit()
    422 
    423     def tearDown(self):
    424         self.db.close()
    425         del self.db
    426         DBEnv.tearDown(self)
    427 
    428     def _check_return(self, value) :
    429         self.assertTrue(isinstance(value, tuple))
    430         self.assertEqual(len(value), 2)
    431         self.assertTrue(isinstance(value[0], tuple))
    432         self.assertEqual(len(value[0]), 2)
    433         self.assertTrue(isinstance(value[0][0], int))
    434         self.assertTrue(isinstance(value[0][1], int))
    435         self.assertTrue(isinstance(value[1], str))
    436 
    437     # Preserve test order
    438     def test_1_first(self) :
    439         logc = self.env.log_cursor()
    440         v = logc.first()
    441         self._check_return(v)
    442         self.assertTrue((1, 1) < v[0])
    443         self.assertTrue(len(v[1])>0)
    444 
    445     def test_2_last(self) :
    446         logc = self.env.log_cursor()
    447         lsn_first = logc.first()[0]
    448         v = logc.last()
    449         self._check_return(v)
    450         self.assertTrue(lsn_first < v[0])
    451 
    452     def test_3_next(self) :
    453         logc = self.env.log_cursor()
    454         lsn_last = logc.last()[0]
    455         self.assertEqual(logc.next(), None)
    456         lsn_first = logc.first()[0]
    457         v = logc.next()
    458         self._check_return(v)
    459         self.assertTrue(lsn_first < v[0])
    460         self.assertTrue(lsn_last > v[0])
    461 
    462         v2 = logc.next()
    463         self.assertTrue(v2[0] > v[0])
    464         self.assertTrue(lsn_last > v2[0])
    465 
    466         v3 = logc.next()
    467         self.assertTrue(v3[0] > v2[0])
    468         self.assertTrue(lsn_last > v3[0])
    469 
    470     def test_4_prev(self) :
    471         logc = self.env.log_cursor()
    472         lsn_first = logc.first()[0]
    473         self.assertEqual(logc.prev(), None)
    474         lsn_last = logc.last()[0]
    475         v = logc.prev()
    476         self._check_return(v)
    477         self.assertTrue(lsn_first < v[0])
    478         self.assertTrue(lsn_last > v[0])
    479 
    480         v2 = logc.prev()
    481         self.assertTrue(v2[0] < v[0])
    482         self.assertTrue(lsn_first < v2[0])
    483 
    484         v3 = logc.prev()
    485         self.assertTrue(v3[0] < v2[0])
    486         self.assertTrue(lsn_first < v3[0])
    487 
    488     def test_5_current(self) :
    489         logc = self.env.log_cursor()
    490         logc.first()
    491         v = logc.next()
    492         self.assertEqual(v, logc.current())
    493 
    494     def test_6_set(self) :
    495         logc = self.env.log_cursor()
    496         logc.first()
    497         v = logc.next()
    498         self.assertNotEqual(v, logc.next())
    499         self.assertNotEqual(v, logc.next())
    500         self.assertEqual(v, logc.set(v[0]))
    501 
    502     def test_explicit_close(self) :
    503         logc = self.env.log_cursor()
    504         logc.close()
    505         self.assertRaises(db.DBCursorClosedError, logc.next)
    506 
    507     def test_implicit_close(self) :
    508         logc =  [self.env.log_cursor() for i in xrange(10)]
    509         self.env.close()  # This close should close too all its tree
    510         for i in logc :
    511             self.assertRaises(db.DBCursorClosedError, i.next)
    512 
    513 def test_suite():
    514     suite = unittest.TestSuite()
    515 
    516     suite.addTest(unittest.makeSuite(DBEnv_general))
    517     suite.addTest(unittest.makeSuite(DBEnv_memp))
    518     suite.addTest(unittest.makeSuite(DBEnv_logcursor))
    519     suite.addTest(unittest.makeSuite(DBEnv_log))
    520     suite.addTest(unittest.makeSuite(DBEnv_log_txn))
    521 
    522     return suite
    523 
    524 if __name__ == '__main__':
    525     unittest.main(defaultTest='test_suite')
    526