def test_deadlock(self): # deadlock is not recoverable t = ZKTransaction(zkhost) # t.txid is lower t.begin() t.lock_get('foo') def _commit(): t.commit() txid = None try: with ZKTransaction(zkhost, timeout=0.5) as t1: txid = t1.txid # lock another key first to produce deadlock t1.lock_get('woo') t1.set_state('bar') threadutil.start_daemon(_commit, after=0.2) t1.lock_get('foo') # should deadlock waiting for higher txid except Deadlock: pass t = ZKTransaction(zkhost) self.assertIsNone(t.zkstorage.state.get(txid)[0])
def test_redo_dead_tx_without_journal(self): t1 = ZKTransaction(zkhost) t1.begin() t1.lock_get('foo') t1.zke.stop() with ZKTransaction(zkhost) as t2: foo = t2.lock_get('foo') foo.v = foo.v or 0 foo.v += 1 t2.set(foo) t2.commit() t = ZKTransaction(zkhost) rst, ver = t.zkstorage.record.get('foo') dd(rst) self.assertEqual(1, rst[-1]) journal_id_set, ver = t.zkstorage.journal_id_set.get() self.assertEqual({COMMITTED: [[0, 1]], PURGED: []}, journal_id_set)
def test_noblocking_lock_get(self): with ZKTransaction(zkhost) as t1: t1.lock_get('foo') f2 = t1.lock_get('foo', blocking=False) self.assertIsNotNone(f2) with ZKTransaction(zkhost) as t2: f4 = t2.lock_get('foo', blocking=False) self.assertIsNone(f4) t = ZKTransaction(zkhost) t.begin() t.lock_get('foo') t.zke.stop() dd(self.zk.get('lock/foo')) # can lock the key which is hold by a dead tx without state with ZKTransaction(zkhost) as t1: self.assertIsNotNone(t1.lock_get('foo', blocking=False)) t = ZKTransaction(zkhost) t.begin() t.lock_get('foo') t.set_state('s') t.zke.stop() dd(self.zk.get('lock/foo')) # can not lock the key which is hold by a dead tx with state with ZKTransaction(zkhost) as t1: self.assertIsNone(t1.lock_get('foo', blocking=False))
def test_timeout(self): # timeout on waiting is recoverable t = ZKTransaction(zkhost) txid = None try: with ZKTransaction(zkhost, timeout=0.5, lock_timeout=0.5) as t1: txid = t1.txid start_ts = t1.start_ts # t.txid is higher t.begin() t.lock_get('foo') t1.set_state('bar') t1.lock_get('foo') # should timeout waiting for higher txid except TXTimeout: pass val, ver = t.zkstorage.state.get(txid) self.assertEqual({ 'got_keys': [], 'data': 'bar', "start_ts": start_ts }, val)
def test_redo_dead_tx_without_journal(self): t1 = ZKTransaction(zkhost) t1.begin() t1.lock_get('foo') t1.zke.stop() with ZKTransaction(zkhost) as t2: foo = t2.lock_get('foo') foo.v = foo.v or 0 foo.v += 1 t2.set(foo) t2.commit() t = ZKTransaction(zkhost) rst, ver = t.zkstorage.record.get('foo') dd(rst) self.assertEqual(1, rst[-1][1]) rst, ver = t.zkstorage.txidset.get() dd(rst) self.assertEqual([1, 2], rst[PURGED][0]) self.assertEqual([2, 3], rst[COMMITTED][0])
def test_timeout(self): # timeout on waiting is recoverable t = ZKTransaction(zkhost) txid = None try: with ZKTransaction(zkhost, timeout=0.5, lock_timeout=0.5) as t1: txid = t1.txid # t.txid is higher t.begin() t.lock_get('foo') t1.set_mem_state('bar') t1.lock_get('foo') # should timeout waiting for higher txid except TXTimeout: pass self.assertIsNone(t.zkstorage.state.get(txid)[0])
def test_timeout(self): # timeout on waiting is recoverable t = ZKTransaction(zkhost) txid = None try: with ZKTransaction(zkhost, timeout=0.5) as t1: txid = t1.txid # t.txid is higher t.begin() t.lock_get('foo') t1.set_state('bar') t1.lock_get('foo') # should timeout waiting for higher txid except TXTimeout: pass val, ver = t.zkstorage.state.get(txid) self.assertEqual({'got_keys': [], 'data': 'bar'}, val)
def test_single_record(self): tx = ZKTransaction(zkhost) tx.begin() foo = tx.lock_get('foo') self.assertEqual('foo', foo.k) self.assertIsNone(foo.v) foo.v = 1 tx.set(foo) tx.commit() rst, ver = self.zk.get('record/foo') self.assertEqual([None, 1], utfjson.load(rst)) rst, ver = self.zk.get('tx/journal_id_set') self.assertEqual({COMMITTED: [[0, 1]], PURGED: [], }, utfjson.load(rst))
def test_single_record(self): tx = ZKTransaction(zkhost) tx.begin() foo = tx.lock_get('foo') self.assertEqual('foo', foo.k) self.assertIsNone(foo.v) foo.v = 1 tx.set(foo) tx.commit() rst, ver = self.zk.get('record/foo') self.assertEqual([[-1, None], [1, 1]], utfjson.load(rst)) rst, ver = self.zk.get('tx/txidset') self.assertEqual({COMMITTED: [[1, 2]], PURGED: [], }, utfjson.load(rst))