[CalendarServer-changes] [10580] CalendarServer/branches/users/glyph/unshare-when-access-revoked

source_changes at macosforge.org source_changes at macosforge.org
Mon Jan 28 19:29:03 PST 2013


Revision: 10580
          http://trac.calendarserver.org//changeset/10580
Author:   glyph at apple.com
Date:     2013-01-28 19:29:03 -0800 (Mon, 28 Jan 2013)
Log Message:
-----------
Move most of the responsibility for creating and maintaining state associated with directory services into a dedicated, isolated fixture class that isn't mixed in with the rest of the resource-traversal objects.

Modified Paths:
--------------
    CalendarServer/branches/users/glyph/unshare-when-access-revoked/twistedcaldav/test/util.py

Property Changed:
----------------
    CalendarServer/branches/users/glyph/unshare-when-access-revoked/

Modified: CalendarServer/branches/users/glyph/unshare-when-access-revoked/twistedcaldav/test/util.py
===================================================================
--- CalendarServer/branches/users/glyph/unshare-when-access-revoked/twistedcaldav/test/util.py	2013-01-29 03:29:02 UTC (rev 10579)
+++ CalendarServer/branches/users/glyph/unshare-when-access-revoked/twistedcaldav/test/util.py	2013-01-29 03:29:03 UTC (rev 10580)
@@ -37,9 +37,12 @@
 from twistedcaldav.config import config
 from twistedcaldav.directory import augment
 from twistedcaldav.directory.addressbook import DirectoryAddressBookHomeProvisioningResource
-from twistedcaldav.directory.calendar import DirectoryCalendarHomeProvisioningResource
+from twistedcaldav.directory.calendar import (
+    DirectoryCalendarHomeProvisioningResource
+)
 from twistedcaldav.directory.principal import (
     DirectoryPrincipalProvisioningResource)
+from twistedcaldav.directory.aggregate import AggregateDirectoryService
 from twistedcaldav.directory.xmlfile import XMLDirectoryService
 
 from txdav.common.datastore.test.util import deriveQuota
@@ -74,33 +77,81 @@
 
 
 
-class TestCase(twext.web2.dav.test.util.TestCase):
-    resource_class = RootResource
+class DirectoryFixture(object):
+    """
+    Test fixture for creating various parts of the resource hierarchy related
+    to directories.
+    """
 
-    def createStockDirectoryService(self):
+    def __init__(self):
+        def _setUpPrincipals(ds):
+            # FIXME: see FIXME in
+            # DirectoryPrincipalProvisioningResource.__init__; this performs a
+            # necessary modification to any directory service object for it to
+            # be fully functional.
+            self.principalsResource = DirectoryPrincipalProvisioningResource(
+                "/principals/", ds
+            )
+        self._directoryChangeHooks = [_setUpPrincipals]
+
+
+    directoryService = None
+    principalsResource = None
+
+    def addDirectoryService(self, newService):
         """
-        Create a stock C{directoryService} attribute and assign it.
+        Add an L{IDirectoryService} to this test case.
+
+        If this test case does not have a directory service yet, create it and
+        assign C{directoryService} and C{principalsResource} attributes to this
+        test case.
+
+        If the test case already has a directory service, create an
+        L{AggregateDirectoryService} and re-assign the C{self.directoryService}
+        attribute to point at it instead, while setting the C{realmName} of the
+        new service to match the old one.
+
+        If the test already has an L{AggregateDirectoryService}, create a
+        I{new} L{AggregateDirectoryService} with the same list of services,
+        after adjusting the new service's realm to match the existing ones.
         """
-        self.xmlFile = FilePath(config.DataRoot).child("accounts.xml")
-        self.xmlFile.setContent(xmlFile.getContent())
 
+        if self.directoryService is None:
+            directoryService = newService
+        else:
+            newService.realmName = self.directoryService.realmName
+            if isinstance(self.directoryService, AggregateDirectoryService):
+                directories = set(self.directoryService._recordTypes.items())
+                directories.add(newService)
+            else:
+                directories = [newService, self.directoryService]
+            directoryService = AggregateDirectoryService(directories, None)
 
-        self.directoryService = XMLDirectoryService(
-            {
-                "xmlFile" : "accounts.xml",
-                "augmentService" :
-                    augment.AugmentXMLDB( xmlFiles=(augmentsFile.path,)),
-            }
-        )
-
+        self.directoryService = directoryService
         # FIXME: see FIXME in DirectoryPrincipalProvisioningResource.__init__;
-        # this performs a necessary modification to the directory service
-        # object for it to be fully functional.
-        self.principalsResource = DirectoryPrincipalProvisioningResource(
-            "/principals/", self.directoryService
-        )
+        # this performs a necessary modification to the directory service object
+        # for it to be fully functional.
+        for hook in self._directoryChangeHooks:
+            hook(directoryService)
 
 
+    def whenDirectoryServiceChanges(self, callback):
+        """
+        When the C{directoryService} attribute is changed by
+        L{TestCase.addDirectoryService}, call the given callback in order to
+        update any state which relies upon that service.
+
+        If there's already a directory, invoke the callback immediately.
+        """
+        self._directoryChangeHooks.append(callback)
+        if self.directoryService is not None:
+            callback(self.directoryService)
+
+
+
+class TestCase(twext.web2.dav.test.util.TestCase):
+    resource_class = RootResource
+
     def createDataStore(self):
         """
         Create an L{IDataStore} that can store calendars (but not
@@ -111,32 +162,42 @@
                                quota=deriveQuota(self))
 
 
+    def createStockDirectoryService(self):
+        """
+        Create a stock C{directoryService} attribute and assign it.
+        """
+        self.xmlFile = FilePath(config.DataRoot).child("accounts.xml")
+        self.xmlFile.setContent(xmlFile.getContent())
+        self.directoryFixture.addDirectoryService(XMLDirectoryService({
+            "xmlFile": "accounts.xml",
+            "augmentService":
+                augment.AugmentXMLDB(xmlFiles=(augmentsFile.path,)),
+        }))
+
+
     def setupCalendars(self):
         """
         Set up the resource at /calendars (a
         L{DirectoryCalendarHomeProvisioningResource}), and assign it as
         C{self.calendarCollection}.
         """
+        newStore = self.createDataStore()
+        def putAllChildren(ds):
+            self.calendarCollection = (
+                DirectoryCalendarHomeProvisioningResource(
+                    ds, "/calendars/", newStore
+                ))
+            self.site.resource.putChild("calendars",
+                                        self.calendarCollection)
+            self.addressbookCollection = (
+                DirectoryAddressBookHomeProvisioningResource(
+                    ds, "/addressbooks/", newStore
+                ))
+            self.site.resource.putChild("addressbooks",
+                                        self.addressbookCollection)
+        self.directoryFixture.whenDirectoryServiceChanges(putAllChildren)
 
-        # Need a data store
-        self._newStore = self.createDataStore()
 
-        self.calendarCollection = DirectoryCalendarHomeProvisioningResource(
-            self.directoryService,
-            "/calendars/",
-            self._newStore
-        )
-        self.site.resource.putChild("calendars", self.calendarCollection)
-
-        self.addressbookCollection = DirectoryAddressBookHomeProvisioningResource(
-            self.directoryService,
-            "/addressbooks/",
-            self._newStore
-        )
-        self.site.resource.putChild("addressbooks", self.addressbookCollection)
-
-
-
     def configure(self):
         """
         Adjust the global configuration for this test.
@@ -156,9 +217,28 @@
         config.DirectoryAddressBook.Enabled = False
 
 
+    @property
+    def directoryService(self):
+        """
+        Read-only alias for L{DirectoryFixture.directoryService} for
+        compatibility with older tests.  TODO: remove this.
+        """
+        return self.directoryFixture.directoryService
+
+
+    @property
+    def principalsResource(self):
+        """
+        Read-only alias for L{DirectoryFixture.principalsResource} for
+        compatibility with older tests.  TODO: remove this.
+        """
+
+
     def setUp(self):
         super(TestCase, self).setUp()
 
+        self.directoryFixture = DirectoryFixture()
+
         # FIXME: this is only here to workaround circular imports
         doBind()
 
@@ -177,7 +257,6 @@
             os.makedirs(config.LogRoot)
 
 
-
     def createHierarchy(self, structure, root=None):
         if root is None:
             root = os.path.abspath(self.mktemp())
@@ -217,6 +296,7 @@
         createChildren(root, structure)
         return root
 
+
     def verifyHierarchy(self, root, structure):
 
         def verifyChildren(parent, subStructure):
@@ -356,17 +436,13 @@
         that stores the data for that L{CalendarHomeResource}.
         """
         super(HomeTestCase, self).setUp()
-
         self.createStockDirectoryService()
+        @self.directoryFixture.whenDirectoryServiceChanges
+        def addHomeProvisioner(ds):
+            self.homeProvisioner = DirectoryCalendarHomeProvisioningResource(
+                ds, "/calendars/", self.createDataStore()
+            )
 
-        # Need a data store
-        _newStore = self.createDataStore()
-
-        self.homeProvisioner = DirectoryCalendarHomeProvisioningResource(
-            self.directoryService, "/calendars/",
-            _newStore
-        )
-
         def _defer(user):
             # Commit the transaction
             self.addCleanup(self.noRenderCommit)
@@ -445,20 +521,13 @@
         file.
         """
         super(AddressBookHomeTestCase, self).setUp()
-
-        fp = FilePath(self.mktemp())
-        fp.createDirectory()
-
         self.createStockDirectoryService()
+        @self.directoryFixture.whenDirectoryServiceChanges
+        def addHomeProvisioner(ds):
+            self.homeProvisioner = DirectoryAddressBookHomeProvisioningResource(
+                ds, "/calendars/", self.createDataStore()
+            )
 
-        # Need a data store
-        _newStore = CommonDataStore(fp, None, True, False)
-
-        self.homeProvisioner = DirectoryAddressBookHomeProvisioningResource(
-            self.directoryService, "/addressbooks/",
-            _newStore
-        )
-
         @inlineCallbacks
         def _defer(user):
             # Commit the transaction
@@ -467,6 +536,7 @@
 
         return self._refreshRoot().addCallback(_defer)
 
+
     @inlineCallbacks
     def _refreshRoot(self):
         """
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20130128/be25793d/attachment-0001.html>


More information about the calendarserver-changes mailing list