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,
return self.app.tpc_abort(transaction=transaction)
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
def store(self, oid, serial, data, version, transaction):
......
......@@ -819,11 +819,13 @@ class Application(object):
self.local_var.clear()
@profiler_decorator
def tpc_finish(self, transaction, f=None):
def tpc_finish(self, transaction, tryToResolveConflict, f=None):
"""Finish current transaction."""
if self.local_var.txn is not transaction:
raise StorageTransactionError('tpc_finish called for wrong '
'transaction')
if not self.local_var.txn_voted:
self.tpc_vote(transaction, tryToResolveConflict)
self._load_lock_acquire()
try:
tid = self.local_var.tid
......@@ -1130,7 +1132,7 @@ class Application(object):
updateLastSerial(r.oid, result)
updateLastSerial(None, self.tpc_vote(transaction,
tryToResolveConflict))
self.tpc_finish(transaction)
self.tpc_finish(transaction, tryToResolveConflict)
transaction_iter.close()
def iterator(self, start=None, stop=None):
......
......@@ -149,7 +149,8 @@ class ClientApplicationTests(NeoTestBase):
'getAddress': ('127.0.0.1', 10010),
'fakeReceived': packet,
})
app.tpc_finish(txn)
app.local_var.txn_voted = True
app.tpc_finish(txn, None)
# common checks
......@@ -678,7 +679,7 @@ class ClientApplicationTests(NeoTestBase):
cell = Mock()
app.pt = Mock({'getCellListForTID': (cell, 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
self.checkNoPacketSent(conn)
self.checkNoPacketSent(app.master_conn)
......@@ -703,13 +704,32 @@ class ClientApplicationTests(NeoTestBase):
'getAddress': ('127.0.0.1', 10000),
'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.local_var.txn_voted = True
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.assertEquals(self.f_called_with_tid, tid)
self.assertEqual(self.vote_params, None)
self.checkAskFinishTransaction(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):
# transaction is finished
......@@ -730,8 +750,9 @@ class ClientApplicationTests(NeoTestBase):
'fakeReceived': packet,
})
app.dispatcher = Mock({})
app.local_var.txn_voted = True
app.local_var.txn_finished = True
app.tpc_finish(txn, hook)
app.tpc_finish(txn, None, hook)
self.assertTrue(self.f_called)
self.assertEquals(self.f_called_with_tid, tid)
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