Commit 3aae133d authored by Vincent Pelletier's avatar Vincent Pelletier

Make tpc_finish call tpc_vote when it hasn't been called yet.

This fixes random failures in old ZODB undo tests, where tpc_vote was not
called before tpc_finish/tpc_abort.

git-svn-id: https://svn.erp5.org/repos/neo/trunk@2279 71dcc9de-d417-0410-9af5-da40c76e7ee4
parent a22eb5e6
...@@ -66,7 +66,8 @@ class Storage(BaseStorage.BaseStorage, ...@@ -66,7 +66,8 @@ class Storage(BaseStorage.BaseStorage,
return self.app.tpc_abort(transaction=transaction) return self.app.tpc_abort(transaction=transaction)
def tpc_finish(self, transaction, f=None): def tpc_finish(self, transaction, f=None):
return self.app.tpc_finish(transaction=transaction, f=f) return self.app.tpc_finish(transaction=transaction,
tryToResolveConflict=self.tryToResolveConflict, f=f)
@check_read_only @check_read_only
def store(self, oid, serial, data, version, transaction): def store(self, oid, serial, data, version, transaction):
......
...@@ -819,11 +819,13 @@ class Application(object): ...@@ -819,11 +819,13 @@ class Application(object):
self.local_var.clear() self.local_var.clear()
@profiler_decorator @profiler_decorator
def tpc_finish(self, transaction, f=None): def tpc_finish(self, transaction, tryToResolveConflict, f=None):
"""Finish current transaction.""" """Finish current transaction."""
if self.local_var.txn is not transaction: if self.local_var.txn is not transaction:
raise StorageTransactionError('tpc_finish called for wrong ' raise StorageTransactionError('tpc_finish called for wrong '
'transaction') 'transaction')
if not self.local_var.txn_voted:
self.tpc_vote(transaction, tryToResolveConflict)
self._load_lock_acquire() self._load_lock_acquire()
try: try:
tid = self.local_var.tid tid = self.local_var.tid
...@@ -1130,7 +1132,7 @@ class Application(object): ...@@ -1130,7 +1132,7 @@ class Application(object):
updateLastSerial(r.oid, result) updateLastSerial(r.oid, result)
updateLastSerial(None, self.tpc_vote(transaction, updateLastSerial(None, self.tpc_vote(transaction,
tryToResolveConflict)) tryToResolveConflict))
self.tpc_finish(transaction) self.tpc_finish(transaction, tryToResolveConflict)
transaction_iter.close() transaction_iter.close()
def iterator(self, start=None, stop=None): def iterator(self, start=None, stop=None):
......
...@@ -149,7 +149,8 @@ class ClientApplicationTests(NeoTestBase): ...@@ -149,7 +149,8 @@ class ClientApplicationTests(NeoTestBase):
'getAddress': ('127.0.0.1', 10010), 'getAddress': ('127.0.0.1', 10010),
'fakeReceived': packet, 'fakeReceived': packet,
}) })
app.tpc_finish(txn) app.local_var.txn_voted = True
app.tpc_finish(txn, None)
# common checks # common checks
...@@ -678,7 +679,7 @@ class ClientApplicationTests(NeoTestBase): ...@@ -678,7 +679,7 @@ class ClientApplicationTests(NeoTestBase):
cell = Mock() cell = Mock()
app.pt = Mock({'getCellListForTID': (cell, cell)}) app.pt = Mock({'getCellListForTID': (cell, cell)})
app.cp = Mock({'getConnForCell': ReturnValues(None, cell)}) app.cp = Mock({'getConnForCell': ReturnValues(None, cell)})
self.assertRaises(StorageTransactionError, app.tpc_finish, txn) self.assertRaises(StorageTransactionError, app.tpc_finish, txn, None)
# no packet sent # no packet sent
self.checkNoPacketSent(conn) self.checkNoPacketSent(conn)
self.checkNoPacketSent(app.master_conn) self.checkNoPacketSent(app.master_conn)
...@@ -703,13 +704,32 @@ class ClientApplicationTests(NeoTestBase): ...@@ -703,13 +704,32 @@ class ClientApplicationTests(NeoTestBase):
'getAddress': ('127.0.0.1', 10000), 'getAddress': ('127.0.0.1', 10000),
'fakeReceived': packet, 'fakeReceived': packet,
}) })
self.vote_params = None
tpc_vote = app.tpc_vote
def voteDetector(transaction, tryToResolveConflict):
self.vote_params = (transaction, tryToResolveConflict)
dummy_tryToResolveConflict = []
app.tpc_vote = voteDetector
app.dispatcher = Mock({}) app.dispatcher = Mock({})
app.local_var.txn_voted = True
app.local_var.txn_finished = False app.local_var.txn_finished = False
self.assertRaises(NEOStorageError, app.tpc_finish, txn, hook) self.assertRaises(NEOStorageError, app.tpc_finish, txn,
dummy_tryToResolveConflict, hook)
self.assertTrue(self.f_called) self.assertTrue(self.f_called)
self.assertEquals(self.f_called_with_tid, tid) self.assertEquals(self.f_called_with_tid, tid)
self.assertEqual(self.vote_params, None)
self.checkAskFinishTransaction(app.master_conn) self.checkAskFinishTransaction(app.master_conn)
self.checkDispatcherRegisterCalled(app, app.master_conn) self.checkDispatcherRegisterCalled(app, app.master_conn)
# Call again, but this time transaction is not voted yet
app.local_var.txn_voted = False
app.local_var.txn_finished = False
self.f_called = False
self.assertRaises(NEOStorageError, app.tpc_finish, txn,
dummy_tryToResolveConflict, hook)
self.assertTrue(self.f_called)
self.assertTrue(self.vote_params[0] is txn)
self.assertTrue(self.vote_params[1] is dummy_tryToResolveConflict)
app.tpc_vote = tpc_vote
def test_tpc_finish3(self): def test_tpc_finish3(self):
# transaction is finished # transaction is finished
...@@ -730,8 +750,9 @@ class ClientApplicationTests(NeoTestBase): ...@@ -730,8 +750,9 @@ class ClientApplicationTests(NeoTestBase):
'fakeReceived': packet, 'fakeReceived': packet,
}) })
app.dispatcher = Mock({}) app.dispatcher = Mock({})
app.local_var.txn_voted = True
app.local_var.txn_finished = True app.local_var.txn_finished = True
app.tpc_finish(txn, hook) app.tpc_finish(txn, None, hook)
self.assertTrue(self.f_called) self.assertTrue(self.f_called)
self.assertEquals(self.f_called_with_tid, tid) self.assertEquals(self.f_called_with_tid, tid)
self.checkAskFinishTransaction(app.master_conn) self.checkAskFinishTransaction(app.master_conn)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment