PageRenderTime 335ms CodeModel.GetById 100ms app.highlight 105ms RepoModel.GetById 127ms app.codeStats 0ms

/Lib/bsddb/test/test_early_close.py

http://unladen-swallow.googlecode.com/
Python | 195 lines | 145 code | 35 blank | 15 comment | 17 complexity | d428f7eac61bfccc96b635d4158a2566 MD5 | raw file
  1"""TestCases for checking that it does not segfault when a DBEnv object
  2is closed before its DB objects.
  3"""
  4
  5import os
  6import unittest
  7
  8from test_all import db, test_support, verbose, get_new_environment_path, get_new_database_path
  9
 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.
 12try:
 13    import warnings
 14except ImportError:
 15    pass
 16else:
 17    warnings.filterwarnings('ignore',
 18                            message='DB could not be closed in',
 19                            category=RuntimeWarning)
 20
 21
 22#----------------------------------------------------------------------
 23
 24class DBEnvClosedEarlyCrash(unittest.TestCase):
 25    def setUp(self):
 26        self.homeDir = get_new_environment_path()
 27        self.filename = "test"
 28
 29    def tearDown(self):
 30        test_support.rmtree(self.homeDir)
 31
 32    def test01_close_dbenv_before_db(self):
 33        dbenv = db.DBEnv()
 34        dbenv.open(self.homeDir,
 35                   db.DB_INIT_CDB| db.DB_CREATE |db.DB_THREAD|db.DB_INIT_MPOOL,
 36                   0666)
 37
 38        d = db.DB(dbenv)
 39        d2 = db.DB(dbenv)
 40        d.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0666)
 41
 42        self.assertRaises(db.DBNoSuchFileError, d2.open,
 43                self.filename+"2", db.DB_BTREE, db.DB_THREAD, 0666)
 44
 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")
 49
 50    def test02_close_dbenv_before_dbcursor(self):
 51        dbenv = db.DBEnv()
 52        dbenv.open(self.homeDir,
 53                   db.DB_INIT_CDB| db.DB_CREATE |db.DB_THREAD|db.DB_INIT_MPOOL,
 54                   0666)
 55
 56        d = db.DB(dbenv)
 57        d.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0666)
 58
 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")
 63        c=d.cursor()
 64        c.first()
 65        c.next()
 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)
 69
 70        d = db.DB(dbenv)
 71        d.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0666)
 72        c=d.cursor()
 73        c.first()
 74        c.next()
 75        dbenv.close()
 76    # The "close" should close the child db handle also, with cursors
 77        self.assertRaises(db.DBError, c.next)
 78
 79    def test03_close_db_before_dbcursor_without_env(self):
 80        import os.path
 81        path=os.path.join(self.homeDir,self.filename)
 82        d = db.DB()
 83        d.open(path, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0666)
 84
 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")
 89        c=d.cursor()
 90        c.first()
 91        c.next()
 92        d.close()
 93    # The "close" should close the child db handle also
 94        self.assertRaises(db.DBError, c.next)
 95
 96    def test04_close_massive(self):
 97        dbenv = db.DBEnv()
 98        dbenv.open(self.homeDir,
 99                   db.DB_INIT_CDB| db.DB_CREATE |db.DB_THREAD|db.DB_INIT_MPOOL,
100                   0666)
101
102        dbs=[db.DB(dbenv) for i in xrange(16)]
103        cursors=[]
104        for i in dbs :
105            i.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0666)
106
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")
111
112        for i in dbs :
113            cursors.extend([i.cursor() for j in xrange(32)])
114
115        for i in dbs[::3] :
116            i.close()
117        for i in cursors[::3] :
118            i.close()
119
120    # Check for missing exception in DB! (after DB close)
121        self.assertRaises(db.DBError, dbs[9].get, "test")
122
123    # Check for missing exception in DBCursor! (after DB close)
124        self.assertRaises(db.DBError, cursors[101].first)
125
126        cursors[80].first()
127        cursors[80].next()
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)
131
132    def test05_close_dbenv_delete_db_success(self):
133        dbenv = db.DBEnv()
134        dbenv.open(self.homeDir,
135                   db.DB_INIT_CDB| db.DB_CREATE |db.DB_THREAD|db.DB_INIT_MPOOL,
136                   0666)
137
138        d = db.DB(dbenv)
139        d.open(self.filename, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0666)
140
141        dbenv.close()  # This "close" should close the child db handle also
142
143        del d
144        try:
145            import gc
146        except ImportError:
147            gc = None
148        if gc:
149            # force d.__del__ [DB_dealloc] to be called
150            gc.collect()
151
152    def test06_close_txn_before_dup_cursor(self) :
153        dbenv = db.DBEnv()
154        dbenv.open(self.homeDir,db.DB_INIT_TXN | db.DB_INIT_MPOOL |
155                db.DB_INIT_LOG | db.DB_CREATE)
156        d = db.DB(dbenv)
157        txn = dbenv.txn_begin()
158        if db.version() < (4,1) :
159            d.open(self.filename, dbtype = db.DB_HASH, flags = db.DB_CREATE)
160        else :
161            d.open(self.filename, dbtype = db.DB_HASH, flags = db.DB_CREATE,
162                    txn=txn)
163        d.put("XXX", "yyy", txn=txn)
164        txn.commit()
165        txn = dbenv.txn_begin()
166        c1 = d.cursor(txn)
167        c2 = c1.dup()
168        self.assertEquals(("XXX", "yyy"), c1.first())
169        import warnings
170        # Not interested in warnings about implicit close.
171        with warnings.catch_warnings():
172            warnings.simplefilter("ignore")
173            txn.commit()
174        self.assertRaises(db.DBCursorClosedError, c2.first)
175
176    if db.version() > (4,3,0) :
177        def test07_close_db_before_sequence(self):
178            import os.path
179            path=os.path.join(self.homeDir,self.filename)
180            d = db.DB()
181            d.open(path, db.DB_BTREE, db.DB_CREATE | db.DB_THREAD, 0666)
182            dbs=db.DBSequence(d)
183            d.close()  # This "close" should close the child DBSequence also
184            dbs.close()  # If not closed, core dump (in Berkeley DB 4.6.*)
185
186#----------------------------------------------------------------------
187
188def test_suite():
189    suite = unittest.TestSuite()
190    suite.addTest(unittest.makeSuite(DBEnvClosedEarlyCrash))
191    return suite
192
193
194if __name__ == '__main__':
195    unittest.main(defaultTest='test_suite')