Commit 9cca0f8e authored by Julien Muchembled's avatar Julien Muchembled

Found 2 bugs in undo, add tests

parent 8ec0faf7
...@@ -538,7 +538,8 @@ class Application(ThreadedApplication): ...@@ -538,7 +538,8 @@ class Application(ThreadedApplication):
if data is CHECKED_SERIAL: if data is CHECKED_SERIAL:
raise ReadConflictError(oid=oid, serials=(conflict_serial, raise ReadConflictError(oid=oid, serials=(conflict_serial,
serial)) serial))
if data: # XXX: can 'data' be None ??? # TODO: data can be None if a conflict happens during undo
if data:
txn_context['data_size'] -= len(data) txn_context['data_size'] -= len(data)
resolved_serial_set = resolved_conflict_serial_dict.setdefault( resolved_serial_set = resolved_conflict_serial_dict.setdefault(
oid, set()) oid, set())
......
...@@ -42,7 +42,10 @@ class PCounter(Persistent): ...@@ -42,7 +42,10 @@ class PCounter(Persistent):
class PCounterWithResolution(PCounter): class PCounterWithResolution(PCounter):
def _p_resolveConflict(self, old, saved, new): def _p_resolveConflict(self, old, saved, new):
new['value'] += saved['value'] - old.get('value', 0) new['value'] = (
saved.get('value', 0)
+ new.get('value', 0)
- old.get('value', 0))
return new return new
class Test(NEOThreadedTest): class Test(NEOThreadedTest):
...@@ -152,6 +155,43 @@ class Test(NEOThreadedTest): ...@@ -152,6 +155,43 @@ class Test(NEOThreadedTest):
finally: finally:
cluster.stop() cluster.stop()
def testUndoConflict(self, conflict_during_store=False):
def waitResponses(orig, *args):
orig(*args)
p.revert()
ob.value += 3
t.commit()
cluster = NEOCluster()
try:
cluster.start()
t, c = cluster.getTransaction()
c.root()[0] = ob = PCounterWithResolution()
t.commit()
ob.value += 1
t.commit()
tid = ob._p_serial
storage = cluster.db.storage
txn = transaction.Transaction()
storage.tpc_begin(txn)
if conflict_during_store:
with Patch(cluster.client, waitResponses=waitResponses) as p:
storage.undo(tid, txn)
else:
ob.value += 3
t.commit()
storage.undo(tid, txn)
storage.tpc_finish(txn)
value = ob.value
ob._p_invalidate() # BUG: this should not be required
self.assertEqual(ob.value, 3)
expectedFailure(self.assertNotEqual)(value, 4)
finally:
cluster.stop()
@expectedFailure(POSException.ConflictError)
def testUndoConflictDuringStore(self):
self.testUndoConflict(True)
def testStorageDataLock(self): def testStorageDataLock(self):
cluster = NEOCluster() cluster = NEOCluster()
try: try:
......
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