1 """TestCases for checking that it does not segfault when a DBEnv object
2 is closed before its DB objects.
8 from test_all
import db
, test_support
, verbose
, get_new_environment_path
, get_new_database_path
10 # We're going to get warnings in this module about trying to close the db when
11 # its env is already closed. Let's just ignore those.
17 warnings
.filterwarnings('ignore',
18 message
='DB could not be closed in',
19 category
=RuntimeWarning)
22 #----------------------------------------------------------------------
24 class DBEnvClosedEarlyCrash(unittest
.TestCase
):
26 self
.homeDir
= get_new_environment_path()
27 self
.filename
= "test"
30 test_support
.rmtree(self
.homeDir
)
32 def test01_close_dbenv_before_db(self
):
34 dbenv
.open(self
.homeDir
,
35 db
.DB_INIT_CDB| db
.DB_CREATE |db
.DB_THREAD|db
.DB_INIT_MPOOL
,
40 d
.open(self
.filename
, db
.DB_BTREE
, db
.DB_CREATE | db
.DB_THREAD
, 0666)
42 self
.assertRaises(db
.DBNoSuchFileError
, d2
.open,
43 self
.filename
+"2", db
.DB_BTREE
, db
.DB_THREAD
, 0666)
45 d
.put("test","this is a test")
46 self
.assertEqual(d
.get("test"), "this is a test", "put!=get")
47 dbenv
.close() # This "close" should close the child db handle also
48 self
.assertRaises(db
.DBError
, d
.get
, "test")
50 def test02_close_dbenv_before_dbcursor(self
):
52 dbenv
.open(self
.homeDir
,
53 db
.DB_INIT_CDB| db
.DB_CREATE |db
.DB_THREAD|db
.DB_INIT_MPOOL
,
57 d
.open(self
.filename
, db
.DB_BTREE
, db
.DB_CREATE | db
.DB_THREAD
, 0666)
59 d
.put("test","this is a test")
60 d
.put("test2","another test")
61 d
.put("test3","another one")
62 self
.assertEqual(d
.get("test"), "this is a test", "put!=get")
66 d
.close() # This "close" should close the child db handle also
67 # db.close should close the child cursor
68 self
.assertRaises(db
.DBError
,c
.next
)
71 d
.open(self
.filename
, db
.DB_BTREE
, db
.DB_CREATE | db
.DB_THREAD
, 0666)
76 # The "close" should close the child db handle also, with cursors
77 self
.assertRaises(db
.DBError
, c
.next
)
79 def test03_close_db_before_dbcursor_without_env(self
):
81 path
=os
.path
.join(self
.homeDir
,self
.filename
)
83 d
.open(path
, db
.DB_BTREE
, db
.DB_CREATE | db
.DB_THREAD
, 0666)
85 d
.put("test","this is a test")
86 d
.put("test2","another test")
87 d
.put("test3","another one")
88 self
.assertEqual(d
.get("test"), "this is a test", "put!=get")
93 # The "close" should close the child db handle also
94 self
.assertRaises(db
.DBError
, c
.next
)
96 def test04_close_massive(self
):
98 dbenv
.open(self
.homeDir
,
99 db
.DB_INIT_CDB| db
.DB_CREATE |db
.DB_THREAD|db
.DB_INIT_MPOOL
,
102 dbs
=[db
.DB(dbenv
) for i
in xrange(16)]
105 i
.open(self
.filename
, db
.DB_BTREE
, db
.DB_CREATE | db
.DB_THREAD
, 0666)
107 dbs
[10].put("test","this is a test")
108 dbs
[10].put("test2","another test")
109 dbs
[10].put("test3","another one")
110 self
.assertEqual(dbs
[4].get("test"), "this is a test", "put!=get")
113 cursors
.extend([i
.cursor() for j
in xrange(32)])
117 for i
in cursors
[::3] :
120 # Check for missing exception in DB! (after DB close)
121 self
.assertRaises(db
.DBError
, dbs
[9].get
, "test")
123 # Check for missing exception in DBCursor! (after DB close)
124 self
.assertRaises(db
.DBError
, cursors
[101].first
)
128 dbenv
.close() # This "close" should close the child db handle also
129 # Check for missing exception! (after DBEnv close)
130 self
.assertRaises(db
.DBError
, cursors
[80].next
)
132 def test05_close_dbenv_delete_db_success(self
):
134 dbenv
.open(self
.homeDir
,
135 db
.DB_INIT_CDB| db
.DB_CREATE |db
.DB_THREAD|db
.DB_INIT_MPOOL
,
139 d
.open(self
.filename
, db
.DB_BTREE
, db
.DB_CREATE | db
.DB_THREAD
, 0666)
141 dbenv
.close() # This "close" should close the child db handle also
149 # force d.__del__ [DB_dealloc] to be called
152 def test06_close_txn_before_dup_cursor(self
) :
154 dbenv
.open(self
.homeDir
,db
.DB_INIT_TXN | db
.DB_INIT_MPOOL |
155 db
.DB_INIT_LOG | db
.DB_CREATE
)
157 txn
= dbenv
.txn_begin()
158 d
.open(self
.filename
, dbtype
= db
.DB_HASH
, flags
= db
.DB_CREATE
,
160 d
.put("XXX", "yyy", txn
=txn
)
162 txn
= dbenv
.txn_begin()
165 self
.assertEquals(("XXX", "yyy"), c1
.first())
167 # Not interested in warnings about implicit close.
169 if sys
.version_info
< (2, 6) :
170 # Completely resetting the warning state is
171 # problematic with python >=2.6 with -3 (py3k warning),
172 # because some stdlib modules selectively ignores warnings.
173 warnings
.simplefilter("ignore")
175 warnings
.resetwarnings()
177 # When we drop support for python 2.3 and 2.4
178 # we could use: (in 2.5 we need a __future__ statement)
180 # with warnings.catch_warnings():
181 # warnings.simplefilter("ignore")
184 # We can not use "with" as is, because it would be invalid syntax
185 # in python 2.3, 2.4 and (with no __future__) 2.5.
186 # Here we simulate "with" following PEP 343 :
187 w
= warnings
.catch_warnings()
190 warnings
.simplefilter("ignore")
195 self
.assertRaises(db
.DBCursorClosedError
, c2
.first
)
197 if db
.version() > (4,3,0) :
198 def test07_close_db_before_sequence(self
):
200 path
=os
.path
.join(self
.homeDir
,self
.filename
)
202 d
.open(path
, db
.DB_BTREE
, db
.DB_CREATE | db
.DB_THREAD
, 0666)
204 d
.close() # This "close" should close the child DBSequence also
205 dbs
.close() # If not closed, core dump (in Berkeley DB 4.6.*)
207 #----------------------------------------------------------------------
210 suite
= unittest
.TestSuite()
211 suite
.addTest(unittest
.makeSuite(DBEnvClosedEarlyCrash
))
215 if __name__
== '__main__':
216 unittest
.main(defaultTest
='test_suite')