10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""Miscellaneous bsddb module test cases
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""
30a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport os, sys
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport unittest
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom test_all import db, dbshelve, hashopen, test_support, get_new_environment_path, get_new_database_path
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#----------------------------------------------------------------------
100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass MiscTestCase(unittest.TestCase):
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def setUp(self):
130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.filename = get_new_database_path()
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.homeDir = get_new_environment_path()
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def tearDown(self):
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        test_support.unlink(self.filename)
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        test_support.rmtree(self.homeDir)
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test01_badpointer(self):
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dbs = dbshelve.open(self.filename)
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dbs.close()
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertRaises(db.DBError, dbs.get, "foo")
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test02_db_home(self):
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        env = db.DBEnv()
270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # check for crash fixed when db_home is used before open()
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(env.db_home is None)
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        env.open(self.homeDir, db.DB_CREATE)
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if sys.version_info[0] < 3 :
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(self.homeDir, env.db_home)
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        else :
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(bytes(self.homeDir, "ascii"), env.db_home)
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test03_repr_closed_db(self):
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        db = hashopen(self.filename)
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        db.close()
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        rp = repr(db)
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(rp, "{}")
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test04_repr_db(self) :
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        db = hashopen(self.filename)
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        d = {}
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i in xrange(100) :
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db[repr(i)] = repr(100*i)
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            d[repr(i)] = repr(100*i)
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        db.close()
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        db = hashopen(self.filename)
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        rp = repr(db)
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(rp, repr(d))
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        db.close()
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # http://sourceforge.net/tracker/index.php?func=detail&aid=1708868&group_id=13900&atid=313900
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    #
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # See the bug report for details.
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    #
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # The problem was that make_key_dbt() was not allocating a copy of
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # string keys but FREE_DBT() was always being told to free it when the
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # database was opened with DB_THREAD.
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test05_double_free_make_key_dbt(self):
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1 = db.DB()
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1.open(self.filename, None, db.DB_BTREE,
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                     db.DB_CREATE | db.DB_THREAD)
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            curs = db1.cursor()
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            t = curs.get("/foo", db.DB_SET)
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # double free happened during exit from DBC_get
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1.close()
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            test_support.unlink(self.filename)
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test06_key_with_null_bytes(self):
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1 = db.DB()
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1.open(self.filename, None, db.DB_HASH, db.DB_CREATE)
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1['a'] = 'eh?'
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1['a\x00'] = 'eh zed.'
790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1['a\x00a'] = 'eh zed eh?'
800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1['aaa'] = 'eh eh eh!'
810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            keys = db1.keys()
820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            keys.sort()
830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(['a', 'a\x00', 'a\x00a', 'aaa'], keys)
840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(db1['a'], 'eh?')
850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(db1['a\x00'], 'eh zed.')
860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(db1['a\x00a'], 'eh zed eh?')
870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(db1['aaa'], 'eh eh eh!')
880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1.close()
900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            test_support.unlink(self.filename)
910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test07_DB_set_flags_persists(self):
930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        try:
940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1 = db.DB()
950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1.set_flags(db.DB_DUPSORT)
960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1.open(self.filename, db.DB_HASH, db.DB_CREATE)
970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1['a'] = 'eh'
980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1['a'] = 'A'
990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual([('a', 'A')], db1.items())
1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1.put('a', 'Aa')
1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual([('a', 'A'), ('a', 'Aa')], db1.items())
1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1.close()
1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1 = db.DB()
1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # no set_flags call, we're testing that it reads and obeys
1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # the flags on open.
1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1.open(self.filename, db.DB_HASH)
1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual([('a', 'A'), ('a', 'Aa')], db1.items())
1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # if it read the flags right this will replace all values
1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # for key 'a' instead of adding a new one.  (as a dict should)
1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1['a'] = 'new A'
1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual([('a', 'new A')], db1.items())
1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        finally:
1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            db1.close()
1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            test_support.unlink(self.filename)
1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test08_ExceptionTypes(self) :
1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(issubclass(db.DBError, Exception))
1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        for i, j in db.__dict__.items() :
1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if i.startswith("DB") and i.endswith("Error") :
1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertTrue(issubclass(j, db.DBError), msg=i)
1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                if i not in ("DBKeyEmptyError", "DBNotFoundError") :
1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                    self.assertFalse(issubclass(j, KeyError), msg=i)
1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        # This two exceptions have two bases
1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(issubclass(db.DBKeyEmptyError, KeyError))
1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertTrue(issubclass(db.DBNotFoundError, KeyError))
1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao#----------------------------------------------------------------------
1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef test_suite():
1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    return unittest.makeSuite(MiscTestCase)
1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif __name__ == '__main__':
1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    unittest.main(defaultTest='test_suite')
139