1edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep"""TestCases for distributed transactions. 2edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep""" 3edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 4edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport os 5edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport unittest 6edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 7edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom test_all import db, test_support, get_new_environment_path, \ 8edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep get_new_database_path 9edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 10edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom test_all import verbose 11edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 12edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#---------------------------------------------------------------------- 13edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 14edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass DBTxn_distributed(unittest.TestCase): 15edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep num_txns=1234 16edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep nosync=True 17edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep must_open_db=False 18edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _create_env(self, must_open_db) : 19edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.dbenv = db.DBEnv() 20edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.dbenv.set_tx_max(self.num_txns) 21edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.dbenv.set_lk_max_lockers(self.num_txns*2) 22edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.dbenv.set_lk_max_locks(self.num_txns*2) 23edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.dbenv.set_lk_max_objects(self.num_txns*2) 24edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self.nosync : 25edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.dbenv.set_flags(db.DB_TXN_NOSYNC,True) 26edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.dbenv.open(self.homeDir, db.DB_CREATE | db.DB_THREAD | 27edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep db.DB_RECOVER | 28edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep db.DB_INIT_TXN | db.DB_INIT_LOG | db.DB_INIT_MPOOL | 29edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep db.DB_INIT_LOCK, 0666) 30edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.db = db.DB(self.dbenv) 31edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.db.set_re_len(db.DB_GID_SIZE) 32edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if must_open_db : 33edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep txn=self.dbenv.txn_begin() 34edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.db.open(self.filename, 35edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep db.DB_QUEUE, db.DB_CREATE | db.DB_THREAD, 0666, 36edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep txn=txn) 37edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep txn.commit() 38edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 39edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def setUp(self) : 40edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.homeDir = get_new_environment_path() 41edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.filename = "test" 42edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._create_env(must_open_db=True) 43edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 44edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _destroy_env(self): 45edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if self.nosync or (db.version()[:2] == (4,6)): # Known bug 46edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.dbenv.log_flush() 47edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.db.close() 48edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.dbenv.close() 49edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 50edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def tearDown(self): 51edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._destroy_env() 52edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep test_support.rmtree(self.homeDir) 53edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 54edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def _recreate_env(self,must_open_db) : 55edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._destroy_env() 56edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._create_env(must_open_db) 57edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 58edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def test01_distributed_transactions(self) : 59edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep txns=set() 60edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep adapt = lambda x : x 61edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep import sys 62edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if sys.version_info[0] >= 3 : 63edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep adapt = lambda x : bytes(x, "ascii") 64edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Create transactions, "prepare" them, and 65edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # let them be garbage collected. 66edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for i in xrange(self.num_txns) : 67edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep txn = self.dbenv.txn_begin() 68edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep gid = "%%%dd" %db.DB_GID_SIZE 69edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep gid = adapt(gid %i) 70edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.db.put(i, gid, txn=txn, flags=db.DB_APPEND) 71edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep txns.add(gid) 72edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep txn.prepare(gid) 73edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del txn 74edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 75edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._recreate_env(self.must_open_db) 76edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 77edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Get "to be recovered" transactions but 78edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # let them be garbage collected. 79edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep recovered_txns=self.dbenv.txn_recover() 80edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(self.num_txns,len(recovered_txns)) 81edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for gid,txn in recovered_txns : 82edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(gid in txns) 83edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del txn 84edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del recovered_txns 85edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 86edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._recreate_env(self.must_open_db) 87edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 88edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Get "to be recovered" transactions. Commit, abort and 89edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # discard them. 90edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep recovered_txns=self.dbenv.txn_recover() 91edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(self.num_txns,len(recovered_txns)) 92edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep discard_txns=set() 93edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep committed_txns=set() 94edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep state=0 95edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for gid,txn in recovered_txns : 96edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if state==0 or state==1: 97edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep committed_txns.add(gid) 98edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep txn.commit() 99edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif state==2 : 100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep txn.abort() 101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif state==3 : 102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep txn.discard() 103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep discard_txns.add(gid) 104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep state=-1 105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep state+=1 106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del txn 107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del recovered_txns 108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._recreate_env(self.must_open_db) 110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Verify the discarded transactions are still 112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # around, and dispose them. 113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep recovered_txns=self.dbenv.txn_recover() 114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(len(discard_txns),len(recovered_txns)) 115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep for gid,txn in recovered_txns : 116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep txn.abort() 117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del txn 118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep del recovered_txns 119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._recreate_env(must_open_db=True) 121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Be sure there are not pending transactions. 123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep # Check also database size. 124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep recovered_txns=self.dbenv.txn_recover() 125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertTrue(len(recovered_txns)==0) 126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.assertEqual(len(committed_txns),self.db.stat()["nkeys"]) 127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass DBTxn_distributedSYNC(DBTxn_distributed): 129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep nosync=False 130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass DBTxn_distributed_must_open_db(DBTxn_distributed): 132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep must_open_db=True 133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass DBTxn_distributedSYNC_must_open_db(DBTxn_distributed): 135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep nosync=False 136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep must_open_db=True 137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep#---------------------------------------------------------------------- 139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef test_suite(): 141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep suite = unittest.TestSuite() 142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if db.version() >= (4,5) : 143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep suite.addTest(unittest.makeSuite(DBTxn_distributed)) 144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep suite.addTest(unittest.makeSuite(DBTxn_distributedSYNC)) 145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if db.version() >= (4,6) : 146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep suite.addTest(unittest.makeSuite(DBTxn_distributed_must_open_db)) 147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep suite.addTest(unittest.makeSuite(DBTxn_distributedSYNC_must_open_db)) 148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return suite 149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepif __name__ == '__main__': 152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep unittest.main(defaultTest='test_suite') 153