[CalendarServer-changes] [5866] CalendarServer/trunk

source_changes at macosforge.org source_changes at macosforge.org
Sat Jul 10 18:24:52 PDT 2010


Revision: 5866
          http://trac.macosforge.org/projects/calendarserver/changeset/5866
Author:   cdaboo at apple.com
Date:     2010-07-10 18:24:48 -0700 (Sat, 10 Jul 2010)
Log Message:
-----------
Allow wildcard uids in augments DB.

Modified Paths:
--------------
    CalendarServer/trunk/conf/auth/augments.dtd
    CalendarServer/trunk/twistedcaldav/directory/augment.py
    CalendarServer/trunk/twistedcaldav/directory/test/augments-test-default.xml
    CalendarServer/trunk/twistedcaldav/directory/test/test_augment.py

Modified: CalendarServer/trunk/conf/auth/augments.dtd
===================================================================
--- CalendarServer/trunk/conf/auth/augments.dtd	2010-07-09 21:58:21 UTC (rev 5865)
+++ CalendarServer/trunk/conf/auth/augments.dtd	2010-07-11 01:24:48 UTC (rev 5866)
@@ -16,7 +16,7 @@
 
 <!ELEMENT augments (record*) >
 
-  <!ELEMENT record (guid, enable, hosted-at?, enable-calendar?, enable-addressbook?, auto-schedule?)>
+  <!ELEMENT record (uid, enable, hosted-at?, enable-calendar?, enable-addressbook?, auto-schedule?)>
     <!ATTLIST record repeat CDATA "1">
 
   <!ELEMENT uid                (#PCDATA)>

Modified: CalendarServer/trunk/twistedcaldav/directory/augment.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/augment.py	2010-07-09 21:58:21 UTC (rev 5865)
+++ CalendarServer/trunk/twistedcaldav/directory/augment.py	2010-07-11 01:24:48 UTC (rev 5866)
@@ -63,7 +63,8 @@
     """
     
     def __init__(self):
-        pass
+        
+        self.cachedRecords = {}
     
     @inlineCallbacks
     def getAugmentRecord(self, uid):
@@ -77,26 +78,29 @@
         """
         
         result = (yield self._lookupAugmentRecord(uid))
-        if result is None:
-            if not hasattr(self, "_defaultRecord"):
-                self._defaultRecord = (yield self._lookupAugmentRecord("Default"))
-            if self._defaultRecord is None:
-                # No default was specified in the db, so generate one
-                self._defaultRecord = AugmentRecord(
-                    "Default",
-                    enabled=True,
-                    enabledForCalendaring=True,
-                    enabledForAddressBooks=True,
-                )
+        if result is not None:
+            returnValue(result)
 
-            result = copy.deepcopy(self._defaultRecord)
-            result.uid = uid
+        # Try wildcard/default matches next
+        for lookup in ("%s*" % (uid[0:2],), "%s*" % (uid[0],), "Default"):
+            result = (yield self._cachedAugmentRecord(lookup))
+            if result is not None:
+                result = copy.deepcopy(result)
+                result.uid = uid
+                result.clonedFromDefault = True
+                returnValue(result)
 
-            # Mark default-cloned augment records as such so
-            # DirectoryRecord.addAugmentInformation( ) can avoid unneccesary
-            # error messages:
-            result.clonedFromDefault = True
-
+        # No default was specified in the db, so generate one
+        result = AugmentRecord(
+            "Default",
+            enabled=True,
+            enabledForCalendaring=True,
+            enabledForAddressBooks=True,
+        )
+        self.cachedRecords["Default"] = result
+        result = copy.deepcopy(result)
+        result.uid = uid
+        result.clonedFromDefault = True
         returnValue(result)
 
     @inlineCallbacks
@@ -121,6 +125,22 @@
         
         raise NotImplementedError("Child class must define this.")
 
+    @inlineCallbacks
+    def _cachedAugmentRecord(self, uid):
+        """
+        Get an AugmentRecord for the specified UID from the cache.
+
+        @param uid: directory UID to lookup
+        @type uid: C{str}
+        
+        @return: L{Deferred}
+        """
+        
+        if not uid in self.cachedRecords:
+            result = (yield self._lookupAugmentRecord(uid))
+            self.cachedRecords[uid] = result
+        returnValue(self.cachedRecords[uid])
+
     def addAugmentRecords(self, records):
         """
         Add an AugmentRecord to the DB.
@@ -152,6 +172,7 @@
         @return: L{Deferred}
         """
 
+        self.cachedRecords.clear()
         return succeed(None)
     
     def clean(self):
@@ -173,6 +194,7 @@
 
     def __init__(self, xmlFiles, cacheTimeout=30):
 
+        super(AugmentXMLDB, self).__init__()
         self.xmlFiles = [fullServerPath(config.DataRoot, path) for path in xmlFiles]
         self.cacheTimeout = cacheTimeout * 60 # Value is mins we want secs
         self.lastCached = 0
@@ -378,6 +400,7 @@
         """
         Refresh any cached data.
         """
+        super(AugmentXMLDB, self).refresh()
         try:
             self.db = self._parseXML()
         except RuntimeError:
@@ -431,6 +454,7 @@
     
     def __init__(self, dbID, dbapiName, dbapiArgs, **kwargs):
         
+        AugmentDB.__init__(self)
         self.cachedPartitions = {}
         self.cachedHostedAt = {}
         

Modified: CalendarServer/trunk/twistedcaldav/directory/test/augments-test-default.xml
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/augments-test-default.xml	2010-07-09 21:58:21 UTC (rev 5865)
+++ CalendarServer/trunk/twistedcaldav/directory/test/augments-test-default.xml	2010-07-11 01:24:48 UTC (rev 5866)
@@ -27,6 +27,30 @@
     <hosted-at>00001</hosted-at>
   </record>
   <record>
+    <uid>AA*</uid>
+    <enable>true</enable>
+    <hosted-at>00001</hosted-at>
+  </record>
+  <record>
+    <uid>AB*</uid>
+    <enable>false</enable>
+  </record>
+  <record>
+    <uid>B*</uid>
+    <enable>true</enable>
+    <hosted-at>00002</hosted-at>
+    <enable-calendar>true</enable-calendar>
+    <enable-addressbook>true</enable-addressbook>
+  </record>
+  <record>
+    <uid>C*</uid>
+    <enable>true</enable>
+    <hosted-at>00003</hosted-at>
+    <enable-calendar>true</enable-calendar>
+    <enable-addressbook>true</enable-addressbook>
+    <auto-schedule>true</auto-schedule>
+  </record>
+  <record>
     <uid>D11F03A0-97EA-48AF-9A6C-FAC7F3975766</uid>
     <enable>true</enable>
   </record>
@@ -60,7 +84,6 @@
     <uid>6A73326A-F781-47E7-A9F8-AF47364D4152</uid>
     <enable>true</enable>
     <hosted-at>00002</hosted-at>
-    <enable>true</enable>
     <enable-calendar>true</enable-calendar>
     <enable-addressbook>true</enable-addressbook>
     <auto-schedule>true</auto-schedule>

Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_augment.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_augment.py	2010-07-09 21:58:21 UTC (rev 5865)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_augment.py	2010-07-11 01:24:48 UTC (rev 5866)
@@ -36,8 +36,19 @@
     {"uid":"6A73326A-F781-47E7-A9F8-AF47364D4152", "enabled":True,  "hostedAt":"00002", "enabledForCalendaring":True, "enabledForAddressBooks":True, "autoSchedule":True},
 )
 
-testRecordDefault = {"uid":"A4318887-F2C7-4A70-9056-B88CC8DB26F1", "enabled":True,  "hostedAt":"00001", "enabledForCalendaring":True, "enabledForAddressBooks":True, "autoSchedule":False}
+testRecordWildcardDefault = (
+    {"uid":"A4318887-F2C7-4A70-9056-B88CC8DB26F1", "enabled":True,  "hostedAt":"00001", "enabledForCalendaring":True,  "enabledForAddressBooks":True,  "autoSchedule":False},
+    {"uid":"AA5F935F-3358-4510-A649-B391D63279F2", "enabled":True,  "hostedAt":"00001", "enabledForCalendaring":False, "enabledForAddressBooks":False, "autoSchedule":False},
+    {"uid":"ABF1A83B-1A29-4E04-BDC3-A6A66ECF27CA", "enabled":False, "hostedAt":"",      "enabledForCalendaring":False, "enabledForAddressBooks":False, "autoSchedule":False},
+    {"uid":"BC22A734-5E41-4FB7-B5C1-51DC0656DC2F", "enabled":True,  "hostedAt":"00002", "enabledForCalendaring":True,  "enabledForAddressBooks":True,  "autoSchedule":False},
+    {"uid":"C6DEEBB1-E14A-47F2-98BA-7E3BB4353E3A", "enabled":True,  "hostedAt":"00003", "enabledForCalendaring":True,  "enabledForAddressBooks":True,  "autoSchedule":True },
+    {"uid":"AA859321-2C72-4974-ADCF-0CBA0C76F95D", "enabled":True,  "hostedAt":"00001", "enabledForCalendaring":False, "enabledForAddressBooks":False, "autoSchedule":False},
+    {"uid":"AB7C488B-9ED2-4265-881C-7E2E38A63584", "enabled":False, "hostedAt":"",      "enabledForCalendaring":False, "enabledForAddressBooks":False, "autoSchedule":False},
+    {"uid":"BB0C0DA1-0545-45F6-8D08-917C554D93A4", "enabled":True,  "hostedAt":"00002", "enabledForCalendaring":True,  "enabledForAddressBooks":True,  "autoSchedule":False},
+    {"uid":"CCD30AD3-582F-4682-8B65-2EDE92C5656E", "enabled":True,  "hostedAt":"00003", "enabledForCalendaring":True,  "enabledForAddressBooks":True,  "autoSchedule":True },
+)
 
+
 testAddRecords = (
     {"uid":"D11F03A0-97EA-48AF-9A6C-FAC7F3975767", "enabled":True,  "hostedAt":"", "enabledForCalendaring":False, "enabledForAddressBooks":False, "autoSchedule":False},
 )
@@ -53,110 +64,27 @@
     def _checkRecord(self, db, items):
         
         record = (yield db.getAugmentRecord(items["uid"]))
-        self.assertTrue(record is not None)
+        self.assertTrue(record is not None, "Failed record uid: %s" % (items["uid"],))
         
         for k,v in items.iteritems():
-            self.assertEqual(getattr(record, k), v)
+            self.assertEqual(getattr(record, k), v, "Failed record uid: %s, attribute: %s" % (items["uid"], k, ))
 
     @inlineCallbacks
     def _checkRecordExists(self, db, uid):
         
         record = (yield db.getAugmentRecord(uid))
-        self.assertTrue(record is not None)
+        self.assertTrue(record is not None, "Failed record uid: %s" % (uid,))
 
-class AugmentXMLTests(AugmentTests):
+class AugmentTestsMixin(object):
 
-    @inlineCallbacks
-    def test_read(self):
-        
-        db = AugmentXMLDB((xmlFile,))
+    def _db(self, dbpath=None):
+        raise NotImplementedError
 
-        for item in testRecords:
-            yield self._checkRecord(db, item)
-
-        # Verify that a default record is returned, even if not specified
-        # in the DB
-        yield self._checkRecordExists(db, "D11F03A0-97EA-48AF-9A6C-FAC7F3975767")
-
     @inlineCallbacks
-    def test_read_default(self):
-        
-        db = AugmentXMLDB((xmlFileDefault,))
-
-        for item in testRecords:
-            yield self._checkRecord(db, item)
-
-        yield self._checkRecord(db, testRecordDefault)
-
-    def test_parseErrors(self):
-        
-        db = {}
-        self.assertRaises(RuntimeError, XMLAugmentsParser, cStringIO.StringIO(""), db)
-        self.assertRaises(RuntimeError, XMLAugmentsParser, cStringIO.StringIO("""<?xml version="1.0" encoding="utf-8"?>
-<accounts>
-    <foo/>
-</accounts>
-"""), db)
-        self.assertRaises(RuntimeError, XMLAugmentsParser, cStringIO.StringIO("""<?xml version="1.0" encoding="utf-8"?>
-<augments>
-    <foo/>
-</augments>
-"""), db)
-        self.assertRaises(RuntimeError, XMLAugmentsParser, cStringIO.StringIO("""<?xml version="1.0" encoding="utf-8"?>
-<augments>
-  <record>
-    <enable>true</enable>
-  </record>
-</augments>
-"""), db)
-        self.assertRaises(RuntimeError, XMLAugmentsParser, cStringIO.StringIO("""<?xml version="1.0" encoding="utf-8"?>
-  <record>
-    <uid>admin</uid>
-    <enable>true</enable>
-    <foo/>
-  </record>
-"""), db)
-
-    @inlineCallbacks
-    def test_add_modify(self):
-        
-        # Duplicate file as we will change it
-        newxmlfile = FilePath(self.mktemp())
-        FilePath(xmlFile).copyTo(newxmlfile)
-        
-        db = AugmentXMLDB((newxmlfile.path,))
-
-        for item in testRecords:
-            yield self._checkRecord(db, item)
-
-        newrecord = AugmentRecord(
-            **testAddRecords[0]
-        )
-        yield db.addAugmentRecords((newrecord,))
-
-        newdb = AugmentXMLDB((newxmlfile.path,))
-
-        for item in testRecords:
-            yield self._checkRecord(newdb, item)
-        yield self._checkRecord(newdb, testAddRecords[0])
-
-        newrecord = AugmentRecord(
-            **testModifyRecords[0]
-        )
-        yield db.addAugmentRecords((newrecord,))
-
-        newdb = AugmentXMLDB((newxmlfile.path,))
-
-        for item in testRecords:
-            yield self._checkRecord(newdb, item)
-        yield self._checkRecord(newdb, testModifyRecords[0])
-
-class AugmentSqliteTests(AugmentTests):
-
-    @inlineCallbacks
     def test_read(self):
         
-        db = AugmentSqliteDB(os.path.abspath(self.mktemp()))
+        dbpath = os.path.abspath(self.mktemp())
+        db = self._db(dbpath)
 
         dbxml = AugmentXMLDB((xmlFile,))
         yield db.addAugmentRecords(dbxml.db.values())
@@ -171,7 +99,8 @@
     @inlineCallbacks
     def test_read_default(self):
         
-        db = AugmentSqliteDB(os.path.abspath(self.mktemp()))
+        dbpath = os.path.abspath(self.mktemp())
+        db = self._db(dbpath)
 
         dbxml = AugmentXMLDB((xmlFileDefault,))
         yield db.addAugmentRecords(dbxml.db.values())
@@ -179,13 +108,18 @@
         for item in testRecords:
             yield self._checkRecord(db, item)
 
-        yield self._checkRecord(db, testRecordDefault)
+        for item in testRecordWildcardDefault:
+            yield self._checkRecord(db, item)
 
+        # Do a second time to test caching
+        for item in testRecordWildcardDefault:
+            yield self._checkRecord(db, item)
+
     @inlineCallbacks
     def test_add_modify(self):
         
         dbpath = os.path.abspath(self.mktemp())
-        db = AugmentSqliteDB(dbpath)
+        db = self._db(dbpath)
 
         dbxml = AugmentXMLDB((xmlFile,))
         yield db.addAugmentRecords(dbxml.db.values())
@@ -202,7 +136,7 @@
         )
         yield db.addAugmentRecords((newrecord,))
 
-        newdb = AugmentSqliteDB(dbpath)
+        newdb = self._db(dbpath)
 
         for item in testRecords:
             yield self._checkRecord(newdb, item)
@@ -213,23 +147,19 @@
         )
         yield db.addAugmentRecords((newrecord,))
 
-        newdb = AugmentSqliteDB(dbpath)
+        newdb = self._db(dbpath)
 
         for item in testRecords:
             yield self._checkRecord(newdb, item)
         yield self._checkRecord(newdb, testModifyRecords[0])
 
-class AugmentPostgreSQLTests(AugmentTests):
+class AugmentXMLTests(AugmentTests):
 
     @inlineCallbacks
     def test_read(self):
         
-        db = AugmentPostgreSQLDB("localhost", "augments")
-        yield db.clean()
+        db = AugmentXMLDB((xmlFile,))
 
-        dbxml = AugmentXMLDB((xmlFile,))
-        yield db.addAugmentRecords(dbxml.db.values())
-
         for item in testRecords:
             yield self._checkRecord(db, item)
 
@@ -240,39 +170,61 @@
     @inlineCallbacks
     def test_read_default(self):
         
-        db = AugmentPostgreSQLDB("localhost", "augments")
-        yield db.clean()
+        db = AugmentXMLDB((xmlFileDefault,))
 
-        dbxml = AugmentXMLDB((xmlFileDefault,))
-        yield db.addAugmentRecords(dbxml.db.values())
-
         for item in testRecords:
             yield self._checkRecord(db, item)
 
-        yield self._checkRecord(db, testRecordDefault)
+        for item in testRecordWildcardDefault:
+            yield self._checkRecord(db, item)
 
+    def test_parseErrors(self):
+        
+        db = {}
+        self.assertRaises(RuntimeError, XMLAugmentsParser, cStringIO.StringIO(""), db)
+        self.assertRaises(RuntimeError, XMLAugmentsParser, cStringIO.StringIO("""<?xml version="1.0" encoding="utf-8"?>
+<accounts>
+    <foo/>
+</accounts>
+"""), db)
+        self.assertRaises(RuntimeError, XMLAugmentsParser, cStringIO.StringIO("""<?xml version="1.0" encoding="utf-8"?>
+<augments>
+    <foo/>
+</augments>
+"""), db)
+        self.assertRaises(RuntimeError, XMLAugmentsParser, cStringIO.StringIO("""<?xml version="1.0" encoding="utf-8"?>
+<augments>
+  <record>
+    <enable>true</enable>
+  </record>
+</augments>
+"""), db)
+        self.assertRaises(RuntimeError, XMLAugmentsParser, cStringIO.StringIO("""<?xml version="1.0" encoding="utf-8"?>
+  <record>
+    <uid>admin</uid>
+    <enable>true</enable>
+    <foo/>
+  </record>
+"""), db)
+
     @inlineCallbacks
     def test_add_modify(self):
         
-        db = AugmentPostgreSQLDB("localhost", "augments")
-        yield db.clean()
+        # Duplicate file as we will change it
+        newxmlfile = FilePath(self.mktemp())
+        FilePath(xmlFile).copyTo(newxmlfile)
+        
+        db = AugmentXMLDB((newxmlfile.path,))
 
-        dbxml = AugmentXMLDB((xmlFile,))
-        yield db.addAugmentRecords(dbxml.db.values())
-
         for item in testRecords:
             yield self._checkRecord(db, item)
 
-        # Verify that a default record is returned, even if not specified
-        # in the DB
-        yield self._checkRecordExists(db, "D11F03A0-97EA-48AF-9A6C-FAC7F3975767")
-
         newrecord = AugmentRecord(
             **testAddRecords[0]
         )
         yield db.addAugmentRecords((newrecord,))
 
-        newdb = AugmentPostgreSQLDB("localhost", "augments")
+        newdb = AugmentXMLDB((newxmlfile.path,))
 
         for item in testRecords:
             yield self._checkRecord(newdb, item)
@@ -283,12 +235,22 @@
         )
         yield db.addAugmentRecords((newrecord,))
 
-        newdb = AugmentPostgreSQLDB("localhost", "augments")
+        newdb = AugmentXMLDB((newxmlfile.path,))
 
         for item in testRecords:
             yield self._checkRecord(newdb, item)
         yield self._checkRecord(newdb, testModifyRecords[0])
 
+class AugmentSqliteTests(AugmentTests, AugmentTestsMixin):
+
+    def _db(self, dbpath=None):
+        return AugmentSqliteDB(dbpath if dbpath else os.path.abspath(self.mktemp()))
+
+class AugmentPostgreSQLTests(AugmentTests, AugmentTestsMixin):
+
+    def _db(self, dbpath=None):
+        return AugmentPostgreSQLDB("localhost", "augments")
+
 try:
     import pgdb
 except ImportError:
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100710/8ed8524d/attachment-0001.html>


More information about the calendarserver-changes mailing list