[CalendarServer-changes] [9317] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Wed May 30 17:06:04 PDT 2012


Revision: 9317
          http://trac.macosforge.org/projects/calendarserver/changeset/9317
Author:   glyph at apple.com
Date:     2012-05-30 17:06:04 -0700 (Wed, 30 May 2012)
Log Message:
-----------
Test and fix for UUID normalization when there is no de-normalized duplicate.

Modified Paths:
--------------
    CalendarServer/trunk/txdav/common/datastore/sql.py
    CalendarServer/trunk/txdav/common/datastore/test/test_sql.py

Property Changed:
----------------
    CalendarServer/trunk/

Modified: CalendarServer/trunk/txdav/common/datastore/sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/sql.py	2012-05-30 20:37:14 UTC (rev 9316)
+++ CalendarServer/trunk/txdav/common/datastore/sql.py	2012-05-31 00:06:04 UTC (rev 9317)
@@ -4045,25 +4045,48 @@
     both.append([other,
                  (yield determineNewest(other.uid(), homeType).on(sqlTxn))])
     both.sort(key=lambda x: x[1])
-    # Note: determineNewest may return None sometimes.
+
     older = both[0][0]
     newer = both[1][0]
     yield migrateHome(older, newer, merge=True)
     # Rename the old one to 'old.<correct-guid>'
     newNormalized = normalizeUUIDOrNot(newer.uid())
     oldNormalized = normalizeUUIDOrNot(older.uid())
-    yield Update({homeTable.OWNER_UID: "old." + oldNormalized},
-                 Where=homeTable.OWNER_UID == older.uid()).on(sqlTxn)
+    yield _renameHome(sqlTxn, homeTable, older.uid(), "old." + oldNormalized)
     # Rename the new one to '<correct-guid>'
     if newer.uid() != newNormalized:
-        yield Update(
-            {homeTable.OWNER_UID: newNormalized},
-            Where=homeTable.OWNER_UID == newer.uid()
-        ).on(sqlTxn)
+        yield _renameHome(sqlTxn, homeTable, newer.uid(), newNormalized)
     yield returnValue(newer)
 
 
 
+def _renameHome(txn, table, oldUID, newUID):
+    """
+    Rename a calendar, addressbook, or notification home.  Note that this
+    function is only safe in transactions that have had caching disabled, and
+    more specifically should only ever be used during upgrades.  Running this
+    in a normal transaction will have unpredictable consequences, especially
+    with respect to memcache.
+
+    @param txn: an SQL transaction to use for this update
+    @type txn: L{twext.enterprise.ienterprise.IAsyncTransaction}
+
+    @param table: the storage table of the desired home type
+    @type table: L{TableSyntax}
+
+    @param oldUID: the old UID, the existing home's UID
+    @type oldUID: L{str}
+
+    @param newUID: the new UID, to change the UID to
+    @type newUID: L{str}
+
+    @return: a L{Deferred} which fires when the home is renamed.
+    """
+    return Update({table.OWNER_UID: newUID},
+                  Where=table.OWNER_UID == oldUID).on(txn)
+
+
+
 def _dontBotherWithNotifications(older, newer, merge):
     """
     Notifications are more transient and can be easily worked around; don't
@@ -4137,13 +4160,15 @@
                         "[%(homeType)s]",
                         uid=UID, newuid=newname, homeType=homeTypeName)
                 other = yield t.homeWithUID(homeType, newname)
-                if homeType == ECALENDARTYPE:
-                    fixedOtherHome = yield fixOneCalendarHome(other)
-                if other is not None:
+                if other is None:
+                    # No duplicate: just fix the name.
+                    yield _renameHome(t, homeTable, UID, newname)
+                else:
+                    if homeType == ECALENDARTYPE:
+                        fixedOtherHome = yield fixOneCalendarHome(other)
                     this = yield mergeHomes(t, this, other, homeType)
-                    # NOTE: WE MUST NOT TOUCH EITHER HOME OBJECT AFTER THIS
-                    # POINT. THE UIDS HAVE CHANGED AND ALL OPERATIONS WILL
-                    # FAIL.
+                # NOTE: WE MUST NOT TOUCH EITHER HOME OBJECT AFTER THIS POINT.
+                # THE UIDS HAVE CHANGED AND ALL OPERATIONS WILL FAIL.
 
         end = time.time()
         elapsed = end - start

Modified: CalendarServer/trunk/txdav/common/datastore/test/test_sql.py
===================================================================
--- CalendarServer/trunk/txdav/common/datastore/test/test_sql.py	2012-05-30 20:37:14 UTC (rev 9316)
+++ CalendarServer/trunk/txdav/common/datastore/test/test_sql.py	2012-05-31 00:06:04 UTC (rev 9317)
@@ -21,7 +21,7 @@
 from twext.enterprise.dal.syntax import Select
 from txdav.xml import element as davxml
 
-from twisted.internet.defer import inlineCallbacks
+from twisted.internet.defer import inlineCallbacks, returnValue
 from twisted.internet.task import Clock
 from twisted.trial.unittest import TestCase
 
@@ -32,6 +32,7 @@
 from txdav.common.datastore.test.util import CommonCommonTests, buildStore
 from txdav.common.icommondatastore import AllRetriesFailed
 from twext.enterprise.dal.syntax import Insert
+from txdav.common.datastore.sql import fixUUIDNormalization
 
 class CommonSQLStoreTests(CommonCommonTests, TestCase):
     """
@@ -335,3 +336,36 @@
              [2, "fdsa", "another-value",
               "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA"]]
         )
+
+
+    @inlineCallbacks
+    def allHomeUIDs(self):
+        """
+        Get a listing of all UIDs in the current store.
+        """
+        results = yield Select(
+            [schema.CALENDAR_HOME.OWNER_UID],
+            From=schema.CALENDAR_HOME).on(self.transactionUnderTest())
+        yield self.commit()
+        returnValue(results)
+
+
+    @inlineCallbacks
+    def test_fixUUIDNormalization_lowerToUpper(self):
+        """
+        L{fixUUIDNormalization} will fix the normalization of UUIDs.  If a home
+        is found with the wrong case but no duplicate, it will simply be
+        upper-cased.
+        """
+        t1 = self.transactionUnderTest()
+        yield t1.calendarHomeWithUID(denormalizedUID, create=True)
+        yield self.commit()
+        yield fixUUIDNormalization(self.storeUnderTest())
+        self.assertEqual((yield self.allHomeUIDs()), [[normalizedUID]])
+
+
+from uuid import UUID
+exampleUID = UUID("a"*32)
+denormalizedUID = str(exampleUID)
+normalizedUID = denormalizedUID.upper()
+
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120530/0bd8662b/attachment-0001.html>


More information about the calendarserver-changes mailing list