4 from test_all
import db
, test_support
, get_new_environment_path
, \
7 #----------------------------------------------------------------------
9 class DBEnv(unittest
.TestCase
):
11 if sys
.version_info
< (2, 4) :
12 def assertTrue(self
, expr
, msg
=None):
13 self
.failUnless(expr
,msg
=msg
)
15 def assertFalse(self
, expr
, msg
=None):
16 self
.failIf(expr
,msg
=msg
)
19 self
.homeDir
= get_new_environment_path()
25 test_support
.rmtree(self
.homeDir
)
27 class DBEnv_general(DBEnv
) :
28 if db
.version() >= (4, 7) :
29 def test_lk_partitions(self
) :
30 for i
in [10, 20, 40] :
31 self
.env
.set_lk_partitions(i
)
32 self
.assertEqual(i
, self
.env
.get_lk_partitions())
34 if db
.version() >= (4, 6) :
35 def test_thread(self
) :
36 for i
in [16, 100, 1000] :
37 self
.env
.set_thread_count(i
)
38 self
.assertEqual(i
, self
.env
.get_thread_count())
40 def test_cache_max(self
) :
41 for size
in [64, 128] :
42 size
= size
*1024*1024 # Megabytes
43 self
.env
.set_cache_max(0, size
)
44 size2
= self
.env
.get_cache_max()
45 self
.assertEqual(0, size2
[0])
46 self
.assertTrue(size
<= size2
[1])
47 self
.assertTrue(2*size
> size2
[1])
49 if db
.version() >= (4, 4) :
50 def test_mutex_stat(self
) :
51 self
.env
.open(self
.homeDir
, db
.DB_CREATE | db
.DB_INIT_MPOOL |
53 stat
= self
.env
.mutex_stat()
54 self
.assertTrue("mutex_inuse_max" in stat
)
56 def test_lg_filemode(self
) :
57 for i
in [0600, 0660, 0666] :
58 self
.env
.set_lg_filemode(i
)
59 self
.assertEqual(i
, self
.env
.get_lg_filemode())
61 if db
.version() >= (4, 3) :
62 def test_mp_max_openfd(self
) :
63 for i
in [17, 31, 42] :
64 self
.env
.set_mp_max_openfd(i
)
65 self
.assertEqual(i
, self
.env
.get_mp_max_openfd())
67 def test_mp_max_write(self
) :
68 for i
in [100, 200, 300] :
71 self
.env
.set_mp_max_write(i
, j
)
72 v
=self
.env
.get_mp_max_write()
73 self
.assertEqual((i
, j
), v
)
75 if db
.version() >= (4, 2) :
76 def test_invalid_txn(self
) :
77 # This environment doesn't support transactions
78 self
.assertRaises(db
.DBInvalidArgError
, self
.env
.txn_begin
)
80 def test_mp_mmapsize(self
) :
81 for i
in [16, 32, 64] :
83 self
.env
.set_mp_mmapsize(i
)
84 self
.assertEqual(i
, self
.env
.get_mp_mmapsize())
86 def test_tmp_dir(self
) :
87 for i
in ["a", "bb", "ccc"] :
88 self
.env
.set_tmp_dir(i
)
89 self
.assertEqual(i
, self
.env
.get_tmp_dir())
91 def test_flags(self
) :
92 self
.env
.set_flags(db
.DB_AUTO_COMMIT
, 1)
93 self
.assertEqual(db
.DB_AUTO_COMMIT
, self
.env
.get_flags())
94 self
.env
.set_flags(db
.DB_TXN_NOSYNC
, 1)
95 self
.assertEqual(db
.DB_AUTO_COMMIT | db
.DB_TXN_NOSYNC
,
97 self
.env
.set_flags(db
.DB_AUTO_COMMIT
, 0)
98 self
.assertEqual(db
.DB_TXN_NOSYNC
, self
.env
.get_flags())
99 self
.env
.set_flags(db
.DB_TXN_NOSYNC
, 0)
100 self
.assertEqual(0, self
.env
.get_flags())
102 def test_lk_max_objects(self
) :
103 for i
in [1000, 2000, 3000] :
104 self
.env
.set_lk_max_objects(i
)
105 self
.assertEqual(i
, self
.env
.get_lk_max_objects())
107 def test_lk_max_locks(self
) :
108 for i
in [1000, 2000, 3000] :
109 self
.env
.set_lk_max_locks(i
)
110 self
.assertEqual(i
, self
.env
.get_lk_max_locks())
112 def test_lk_max_lockers(self
) :
113 for i
in [1000, 2000, 3000] :
114 self
.env
.set_lk_max_lockers(i
)
115 self
.assertEqual(i
, self
.env
.get_lk_max_lockers())
117 def test_lg_regionmax(self
) :
118 for i
in [128, 256, 1024] :
120 self
.env
.set_lg_regionmax(i
)
121 j
= self
.env
.get_lg_regionmax()
122 self
.assertTrue(i
<= j
)
123 self
.assertTrue(2*i
> j
)
125 def test_lk_detect(self
) :
126 flags
= [db
.DB_LOCK_DEFAULT
, db
.DB_LOCK_EXPIRE
, db
.DB_LOCK_MAXLOCKS
,
127 db
.DB_LOCK_MINLOCKS
, db
.DB_LOCK_MINWRITE
,
128 db
.DB_LOCK_OLDEST
, db
.DB_LOCK_RANDOM
, db
.DB_LOCK_YOUNGEST
]
130 if db
.version() >= (4, 3) :
131 flags
.append(db
.DB_LOCK_MAXWRITE
)
134 self
.env
.set_lk_detect(i
)
135 self
.assertEqual(i
, self
.env
.get_lk_detect())
137 def test_lg_dir(self
) :
138 for i
in ["a", "bb", "ccc", "dddd"] :
139 self
.env
.set_lg_dir(i
)
140 self
.assertEqual(i
, self
.env
.get_lg_dir())
142 def test_lg_bsize(self
) :
144 self
.env
.set_lg_bsize(log_size
)
145 self
.assertTrue(self
.env
.get_lg_bsize() >= log_size
)
146 self
.assertTrue(self
.env
.get_lg_bsize() < 4*log_size
)
147 self
.env
.set_lg_bsize(4*log_size
)
148 self
.assertTrue(self
.env
.get_lg_bsize() >= 4*log_size
)
150 def test_setget_data_dirs(self
) :
151 dirs
= ("a", "b", "c", "d")
153 self
.env
.set_data_dir(i
)
154 self
.assertEqual(dirs
, self
.env
.get_data_dirs())
156 def test_setget_cachesize(self
) :
157 cachesize
= (0, 512*1024*1024, 3)
158 self
.env
.set_cachesize(*cachesize
)
159 self
.assertEqual(cachesize
, self
.env
.get_cachesize())
161 cachesize
= (0, 1*1024*1024, 5)
162 self
.env
.set_cachesize(*cachesize
)
163 cachesize2
= self
.env
.get_cachesize()
164 self
.assertEqual(cachesize
[0], cachesize2
[0])
165 self
.assertEqual(cachesize
[2], cachesize2
[2])
166 # Berkeley DB expands the cache 25% accounting overhead,
167 # if the cache is small.
168 self
.assertEqual(125, int(100.0*cachesize2
[1]/cachesize
[1]))
170 # You can not change configuration after opening
172 self
.env
.open(self
.homeDir
, db
.DB_CREATE | db
.DB_INIT_MPOOL
)
173 cachesize
= (0, 2*1024*1024, 1)
174 self
.assertRaises(db
.DBInvalidArgError
,
175 self
.env
.set_cachesize
, *cachesize
)
176 self
.assertEqual(cachesize2
, self
.env
.get_cachesize())
178 def test_set_cachesize_dbenv_db(self
) :
179 # You can not configure the cachesize using
180 # the database handle, if you are using an environment.
182 self
.assertRaises(db
.DBInvalidArgError
,
183 d
.set_cachesize
, 0, 1024*1024, 1)
185 def test_setget_shm_key(self
) :
187 self
.env
.set_shm_key(shm_key
)
188 self
.assertEqual(shm_key
, self
.env
.get_shm_key())
189 self
.env
.set_shm_key(shm_key
+1)
190 self
.assertEqual(shm_key
+1, self
.env
.get_shm_key())
192 # You can not change configuration after opening
194 self
.env
.open(self
.homeDir
, db
.DB_CREATE | db
.DB_INIT_MPOOL
)
195 # If we try to reconfigure cache after opening the
196 # environment, core dump.
197 self
.assertRaises(db
.DBInvalidArgError
,
198 self
.env
.set_shm_key
, shm_key
)
199 self
.assertEqual(shm_key
+1, self
.env
.get_shm_key())
201 if db
.version() >= (4, 4) :
202 def test_mutex_setget_max(self
) :
203 v
= self
.env
.mutex_get_max()
206 self
.env
.mutex_set_max(v2
)
207 self
.assertEqual(v2
, self
.env
.mutex_get_max())
209 self
.env
.mutex_set_max(v
)
210 self
.assertEqual(v
, self
.env
.mutex_get_max())
212 # You can not change configuration after opening
214 self
.env
.open(self
.homeDir
, db
.DB_CREATE
)
215 self
.assertRaises(db
.DBInvalidArgError
,
216 self
.env
.mutex_set_max
, v2
)
218 def test_mutex_setget_increment(self
) :
219 v
= self
.env
.mutex_get_increment()
222 self
.env
.mutex_set_increment(v2
)
223 self
.assertEqual(v2
, self
.env
.mutex_get_increment())
225 self
.env
.mutex_set_increment(v
)
226 self
.assertEqual(v
, self
.env
.mutex_get_increment())
228 # You can not change configuration after opening
230 self
.env
.open(self
.homeDir
, db
.DB_CREATE
)
231 self
.assertRaises(db
.DBInvalidArgError
,
232 self
.env
.mutex_set_increment
, v2
)
234 def test_mutex_setget_tas_spins(self
) :
235 self
.env
.mutex_set_tas_spins(0) # Default = BDB decides
236 v
= self
.env
.mutex_get_tas_spins()
239 self
.env
.mutex_set_tas_spins(v2
)
240 self
.assertEqual(v2
, self
.env
.mutex_get_tas_spins())
242 self
.env
.mutex_set_tas_spins(v
)
243 self
.assertEqual(v
, self
.env
.mutex_get_tas_spins())
245 # In this case, you can change configuration
246 # after opening the environment.
247 self
.env
.open(self
.homeDir
, db
.DB_CREATE
)
248 self
.env
.mutex_set_tas_spins(v2
)
250 def test_mutex_setget_align(self
) :
251 v
= self
.env
.mutex_get_align()
256 self
.env
.mutex_set_align(v2
)
257 self
.assertEqual(v2
, self
.env
.mutex_get_align())
259 # Requires a nonzero power of two
260 self
.assertRaises(db
.DBInvalidArgError
,
261 self
.env
.mutex_set_align
, 0)
262 self
.assertRaises(db
.DBInvalidArgError
,
263 self
.env
.mutex_set_align
, 17)
265 self
.env
.mutex_set_align(2*v2
)
266 self
.assertEqual(2*v2
, self
.env
.mutex_get_align())
268 # You can not change configuration after opening
270 self
.env
.open(self
.homeDir
, db
.DB_CREATE
)
271 self
.assertRaises(db
.DBInvalidArgError
,
272 self
.env
.mutex_set_align
, v2
)
275 class DBEnv_log(DBEnv
) :
278 self
.env
.open(self
.homeDir
, db
.DB_CREATE | db
.DB_INIT_MPOOL | db
.DB_INIT_LOG
)
280 def test_log_file(self
) :
281 log_file
= self
.env
.log_file((1, 1))
282 self
.assertEqual("log.0000000001", log_file
[-14:])
284 if db
.version() >= (4, 4) :
285 # The version with transactions is checked in other test object
286 def test_log_printf(self
) :
287 msg
= "This is a test..."
288 self
.env
.log_printf(msg
)
289 logc
= self
.env
.log_cursor()
290 self
.assertTrue(msg
in (logc
.last()[1]))
292 if db
.version() >= (4, 7) :
293 def test_log_config(self
) :
294 self
.env
.log_set_config(db
.DB_LOG_DSYNC | db
.DB_LOG_ZERO
, 1)
295 self
.assertTrue(self
.env
.log_get_config(db
.DB_LOG_DSYNC
))
296 self
.assertTrue(self
.env
.log_get_config(db
.DB_LOG_ZERO
))
297 self
.env
.log_set_config(db
.DB_LOG_ZERO
, 0)
298 self
.assertTrue(self
.env
.log_get_config(db
.DB_LOG_DSYNC
))
299 self
.assertFalse(self
.env
.log_get_config(db
.DB_LOG_ZERO
))
302 class DBEnv_log_txn(DBEnv
) :
305 self
.env
.open(self
.homeDir
, db
.DB_CREATE | db
.DB_INIT_MPOOL |
306 db
.DB_INIT_LOG | db
.DB_INIT_TXN
)
308 if db
.version() >= (4, 5) :
309 def test_tx_max(self
) :
312 for i
in xrange(self
.env
.get_tx_max()) :
313 txns
.append(self
.env
.txn_begin())
316 self
.assertRaises(MemoryError, tx
)
318 # Abort the transactions before garbage collection,
319 # to avoid "warnings".
323 if db
.version() >= (4, 4) :
324 # The version without transactions is checked in other test object
325 def test_log_printf(self
) :
326 msg
= "This is a test..."
327 txn
= self
.env
.txn_begin()
328 self
.env
.log_printf(msg
, txn
=txn
)
330 logc
= self
.env
.log_cursor()
331 logc
.last() # Skip the commit
332 self
.assertTrue(msg
in (logc
.prev()[1]))
334 msg
= "This is another test..."
335 txn
= self
.env
.txn_begin()
336 self
.env
.log_printf(msg
, txn
=txn
)
337 txn
.abort() # Do not store the new message
338 logc
.last() # Skip the abort
339 self
.assertTrue(msg
not in (logc
.prev()[1]))
341 msg
= "This is a third test..."
342 txn
= self
.env
.txn_begin()
343 self
.env
.log_printf(msg
, txn
=txn
)
344 txn
.commit() # Do not store the new message
345 logc
.last() # Skip the commit
346 self
.assertTrue(msg
in (logc
.prev()[1]))
349 class DBEnv_memp(DBEnv
):
352 self
.env
.open(self
.homeDir
, db
.DB_CREATE | db
.DB_INIT_MPOOL | db
.DB_INIT_LOG
)
353 self
.db
= db
.DB(self
.env
)
354 self
.db
.open("test", db
.DB_HASH
, db
.DB_CREATE
, 0660)
361 def test_memp_1_trickle(self
) :
362 self
.db
.put("hi", "bye")
363 self
.assertTrue(self
.env
.memp_trickle(100) > 0)
365 # Preserve the order, do "memp_trickle" test first
366 def test_memp_2_sync(self
) :
367 self
.db
.put("hi", "bye")
368 self
.env
.memp_sync() # Full flush
370 self
.assertTrue(self
.env
.memp_trickle(100) == 0)
372 self
.db
.put("hi", "bye2")
373 self
.env
.memp_sync((1, 0)) # NOP, probably
374 # Something to do... or not
375 self
.assertTrue(self
.env
.memp_trickle(100) >= 0)
377 self
.db
.put("hi", "bye3")
378 self
.env
.memp_sync((123, 99)) # Full flush
380 self
.assertTrue(self
.env
.memp_trickle(100) == 0)
382 def test_memp_stat_1(self
) :
383 stats
= self
.env
.memp_stat() # No param
384 self
.assertTrue(len(stats
)==2)
385 self
.assertTrue("cache_miss" in stats
[0])
386 stats
= self
.env
.memp_stat(db
.DB_STAT_CLEAR
) # Positional param
387 self
.assertTrue("cache_miss" in stats
[0])
388 stats
= self
.env
.memp_stat(flags
=0) # Keyword param
389 self
.assertTrue("cache_miss" in stats
[0])
391 def test_memp_stat_2(self
) :
392 stats
=self
.env
.memp_stat()[1]
393 self
.assertTrue(len(stats
))==1
394 self
.assertTrue("test" in stats
)
395 self
.assertTrue("page_in" in stats
["test"])
397 class DBEnv_logcursor(DBEnv
):
400 self
.env
.open(self
.homeDir
, db
.DB_CREATE | db
.DB_INIT_MPOOL |
401 db
.DB_INIT_LOG | db
.DB_INIT_TXN
)
402 txn
= self
.env
.txn_begin()
403 self
.db
= db
.DB(self
.env
)
404 self
.db
.open("test", db
.DB_HASH
, db
.DB_CREATE
, 0660, txn
=txn
)
406 for i
in ["2", "8", "20"] :
407 txn
= self
.env
.txn_begin()
408 self
.db
.put(key
= i
, data
= i
*int(i
), txn
=txn
)
416 def _check_return(self
, value
) :
417 self
.assertTrue(isinstance(value
, tuple))
418 self
.assertEqual(len(value
), 2)
419 self
.assertTrue(isinstance(value
[0], tuple))
420 self
.assertEqual(len(value
[0]), 2)
421 self
.assertTrue(isinstance(value
[0][0], int))
422 self
.assertTrue(isinstance(value
[0][1], int))
423 self
.assertTrue(isinstance(value
[1], str))
425 # Preserve test order
426 def test_1_first(self
) :
427 logc
= self
.env
.log_cursor()
429 self
._check
_return
(v
)
430 self
.assertTrue((1, 1) < v
[0])
431 self
.assertTrue(len(v
[1])>0)
433 def test_2_last(self
) :
434 logc
= self
.env
.log_cursor()
435 lsn_first
= logc
.first()[0]
437 self
._check
_return
(v
)
438 self
.assertTrue(lsn_first
< v
[0])
440 def test_3_next(self
) :
441 logc
= self
.env
.log_cursor()
442 lsn_last
= logc
.last()[0]
443 self
.assertEqual(logc
.next(), None)
444 lsn_first
= logc
.first()[0]
446 self
._check
_return
(v
)
447 self
.assertTrue(lsn_first
< v
[0])
448 self
.assertTrue(lsn_last
> v
[0])
451 self
.assertTrue(v2
[0] > v
[0])
452 self
.assertTrue(lsn_last
> v2
[0])
455 self
.assertTrue(v3
[0] > v2
[0])
456 self
.assertTrue(lsn_last
> v3
[0])
458 def test_4_prev(self
) :
459 logc
= self
.env
.log_cursor()
460 lsn_first
= logc
.first()[0]
461 self
.assertEqual(logc
.prev(), None)
462 lsn_last
= logc
.last()[0]
464 self
._check
_return
(v
)
465 self
.assertTrue(lsn_first
< v
[0])
466 self
.assertTrue(lsn_last
> v
[0])
469 self
.assertTrue(v2
[0] < v
[0])
470 self
.assertTrue(lsn_first
< v2
[0])
473 self
.assertTrue(v3
[0] < v2
[0])
474 self
.assertTrue(lsn_first
< v3
[0])
476 def test_5_current(self
) :
477 logc
= self
.env
.log_cursor()
480 self
.assertEqual(v
, logc
.current())
482 def test_6_set(self
) :
483 logc
= self
.env
.log_cursor()
486 self
.assertNotEqual(v
, logc
.next())
487 self
.assertNotEqual(v
, logc
.next())
488 self
.assertEqual(v
, logc
.set(v
[0]))
490 def test_explicit_close(self
) :
491 logc
= self
.env
.log_cursor()
493 self
.assertRaises(db
.DBCursorClosedError
, logc
.next
)
495 def test_implicit_close(self
) :
496 logc
= [self
.env
.log_cursor() for i
in xrange(10)]
497 self
.env
.close() # This close should close too all its tree
499 self
.assertRaises(db
.DBCursorClosedError
, i
.next
)
502 suite
= unittest
.TestSuite()
504 suite
.addTest(unittest
.makeSuite(DBEnv_general
))
505 suite
.addTest(unittest
.makeSuite(DBEnv_memp
))
506 suite
.addTest(unittest
.makeSuite(DBEnv_logcursor
))
507 suite
.addTest(unittest
.makeSuite(DBEnv_log
))
508 suite
.addTest(unittest
.makeSuite(DBEnv_log_txn
))
512 if __name__
== '__main__':
513 unittest
.main(defaultTest
='test_suite')