[CalendarServer-changes] [7257] CalendarServer/branches/users/glyph/subtransactions/txdav/base/ propertystore/test/test_sql.py

source_changes at macosforge.org source_changes at macosforge.org
Thu Mar 24 13:37:02 PDT 2011


Revision: 7257
          http://trac.macosforge.org/projects/calendarserver/changeset/7257
Author:   glyph at apple.com
Date:     2011-03-24 13:37:02 -0700 (Thu, 24 Mar 2011)
Log Message:
-----------
correct errors in test_concurrentInsertion

Modified Paths:
--------------
    CalendarServer/branches/users/glyph/subtransactions/txdav/base/propertystore/test/test_sql.py

Modified: CalendarServer/branches/users/glyph/subtransactions/txdav/base/propertystore/test/test_sql.py
===================================================================
--- CalendarServer/branches/users/glyph/subtransactions/txdav/base/propertystore/test/test_sql.py	2011-03-24 20:36:51 UTC (rev 7256)
+++ CalendarServer/branches/users/glyph/subtransactions/txdav/base/propertystore/test/test_sql.py	2011-03-24 20:37:02 UTC (rev 7257)
@@ -27,6 +27,8 @@
     PropertyStoreTest, propertyName, propertyValue)
 
 from twistedcaldav import memcacher
+from twisted.internet.defer import gatherResults
+from twext.enterprise.ienterprise import AlreadyFinishedError
 from twistedcaldav.config import config
 
 try:
@@ -115,25 +117,45 @@
     @inlineCallbacks
     def test_concurrentInsertion(self):
         """
-        When two property stores set the same value, the last one to set it
-        should win.
+        When two property stores set the same value, both should succeed, and
+        update the cache.  Whoever wins the race (i.e. updates last) will set
+        the last property value.
         """
         pname = propertyName("concurrent")
         pval1 = propertyValue("alpha")
         pval2 = propertyValue("beta")
         concurrentTxn = self.store.newTransaction()
-        self.addCleanup(concurrentTxn.abort)
+        @inlineCallbacks
+        def maybeAbortIt():
+            try:
+                yield concurrentTxn.abort()
+            except AlreadyFinishedError:
+                pass
+        self.addCleanup(maybeAbortIt)
         concurrentPropertyStore = yield PropertyStore.load(
             "user01", concurrentTxn, 1
         )
         concurrentPropertyStore[pname] = pval1
-        concurrentTxn.commit()
-
+        race = []
+        def tiebreaker(label):
+            # Let's not get into the business of figuring out who the database
+            # concurrency rules are suppsoed to pick; it might differ.  We just
+            # take the answer we're given for who gets to be the final writer,
+            # and make sure that matches the property read in the next
+            # transaction.
+            def breaktie(result):
+                race.append(label)
+                return result
+            return breaktie
+        a = concurrentTxn.commit().addCallback(tiebreaker('a'))
         self.propertyStore[pname] = pval2
-        yield self._txn.commit()
-        self._txn = None
-        self._abort(self.propertyStore)
-        self.assertEquals(self.propertyStore[pname], pval2)
+        b = self._txn.commit().addCallback(tiebreaker('b'))
+        del self._txn
+        self.assertEquals((yield gatherResults([a, b])), [None, None])
+        yield self._abort(self.propertyStore)
+        winner = {'a': pval1,
+                  'b': pval2}[race[-1]]
+        self.assertEquals(self.propertyStore[pname], winner)
 
 
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110324/ce38a1a5/attachment-0001.html>


More information about the calendarserver-changes mailing list