예제 #1
0
    def delete(self, paths):
        """See L{NamespaceAPI.delete}.

        Permissions for deleted L{Namespace}s are removed from the cache.
        """
        if isgenerator(paths):
            paths = list(paths)
        cache = PermissionCache()
        cache.clearNamespacePermissions(paths)
        return self._api.delete(paths)
예제 #2
0
    def delete(self, paths):
        """See L{NamespaceAPI.delete}.

        Permissions for deleted L{Namespace}s are removed from the cache.
        """
        if isgenerator(paths):
            paths = list(paths)
        cache = PermissionCache()
        cache.clearNamespacePermissions(paths)
        return self._api.delete(paths)
예제 #3
0
 def testSetInvalidatesCachedNamespacePermissions(self):
     """
     L{CachingPermissionAPI.set} invalidates L{NamespacePermission}s to
     ensure the cache is always fresh.
     """
     cache = PermissionCache()
     cache.saveNamespacePermissions(
         {u'username': self.user.namespace.permission})
     self.permissions.set([(u'username', Operation.CREATE_NAMESPACE,
                            Policy.OPEN, [])])
     cached = cache.getNamespacePermissions([u'username'])
     self.assertEqual({}, cached.results)
     self.assertEqual([u'username'], cached.uncachedValues)
예제 #4
0
 def testSetInvalidatesCachedNamespacePermissions(self):
     """
     L{CachingPermissionAPI.set} invalidates L{NamespacePermission}s to
     ensure the cache is always fresh.
     """
     cache = PermissionCache()
     cache.saveNamespacePermissions(
         {u'username': self.user.namespace.permission})
     self.permissions.set([
         (u'username', Operation.CREATE_NAMESPACE, Policy.OPEN, [])])
     cached = cache.getNamespacePermissions([u'username'])
     self.assertEqual({}, cached.results)
     self.assertEqual([u'username'], cached.uncachedValues)
예제 #5
0
    def testDeleteInvalidatesCachedTagPermissions(self):
        """
        L{CachingTagAPI.delete} invalidates L{TagPermission}s to ensure the
        cache is always fresh.
        """
        self.tags.create([(u'username/tag', u'A tag')])
        tag = getTags(paths=[u'username/tag']).one()
        cache = PermissionCache()
        cache.saveTagPermissions({u'username/tag': tag.permission})

        self.tags.delete([u'username/tag'])
        cached = cache.getTagPermissions([u'username/tag'])
        self.assertEqual({}, cached.results)
        self.assertEqual([u'username/tag'], cached.uncachedValues)
예제 #6
0
 def testSetInvalidatesCachedTagPermissions(self):
     """
     L{CachingPermissionAPI.set} invalidates L{TagPermission}s to ensure
     the cache is always fresh.
     """
     TagAPI(self.user).create([(u'username/tag', u'A tag')])
     _, permission = getTagPermissions(paths=[u'username/tag']).one()
     cache = PermissionCache()
     cache.saveTagPermissions({u'username/tag': permission})
     self.permissions.set([(u'username/tag', Operation.UPDATE_TAG,
                            Policy.OPEN, [])])
     cached = cache.getTagPermissions([u'username/tag'])
     self.assertEqual({}, cached.results)
     self.assertEqual([u'username/tag'], cached.uncachedValues)
예제 #7
0
파일: test_tag.py 프로젝트: xanixon/fluiddb
    def testDeleteInvalidatesCachedTagPermissions(self):
        """
        L{CachingTagAPI.delete} invalidates L{TagPermission}s to ensure the
        cache is always fresh.
        """
        self.tags.create([(u'username/tag', u'A tag')])
        tag = getTags(paths=[u'username/tag']).one()
        cache = PermissionCache()
        cache.saveTagPermissions({u'username/tag': tag.permission})

        self.tags.delete([u'username/tag'])
        cached = cache.getTagPermissions([u'username/tag'])
        self.assertEqual({}, cached.results)
        self.assertEqual([u'username/tag'], cached.uncachedValues)
예제 #8
0
 def testSetInvalidatesCachedTagPermissions(self):
     """
     L{CachingPermissionAPI.set} invalidates L{TagPermission}s to ensure
     the cache is always fresh.
     """
     TagAPI(self.user).create([(u'username/tag', u'A tag')])
     _, permission = getTagPermissions(paths=[u'username/tag']).one()
     cache = PermissionCache()
     cache.saveTagPermissions({u'username/tag': permission})
     self.permissions.set([
         (u'username/tag', Operation.UPDATE_TAG, Policy.OPEN, [])])
     cached = cache.getTagPermissions([u'username/tag'])
     self.assertEqual({}, cached.results)
     self.assertEqual([u'username/tag'], cached.uncachedValues)
예제 #9
0
    def testDeleteInvalidatesCachedNamespacePermissions(self):
        """
        L{CachingNamespaceAPI.delete} invalidates L{NamespacePermission}s to
        ensure the cache is always fresh.
        """
        self.namespaces.create([(u'username/namespace', u'A namespace')])
        namespace = getNamespaces(paths=[u'username/namespace']).one()
        cache = PermissionCache()
        cache.saveNamespacePermissions(
            {u'username/namespace': namespace.permission})

        self.namespaces.delete([u'username/namespace'])
        cached = cache.getNamespacePermissions([u'username/namespace'])
        self.assertEqual({}, cached.results)
        self.assertEqual([u'username/namespace'], cached.uncachedValues)
예제 #10
0
파일: tag.py 프로젝트: xanixon/fluiddb
    def delete(self, paths):
        """See L{TagAPI.delete}.

        Permissions for deleted L{Tag}s are removed from the cache.
        """
        if isgenerator(paths):
            paths = list(paths)
        # FIXME getObjectIDs is called twice--once here and once in
        # TagAPI.delete.  It would be better if we only did this once, not to
        # mention that this breaks encapsulation by bypassing the model layer
        # and accessing the data layer directly. -jkakar
        objectIDs = set(getObjectIDs(paths))
        RecentObjectActivityCache().clear(objectIDs)
        usernames = set([path.split('/')[0] for path in paths])
        RecentUserActivityCache().clear(usernames)
        PermissionCache().clearTagPermissions(paths)
        return self._api.delete(paths)
예제 #11
0
 def setUp(self):
     super(PermissionCacheTest, self).setUp()
     self.permissionCache = PermissionCache()
예제 #12
0
class PermissionCacheTest(FluidinfoTestCase):

    resources = [('cache', CacheResource()), ('config', ConfigResource()),
                 ('log', LoggingResource(format='%(message)s'))]

    def setUp(self):
        super(PermissionCacheTest, self).setUp()
        self.permissionCache = PermissionCache()

    def setList(self, name, values):
        """Small helper method to put a C{list} in the cache."""
        for item in values:
            self.cache.rpush(name, item)

    def testGetTagPermissions(self):
        """
        L{PermissionCache.getTagPermissions} returns L{TagPermission}s stored
        in the cache.
        """
        permissionDict = {
            Operation.UPDATE_TAG.id: [Policy.OPEN.id, [1, 2, 3]],
            Operation.DELETE_TAG.id: [Policy.CLOSED.id, [4, 5, 6]],
            Operation.CONTROL_TAG.id: [Policy.OPEN.id, [7, 8, 9]],
            Operation.WRITE_TAG_VALUE.id: [Policy.CLOSED.id, [10, 11, 12]],
            Operation.READ_TAG_VALUE.id: [Policy.OPEN.id, [13, 14, 15]],
            Operation.DELETE_TAG_VALUE.id: [Policy.CLOSED.id, [16, 17, 18]],
            Operation.CONTROL_TAG_VALUE.id: [Policy.OPEN.id, [19, 20, 21]]
        }
        self.cache.set('permission:tag:test/tag1', json.dumps(permissionDict))

        permissionDict = {
            Operation.UPDATE_TAG.id: [Policy.CLOSED.id, [10, 15, 20]],
            Operation.DELETE_TAG.id: [Policy.OPEN.id, [25, 30, 35]],
            Operation.CONTROL_TAG.id: [Policy.CLOSED.id, [40, 45, 50]],
            Operation.WRITE_TAG_VALUE.id: [Policy.OPEN.id, [55, 60, 65]],
            Operation.READ_TAG_VALUE.id: [Policy.CLOSED.id, [70, 75, 80]],
            Operation.DELETE_TAG_VALUE.id: [Policy.OPEN.id, [85, 90, 95]],
            Operation.CONTROL_TAG_VALUE.id:
            [Policy.CLOSED.id, [100, 105, 110]]
        }
        self.cache.set('permission:tag:test/tag2', json.dumps(permissionDict))

        result = self.permissionCache.getTagPermissions(
            [u'test/tag1', u'test/tag2'])
        self.assertEqual([], result.uncachedValues)
        permission1 = result.results[u'test/tag1']
        self.assertEqual((Policy.OPEN, [1, 2, 3]),
                         permission1.get(Operation.UPDATE_TAG))
        self.assertEqual((Policy.CLOSED, [4, 5, 6]),
                         permission1.get(Operation.DELETE_TAG))
        self.assertEqual((Policy.OPEN, [7, 8, 9]),
                         permission1.get(Operation.CONTROL_TAG))
        self.assertEqual((Policy.CLOSED, [10, 11, 12]),
                         permission1.get(Operation.WRITE_TAG_VALUE))
        self.assertEqual((Policy.OPEN, [13, 14, 15]),
                         permission1.get(Operation.READ_TAG_VALUE))
        self.assertEqual((Policy.CLOSED, [16, 17, 18]),
                         permission1.get(Operation.DELETE_TAG_VALUE))
        self.assertEqual((Policy.OPEN, [19, 20, 21]),
                         permission1.get(Operation.CONTROL_TAG_VALUE))

        permission2 = result.results[u'test/tag2']
        self.assertEqual((Policy.CLOSED, [10, 15, 20]),
                         permission2.get(Operation.UPDATE_TAG))
        self.assertEqual((Policy.OPEN, [25, 30, 35]),
                         permission2.get(Operation.DELETE_TAG))
        self.assertEqual((Policy.CLOSED, [40, 45, 50]),
                         permission2.get(Operation.CONTROL_TAG))
        self.assertEqual((Policy.OPEN, [55, 60, 65]),
                         permission2.get(Operation.WRITE_TAG_VALUE))
        self.assertEqual((Policy.CLOSED, [70, 75, 80]),
                         permission2.get(Operation.READ_TAG_VALUE))
        self.assertEqual((Policy.OPEN, [85, 90, 95]),
                         permission2.get(Operation.DELETE_TAG_VALUE))
        self.assertEqual((Policy.CLOSED, [100, 105, 110]),
                         permission2.get(Operation.CONTROL_TAG_VALUE))

    def testGetTagPermissionsReturnsUncachedValues(self):
        """
        L{PermissionCache.getTagPermissions} returns the paths of
        L{TagPermission}s not found in the cache.
        """
        permissionDict = {
            Operation.UPDATE_TAG.id: [Policy.OPEN.id, [1, 2, 3]],
            Operation.DELETE_TAG.id: [Policy.CLOSED.id, [4, 5, 6]],
            Operation.CONTROL_TAG.id: [Policy.OPEN.id, [7, 8, 9]],
            Operation.WRITE_TAG_VALUE.id: [Policy.CLOSED.id, [10, 11, 12]],
            Operation.READ_TAG_VALUE.id: [Policy.OPEN.id, [13, 14, 15]],
            Operation.DELETE_TAG_VALUE.id: [Policy.CLOSED.id, [16, 17, 18]],
            Operation.CONTROL_TAG_VALUE.id: [Policy.OPEN.id, [19, 20, 21]]
        }
        self.cache.set('permission:tag:test/tag1', json.dumps(permissionDict))

        result = self.permissionCache.getTagPermissions(
            [u'test/tag1', u'test/tag2'])

        self.assertEqual([u'test/tag2'], result.uncachedValues)
        self.assertIn(u'test/tag1', result.results)

    def testGetTagPermissionsWithEmptyPaths(self):
        """
        L{PermissionCache.getTagPermissions} returns an empty L{CacheResult}
        if no paths are provided.
        """
        cached = self.permissionCache.getTagPermissions([])
        self.assertEqual({}, cached.results)
        self.assertEqual([], cached.uncachedValues)

    def testGetNamespacePermissions(self):
        """
        L{PermissionCache.getNamespacePermissions} returns
        L{NamespacePermission}s stored in the cache.
        """
        permissionDict = {
            Operation.CREATE_NAMESPACE.id: [Policy.OPEN.id, [1, 2, 3]],
            Operation.UPDATE_NAMESPACE.id: [Policy.CLOSED.id, [4, 5, 6]],
            Operation.DELETE_NAMESPACE.id: [Policy.OPEN.id, [7, 8, 9]],
            Operation.LIST_NAMESPACE.id: [Policy.CLOSED.id, [10, 11, 12]],
            Operation.CONTROL_NAMESPACE.id: [Policy.OPEN.id, [13, 14, 15]],
        }
        self.cache.set('permission:namespace:test/namespace1',
                       json.dumps(permissionDict))

        permissionDict = {
            Operation.CREATE_NAMESPACE.id: [Policy.CLOSED.id, [5, 10, 15]],
            Operation.UPDATE_NAMESPACE.id: [Policy.OPEN.id, [20, 25, 30]],
            Operation.DELETE_NAMESPACE.id: [Policy.CLOSED.id, [35, 40, 45]],
            Operation.LIST_NAMESPACE.id: [Policy.OPEN.id, [50, 55, 60]],
            Operation.CONTROL_NAMESPACE.id: [Policy.CLOSED.id, [65, 70, 75]],
        }
        self.cache.set('permission:namespace:test/namespace2',
                       json.dumps(permissionDict))

        result = self.permissionCache.getNamespacePermissions(
            [u'test/namespace1', u'test/namespace2'])

        permission1 = result.results[u'test/namespace1']

        self.assertEqual((Policy.OPEN, [1, 2, 3]),
                         permission1.get(Operation.CREATE_NAMESPACE))
        self.assertEqual((Policy.CLOSED, [4, 5, 6]),
                         permission1.get(Operation.UPDATE_NAMESPACE))
        self.assertEqual((Policy.OPEN, [7, 8, 9]),
                         permission1.get(Operation.DELETE_NAMESPACE))
        self.assertEqual((Policy.CLOSED, [10, 11, 12]),
                         permission1.get(Operation.LIST_NAMESPACE))
        self.assertEqual((Policy.OPEN, [13, 14, 15]),
                         permission1.get(Operation.CONTROL_NAMESPACE))

        permission2 = result.results[u'test/namespace2']
        self.assertEqual((Policy.CLOSED, [5, 10, 15]),
                         permission2.get(Operation.CREATE_NAMESPACE))
        self.assertEqual((Policy.OPEN, [20, 25, 30]),
                         permission2.get(Operation.UPDATE_NAMESPACE))
        self.assertEqual((Policy.CLOSED, [35, 40, 45]),
                         permission2.get(Operation.DELETE_NAMESPACE))
        self.assertEqual((Policy.OPEN, [50, 55, 60]),
                         permission2.get(Operation.LIST_NAMESPACE))
        self.assertEqual((Policy.CLOSED, [65, 70, 75]),
                         permission2.get(Operation.CONTROL_NAMESPACE))

    def testGetNamespacePermissionsReturnsUncachedValues(self):
        """
        L{PermissionCache.getNamespacePermissions} returns the paths of
        L{NamespacePermission}s not found in the cache.
        """
        permissionDict = {
            Operation.CREATE_NAMESPACE.id: [Policy.OPEN.id, [1, 2, 3]],
            Operation.UPDATE_NAMESPACE.id: [Policy.CLOSED.id, [4, 5, 6]],
            Operation.DELETE_NAMESPACE.id: [Policy.OPEN.id, [7, 8, 9]],
            Operation.LIST_NAMESPACE.id: [Policy.CLOSED.id, [10, 11, 12]],
            Operation.CONTROL_NAMESPACE.id: [Policy.OPEN.id, [13, 14, 15]],
        }
        self.cache.set('permission:namespace:test/namespace1',
                       json.dumps(permissionDict))

        result = self.permissionCache.getNamespacePermissions(
            [u'test/namespace1', u'test/namespace2'])

        self.assertEqual([u'test/namespace2'], result.uncachedValues)
        self.assertIn(u'test/namespace1', result.results)

    def testGetNamespacePermissionsWithEmptyPaths(self):
        """
        L{PermissionCache.getNamespacePermissions} returns an empty
        L{CacheResult} if no paths are provided.
        """
        cached = self.permissionCache.getNamespacePermissions([])
        self.assertEqual({}, cached.results)
        self.assertEqual([], cached.uncachedValues)

    def testClearTagPermissionsRemovesTagPermissions(self):
        """
        L{PermissionCache.clearTagPermissions} removes L{TagPermission}s from
        the cache, leaving L{NamespacePermission} for the same paths.
        """
        permissionDict = {
            Operation.UPDATE_TAG.id: [Policy.OPEN.id, [1, 2, 3]],
            Operation.DELETE_TAG.id: [Policy.CLOSED.id, [4, 5, 6]],
            Operation.CONTROL_TAG.id: [Policy.OPEN.id, [7, 8, 9]],
            Operation.WRITE_TAG_VALUE.id: [Policy.CLOSED.id, [10, 11, 12]],
            Operation.READ_TAG_VALUE.id: [Policy.OPEN.id, [13, 14, 15]],
            Operation.DELETE_TAG_VALUE.id: [Policy.CLOSED.id, [16, 17, 18]],
            Operation.CONTROL_TAG_VALUE.id: [Policy.OPEN.id, [19, 20, 21]]
        }
        self.cache.set('permission:tag:test/test', json.dumps(permissionDict))

        self.permissionCache.clearTagPermissions([u'test/test'])
        self.assertIdentical(None, self.cache.get('permission:tag:test/test'))

    def testClearNamespacePermissionsRemovesNamespacePermissions(self):
        """
        L{PermissionCache.clearNamespacePermissions} removes
        L{NamespacePermission}s from the cache, leaving L{TagPermission} for
        the same paths.
        """
        permissionDict = {
            Operation.CREATE_NAMESPACE.id: [Policy.OPEN.id, [1, 2, 3]],
            Operation.UPDATE_NAMESPACE.id: [Policy.CLOSED.id, [4, 5, 6]],
            Operation.DELETE_NAMESPACE.id: [Policy.OPEN.id, [7, 8, 9]],
            Operation.LIST_NAMESPACE.id: [Policy.CLOSED.id, [10, 11, 12]],
            Operation.CONTROL_NAMESPACE.id: [Policy.OPEN.id, [13, 14, 15]],
        }
        self.cache.set('permission:namespace:test/test',
                       json.dumps(permissionDict))

        self.permissionCache.clearNamespacePermissions([u'test/test'])
        self.assertIdentical(None,
                             self.cache.get('permission:namespace:test/test'))

    def testSaveTagPermissions(self):
        """
        L{PermissionCache.saveTagPermissions} store L{TagPermission}s in the
        cache.
        """
        permissions = {
            'test/tag1': TagPermission(userID=1, tagID=1),
            'test/tag2': TagPermission(userID=2, tagID=2)
        }

        self.permissionCache.saveTagPermissions(permissions)

        expected = {
            str(Operation.UPDATE_TAG.id): [False, [1]],
            str(Operation.DELETE_TAG.id): [False, [1]],
            str(Operation.CONTROL_TAG.id): [False, [1]],
            str(Operation.WRITE_TAG_VALUE.id): [False, [1]],
            str(Operation.READ_TAG_VALUE.id): [True, []],
            str(Operation.DELETE_TAG_VALUE.id): [False, [1]],
            str(Operation.CONTROL_TAG_VALUE.id): [False, [1]]
        }
        self.assertEqual(
            expected, json.loads(self.cache.get('permission:tag:test/tag1')))

        expected = {
            str(Operation.UPDATE_TAG.id): [False, [2]],
            str(Operation.DELETE_TAG.id): [False, [2]],
            str(Operation.CONTROL_TAG.id): [False, [2]],
            str(Operation.WRITE_TAG_VALUE.id): [False, [2]],
            str(Operation.READ_TAG_VALUE.id): [True, []],
            str(Operation.DELETE_TAG_VALUE.id): [False, [2]],
            str(Operation.CONTROL_TAG_VALUE.id): [False, [2]]
        }
        self.assertEqual(
            expected, json.loads(self.cache.get('permission:tag:test/tag2')))

    def testSaveNamespacePermissions(self):
        """
        L{PermissionCache.saveNamespacePermissions} store
        L{NamespacePermission}s in the cache.
        """
        permissions = {
            'test/ns1': NamespacePermission(userID=1, namespaceID=1),
            'test/ns2': NamespacePermission(userID=2, namespaceID=2)
        }

        self.permissionCache.saveNamespacePermissions(permissions)
        expected = {
            str(Operation.CREATE_NAMESPACE.id): [False, [1]],
            str(Operation.UPDATE_NAMESPACE.id): [False, [1]],
            str(Operation.DELETE_NAMESPACE.id): [False, [1]],
            str(Operation.LIST_NAMESPACE.id): [True, []],
            str(Operation.CONTROL_NAMESPACE.id): [False, [1]]
        }
        self.assertEqual(
            expected,
            json.loads(self.cache.get('permission:namespace:test/ns1')))

        expected = {
            str(Operation.CREATE_NAMESPACE.id): [False, [2]],
            str(Operation.UPDATE_NAMESPACE.id): [False, [2]],
            str(Operation.DELETE_NAMESPACE.id): [False, [2]],
            str(Operation.LIST_NAMESPACE.id): [True, []],
            str(Operation.CONTROL_NAMESPACE.id): [False, [2]]
        }
        self.assertEqual(
            expected,
            json.loads(self.cache.get('permission:namespace:test/ns2')))
예제 #13
0
 def setUp(self):
     super(PermissionCacheTest, self).setUp()
     self.permissionCache = PermissionCache()
예제 #14
0
class PermissionCacheTest(FluidinfoTestCase):

    resources = [('cache', CacheResource()),
                 ('config', ConfigResource()),
                 ('log', LoggingResource(format='%(message)s'))]

    def setUp(self):
        super(PermissionCacheTest, self).setUp()
        self.permissionCache = PermissionCache()

    def setList(self, name, values):
        """Small helper method to put a C{list} in the cache."""
        for item in values:
            self.cache.rpush(name, item)

    def testGetTagPermissions(self):
        """
        L{PermissionCache.getTagPermissions} returns L{TagPermission}s stored
        in the cache.
        """
        permissionDict = {
            Operation.UPDATE_TAG.id: [Policy.OPEN.id, [1, 2, 3]],
            Operation.DELETE_TAG.id: [Policy.CLOSED.id, [4, 5, 6]],
            Operation.CONTROL_TAG.id: [Policy.OPEN.id, [7, 8, 9]],
            Operation.WRITE_TAG_VALUE.id: [Policy.CLOSED.id, [10, 11, 12]],
            Operation.READ_TAG_VALUE.id: [Policy.OPEN.id, [13, 14, 15]],
            Operation.DELETE_TAG_VALUE.id: [Policy.CLOSED.id, [16, 17, 18]],
            Operation.CONTROL_TAG_VALUE.id: [Policy.OPEN.id, [19, 20, 21]]
        }
        self.cache.set('permission:tag:test/tag1', json.dumps(permissionDict))

        permissionDict = {
            Operation.UPDATE_TAG.id: [Policy.CLOSED.id, [10, 15, 20]],
            Operation.DELETE_TAG.id: [Policy.OPEN.id, [25, 30, 35]],
            Operation.CONTROL_TAG.id: [Policy.CLOSED.id, [40, 45, 50]],
            Operation.WRITE_TAG_VALUE.id: [Policy.OPEN.id, [55, 60, 65]],
            Operation.READ_TAG_VALUE.id: [Policy.CLOSED.id, [70, 75, 80]],
            Operation.DELETE_TAG_VALUE.id: [Policy.OPEN.id, [85, 90, 95]],
            Operation.CONTROL_TAG_VALUE.id: [Policy.CLOSED.id, [100, 105, 110]]
        }
        self.cache.set('permission:tag:test/tag2', json.dumps(permissionDict))

        result = self.permissionCache.getTagPermissions([u'test/tag1',
                                                         u'test/tag2'])
        self.assertEqual([], result.uncachedValues)
        permission1 = result.results[u'test/tag1']
        self.assertEqual((Policy.OPEN, [1, 2, 3]),
                         permission1.get(Operation.UPDATE_TAG))
        self.assertEqual((Policy.CLOSED, [4, 5, 6]),
                         permission1.get(Operation.DELETE_TAG))
        self.assertEqual((Policy.OPEN, [7, 8, 9]),
                         permission1.get(Operation.CONTROL_TAG))
        self.assertEqual((Policy.CLOSED, [10, 11, 12]),
                         permission1.get(Operation.WRITE_TAG_VALUE))
        self.assertEqual((Policy.OPEN, [13, 14, 15]),
                         permission1.get(Operation.READ_TAG_VALUE))
        self.assertEqual((Policy.CLOSED, [16, 17, 18]),
                         permission1.get(Operation.DELETE_TAG_VALUE))
        self.assertEqual((Policy.OPEN, [19, 20, 21]),
                         permission1.get(Operation.CONTROL_TAG_VALUE))

        permission2 = result.results[u'test/tag2']
        self.assertEqual((Policy.CLOSED, [10, 15, 20]),
                         permission2.get(Operation.UPDATE_TAG))
        self.assertEqual((Policy.OPEN, [25, 30, 35]),
                         permission2.get(Operation.DELETE_TAG))
        self.assertEqual((Policy.CLOSED, [40, 45, 50]),
                         permission2.get(Operation.CONTROL_TAG))
        self.assertEqual((Policy.OPEN, [55, 60, 65]),
                         permission2.get(Operation.WRITE_TAG_VALUE))
        self.assertEqual((Policy.CLOSED, [70, 75, 80]),
                         permission2.get(Operation.READ_TAG_VALUE))
        self.assertEqual((Policy.OPEN, [85, 90, 95]),
                         permission2.get(Operation.DELETE_TAG_VALUE))
        self.assertEqual((Policy.CLOSED, [100, 105, 110]),
                         permission2.get(Operation.CONTROL_TAG_VALUE))

    def testGetTagPermissionsReturnsUncachedValues(self):
        """
        L{PermissionCache.getTagPermissions} returns the paths of
        L{TagPermission}s not found in the cache.
        """
        permissionDict = {
            Operation.UPDATE_TAG.id: [Policy.OPEN.id, [1, 2, 3]],
            Operation.DELETE_TAG.id: [Policy.CLOSED.id, [4, 5, 6]],
            Operation.CONTROL_TAG.id: [Policy.OPEN.id, [7, 8, 9]],
            Operation.WRITE_TAG_VALUE.id: [Policy.CLOSED.id, [10, 11, 12]],
            Operation.READ_TAG_VALUE.id: [Policy.OPEN.id, [13, 14, 15]],
            Operation.DELETE_TAG_VALUE.id: [Policy.CLOSED.id, [16, 17, 18]],
            Operation.CONTROL_TAG_VALUE.id: [Policy.OPEN.id, [19, 20, 21]]
        }
        self.cache.set('permission:tag:test/tag1', json.dumps(permissionDict))

        result = self.permissionCache.getTagPermissions([u'test/tag1',
                                                         u'test/tag2'])

        self.assertEqual([u'test/tag2'], result.uncachedValues)
        self.assertIn(u'test/tag1', result.results)

    def testGetTagPermissionsWithEmptyPaths(self):
        """
        L{PermissionCache.getTagPermissions} returns an empty L{CacheResult}
        if no paths are provided.
        """
        cached = self.permissionCache.getTagPermissions([])
        self.assertEqual({}, cached.results)
        self.assertEqual([], cached.uncachedValues)

    def testGetNamespacePermissions(self):
        """
        L{PermissionCache.getNamespacePermissions} returns
        L{NamespacePermission}s stored in the cache.
        """
        permissionDict = {
            Operation.CREATE_NAMESPACE.id: [Policy.OPEN.id, [1, 2, 3]],
            Operation.UPDATE_NAMESPACE.id: [Policy.CLOSED.id, [4, 5, 6]],
            Operation.DELETE_NAMESPACE.id: [Policy.OPEN.id, [7, 8, 9]],
            Operation.LIST_NAMESPACE.id: [Policy.CLOSED.id, [10, 11, 12]],
            Operation.CONTROL_NAMESPACE.id: [Policy.OPEN.id, [13, 14, 15]],
        }
        self.cache.set('permission:namespace:test/namespace1',
                       json.dumps(permissionDict))

        permissionDict = {
            Operation.CREATE_NAMESPACE.id: [Policy.CLOSED.id, [5, 10, 15]],
            Operation.UPDATE_NAMESPACE.id: [Policy.OPEN.id, [20, 25, 30]],
            Operation.DELETE_NAMESPACE.id: [Policy.CLOSED.id, [35, 40, 45]],
            Operation.LIST_NAMESPACE.id: [Policy.OPEN.id, [50, 55, 60]],
            Operation.CONTROL_NAMESPACE.id: [Policy.CLOSED.id, [65, 70, 75]],
        }
        self.cache.set('permission:namespace:test/namespace2',
                       json.dumps(permissionDict))

        result = self.permissionCache.getNamespacePermissions(
            [u'test/namespace1', u'test/namespace2'])

        permission1 = result.results[u'test/namespace1']

        self.assertEqual((Policy.OPEN, [1, 2, 3]),
                         permission1.get(Operation.CREATE_NAMESPACE))
        self.assertEqual((Policy.CLOSED, [4, 5, 6]),
                         permission1.get(Operation.UPDATE_NAMESPACE))
        self.assertEqual((Policy.OPEN, [7, 8, 9]),
                         permission1.get(Operation.DELETE_NAMESPACE))
        self.assertEqual((Policy.CLOSED, [10, 11, 12]),
                         permission1.get(Operation.LIST_NAMESPACE))
        self.assertEqual((Policy.OPEN, [13, 14, 15]),
                         permission1.get(Operation.CONTROL_NAMESPACE))

        permission2 = result.results[u'test/namespace2']
        self.assertEqual((Policy.CLOSED, [5, 10, 15]),
                         permission2.get(Operation.CREATE_NAMESPACE))
        self.assertEqual((Policy.OPEN, [20, 25, 30]),
                         permission2.get(Operation.UPDATE_NAMESPACE))
        self.assertEqual((Policy.CLOSED, [35, 40, 45]),
                         permission2.get(Operation.DELETE_NAMESPACE))
        self.assertEqual((Policy.OPEN, [50, 55, 60]),
                         permission2.get(Operation.LIST_NAMESPACE))
        self.assertEqual((Policy.CLOSED, [65, 70, 75]),
                         permission2.get(Operation.CONTROL_NAMESPACE))

    def testGetNamespacePermissionsReturnsUncachedValues(self):
        """
        L{PermissionCache.getNamespacePermissions} returns the paths of
        L{NamespacePermission}s not found in the cache.
        """
        permissionDict = {
            Operation.CREATE_NAMESPACE.id: [Policy.OPEN.id, [1, 2, 3]],
            Operation.UPDATE_NAMESPACE.id: [Policy.CLOSED.id, [4, 5, 6]],
            Operation.DELETE_NAMESPACE.id: [Policy.OPEN.id, [7, 8, 9]],
            Operation.LIST_NAMESPACE.id: [Policy.CLOSED.id, [10, 11, 12]],
            Operation.CONTROL_NAMESPACE.id: [Policy.OPEN.id, [13, 14, 15]],
        }
        self.cache.set('permission:namespace:test/namespace1',
                       json.dumps(permissionDict))

        result = self.permissionCache.getNamespacePermissions(
            [u'test/namespace1', u'test/namespace2'])

        self.assertEqual([u'test/namespace2'], result.uncachedValues)
        self.assertIn(u'test/namespace1', result.results)

    def testGetNamespacePermissionsWithEmptyPaths(self):
        """
        L{PermissionCache.getNamespacePermissions} returns an empty
        L{CacheResult} if no paths are provided.
        """
        cached = self.permissionCache.getNamespacePermissions([])
        self.assertEqual({}, cached.results)
        self.assertEqual([], cached.uncachedValues)

    def testClearTagPermissionsRemovesTagPermissions(self):
        """
        L{PermissionCache.clearTagPermissions} removes L{TagPermission}s from
        the cache, leaving L{NamespacePermission} for the same paths.
        """
        permissionDict = {
            Operation.UPDATE_TAG.id: [Policy.OPEN.id, [1, 2, 3]],
            Operation.DELETE_TAG.id: [Policy.CLOSED.id, [4, 5, 6]],
            Operation.CONTROL_TAG.id: [Policy.OPEN.id, [7, 8, 9]],
            Operation.WRITE_TAG_VALUE.id: [Policy.CLOSED.id, [10, 11, 12]],
            Operation.READ_TAG_VALUE.id: [Policy.OPEN.id, [13, 14, 15]],
            Operation.DELETE_TAG_VALUE.id: [Policy.CLOSED.id, [16, 17, 18]],
            Operation.CONTROL_TAG_VALUE.id: [Policy.OPEN.id, [19, 20, 21]]
        }
        self.cache.set('permission:tag:test/test', json.dumps(permissionDict))

        self.permissionCache.clearTagPermissions([u'test/test'])
        self.assertIdentical(None, self.cache.get('permission:tag:test/test'))

    def testClearNamespacePermissionsRemovesNamespacePermissions(self):
        """
        L{PermissionCache.clearNamespacePermissions} removes
        L{NamespacePermission}s from the cache, leaving L{TagPermission} for
        the same paths.
        """
        permissionDict = {
            Operation.CREATE_NAMESPACE.id: [Policy.OPEN.id, [1, 2, 3]],
            Operation.UPDATE_NAMESPACE.id: [Policy.CLOSED.id, [4, 5, 6]],
            Operation.DELETE_NAMESPACE.id: [Policy.OPEN.id, [7, 8, 9]],
            Operation.LIST_NAMESPACE.id: [Policy.CLOSED.id, [10, 11, 12]],
            Operation.CONTROL_NAMESPACE.id: [Policy.OPEN.id, [13, 14, 15]],
        }
        self.cache.set('permission:namespace:test/test',
                       json.dumps(permissionDict))

        self.permissionCache.clearNamespacePermissions([u'test/test'])
        self.assertIdentical(None,
                             self.cache.get('permission:namespace:test/test'))

    def testSaveTagPermissions(self):
        """
        L{PermissionCache.saveTagPermissions} store L{TagPermission}s in the
        cache.
        """
        permissions = {
            'test/tag1': TagPermission(userID=1, tagID=1),
            'test/tag2': TagPermission(userID=2, tagID=2)}

        self.permissionCache.saveTagPermissions(permissions)

        expected = {
            str(Operation.UPDATE_TAG.id): [False, [1]],
            str(Operation.DELETE_TAG.id): [False, [1]],
            str(Operation.CONTROL_TAG.id): [False, [1]],
            str(Operation.WRITE_TAG_VALUE.id): [False, [1]],
            str(Operation.READ_TAG_VALUE.id): [True, []],
            str(Operation.DELETE_TAG_VALUE.id): [False, [1]],
            str(Operation.CONTROL_TAG_VALUE.id): [False, [1]]
        }
        self.assertEqual(
            expected, json.loads(self.cache.get('permission:tag:test/tag1')))

        expected = {
            str(Operation.UPDATE_TAG.id): [False, [2]],
            str(Operation.DELETE_TAG.id): [False, [2]],
            str(Operation.CONTROL_TAG.id): [False, [2]],
            str(Operation.WRITE_TAG_VALUE.id): [False, [2]],
            str(Operation.READ_TAG_VALUE.id): [True, []],
            str(Operation.DELETE_TAG_VALUE.id): [False, [2]],
            str(Operation.CONTROL_TAG_VALUE.id): [False, [2]]
        }
        self.assertEqual(
            expected, json.loads(self.cache.get('permission:tag:test/tag2')))

    def testSaveNamespacePermissions(self):
        """
        L{PermissionCache.saveNamespacePermissions} store
        L{NamespacePermission}s in the cache.
        """
        permissions = {
            'test/ns1': NamespacePermission(userID=1, namespaceID=1),
            'test/ns2': NamespacePermission(userID=2, namespaceID=2)}

        self.permissionCache.saveNamespacePermissions(permissions)
        expected = {
            str(Operation.CREATE_NAMESPACE.id): [False, [1]],
            str(Operation.UPDATE_NAMESPACE.id): [False, [1]],
            str(Operation.DELETE_NAMESPACE.id): [False, [1]],
            str(Operation.LIST_NAMESPACE.id): [True, []],
            str(Operation.CONTROL_NAMESPACE.id): [False, [1]]
        }
        self.assertEqual(
            expected,
            json.loads(self.cache.get('permission:namespace:test/ns1')))

        expected = {
            str(Operation.CREATE_NAMESPACE.id): [False, [2]],
            str(Operation.UPDATE_NAMESPACE.id): [False, [2]],
            str(Operation.DELETE_NAMESPACE.id): [False, [2]],
            str(Operation.LIST_NAMESPACE.id): [True, []],
            str(Operation.CONTROL_NAMESPACE.id): [False, [2]]
        }
        self.assertEqual(
            expected,
            json.loads(self.cache.get('permission:namespace:test/ns2')))