[CalendarServer-changes] [2514] CalendarServer/trunk/twistedcaldav
source_changes at macosforge.org
source_changes at macosforge.org
Thu May 29 17:10:26 PDT 2008
Revision: 2514
http://trac.macosforge.org/projects/calendarserver/changeset/2514
Author: dreid at apple.com
Date: 2008-05-29 17:10:24 -0700 (Thu, 29 May 2008)
Log Message:
-----------
Fix bug with multi-homed resources being cached in two places with two tokens and not being invalidated properly.
Also remove the Xattr based response cache. It didn't share enough code with the Memcache version and it was hard to make multi-homing work in it.
Modified Paths:
--------------
CalendarServer/trunk/twistedcaldav/cache.py
CalendarServer/trunk/twistedcaldav/directory/principal.py
CalendarServer/trunk/twistedcaldav/directory/test/test_principal.py
CalendarServer/trunk/twistedcaldav/root.py
CalendarServer/trunk/twistedcaldav/static.py
CalendarServer/trunk/twistedcaldav/test/test_cache.py
CalendarServer/trunk/twistedcaldav/test/test_static.py
CalendarServer/trunk/twistedcaldav/test/util.py
Modified: CalendarServer/trunk/twistedcaldav/cache.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/cache.py 2008-05-29 23:05:56 UTC (rev 2513)
+++ CalendarServer/trunk/twistedcaldav/cache.py 2008-05-30 00:10:24 UTC (rev 2514)
@@ -21,6 +21,7 @@
from zope.interface import implements
+from twisted.python.failure import Failure
from twisted.internet.defer import succeed
from twisted.internet.protocol import ClientCreator
@@ -38,41 +39,42 @@
from twistedcaldav.memcache import MemCacheProtocol
from twistedcaldav.config import config
-class CacheTokensProperty(davxml.WebDAVTextElement):
- namespace = davxml.twisted_private_namespace
- name = "cacheTokens"
+class DisabledCacheNotifier(object):
+ def __init__(self, *args, **kwargs):
+ pass
-class XattrCacheChangeNotifier(LoggingMixIn):
- def __init__(self, propertyStore):
- self._propertyStore = propertyStore
- self._token = None
+ def changed(self):
+ return succeed(None)
- def _newCacheToken(self):
- return str(uuid.uuid4())
+class DisabledCache(object):
+ def getResponseForRequest(self, request):
+ return None
- def changed(self):
- """
- Change the cache token for a resource.
+ def cacheResponseForRequest(self, request, response):
+ return response
- return: A L{Deferred} that fires when the token has been changed.
- """
- self.log_debug("Changing Cache Token for %r" % (
- self._propertyStore.resource.fp))
- property = CacheTokensProperty.fromString(self._newCacheToken())
- self._propertyStore.set(property)
- return succeed(True)
+class URINotFoundException(Exception):
+ def __init__(self, uri):
+ self.uri = uri
+ def __repr__(self):
+ return "%s: Could not find URI %r" % (
+ self.__class__.__name__,
+ self.uri)
+
+
+
class MemcacheChangeNotifier(LoggingMixIn):
_memcacheProtocol = None
- def __init__(self, propertyStore):
- self._path = propertyStore.resource.fp.path
+ def __init__(self, resource):
+ self._resource = resource
self._host = config.Memcached['BindAddress']
self._port = config.Memcached['Port']
@@ -106,10 +108,10 @@
return: A L{Deferred} that fires when the token has been changed.
"""
def _updateCacheToken(proto):
- return proto.set('cacheToken:%s' % (self._path,),
+ return proto.set('cacheToken:%s' % (self._resource.url(),),
self._newCacheToken())
- self.log_debug("Changing Cache Token for %r" % (self._path,))
+ self.log_debug("Changing Cache Token for %r" % (self._resource.url(),))
d = self._getMemcacheProtocol()
d.addCallback(_updateCacheToken)
return d
@@ -126,67 +128,51 @@
return str(principal.children[0])
+ def _canonicalizeURIForRequest(self, uri, request):
+ def _uriNotFound(f):
+ f.trap(AttributeError)
+ return Failure(URINotFoundException(uri))
+
+ return request.locateResource(uri).addCallback(
+ lambda resrc: resrc.url()).addErrback(_uriNotFound)
+
+
+ def _getURIs(self, request):
+ def _getSecondURI(rURI):
+ return self._canonicalizeURIForRequest(
+ self._principalURI(request.authnUser),
+ request).addCallback(lambda pURI: (pURI, rURI))
+
+ d = self._canonicalizeURIForRequest(request.uri, request)
+ d.addCallback(_getSecondURI)
+
+ return d
+
+
def _requestKey(self, request):
- def _getKey(requestBody):
+ def _getBody(uris):
+ return allDataFromStream(request.stream).addCallback(
+ lambda body: (body, uris))
+
+ def _getKey((requestBody, (pURI, rURI))):
if requestBody is not None:
request.stream = MemoryStream(requestBody)
request.stream.doStartReading = None
request.cacheKey = (request.method,
- self._principalURI(request.authnUser),
- request.uri,
+ pURI,
+ rURI,
request.headers.getHeader('depth'),
hash(requestBody))
return request.cacheKey
- d = allDataFromStream(request.stream)
+ d = self._getURIs(request)
+ d.addCallback(_getBody)
d.addCallback(_getKey)
return d
- def _getTokensInThread(self, principalURI, requestURI):
- def _getTokens():
- pToken = self._tokenForURI(principalURI)
- uToken = self._tokenForURI(requestURI)
-
- return (pToken, uToken)
-
- return deferToThread(_getTokens)
-
-
- def _tokenForURI(self, uri):
- """
- Get a property store for the given C{uri}.
-
- @param uri: The URI we'd like the token for.
- @return: A C{str} representing the token for the URI.
- """
-
- class __FauxStaticResource(object):
- def __init__(self, fp):
- self.fp = fp
-
-
- fp = self._docroot
- segments = uri.split('/')
- for childPath in segments[:3]:
- fp = fp.child(childPath)
-
- fp = fp.child(segments[3][:2]
- ).child(segments[3][2:4]
- ).child(segments[3])
-
- props = self.propertyStoreFactory(__FauxStaticResource(fp))
-
- try:
- tokenElement = props.get(CacheTokensProperty.qname())
- return tokenElement.children[0].data
-
- except HTTPError, err:
- pass
-
-
def _getResponseBody(self, key, response):
d1 = allDataFromStream(response.stream)
d1.addCallback(lambda responseBody: (key, responseBody))
@@ -194,167 +180,6 @@
-class ResponseCache(BaseResponseCache):
- """
- An object that caches responses to given requests.
-
- @ivar CACHE_TIMEOUT: The number of seconds that a cache entry is valid,
- (default 3600 seconds or 1 hour).
-
- @ivar _docroot: An L{FilePath} that points to the document root.
- @ivar _responses: A C{dict} with (request-method, request-uri,
- principal-uri) keys and (principal-token, uri-token, cache-time,
- response) values.
- """
-
- CACHE_SIZE = 1000
-
- def __init__(self, docroot, cacheSize=None):
- self._docroot = docroot
- self._responses = {}
-
- if cacheSize is not None:
- self.CACHE_SIZE = cacheSize
-
-
- def _time(self):
- """
- Return the current time in seconds since the epoch
- """
- return time.time()
-
-
- def getResponseForRequest(self, request):
- """
- Retrieve a cached response to the given C{request} otherwise return
- C{None}
-
- @param request: An L{IRequest} provider that will be used to locate
- a cached L{IResponse}.
-
- @return: An L{IResponse} or C{None} if the response has not been cached.
- """
- principalURI = self._principalURI(request.authnUser)
-
- def _checkTokens((newPrincipalToken, newURIToken), key):
- (principalToken,
- uriToken,
- accessTime,
- response) = self._responses[key]
-
- if newPrincipalToken != principalToken:
- self.log_debug("Principal token changed on %r from %r to %r" % (
- key,
- principalToken,
- newPrincipalToken
- ))
- return None
-
- elif newURIToken != uriToken:
- self.log_debug("URI token changed on %r from %r to %r" % (
- key,
- uriToken,
- newURIToken
- ))
- return None
-
- response[1].removeHeader('date')
-
- responseObj = Response(response[0],
- headers=response[1],
- stream=MemoryStream(response[2]))
-
- self._responses[key] = (principalToken,
- uriToken,
- self._time(),
- response)
-
- self.log_debug("Found in cache: %r = %r" % (key,
- responseObj))
-
- return responseObj
-
-
- def _checkKeyInCache(key):
- self.log_debug("Checking cache for: %r" % (key,))
-
- if key not in self._responses:
- self.log_debug("Not in cache: %r" % (key,))
- return None
-
- d1 = self._getTokensInThread(principalURI, request.uri)
- d1.addCallback(_checkTokens, key)
-
- return d1
-
- d = self._requestKey(request)
- d.addCallback(_checkKeyInCache)
- return d
-
-
- def cacheResponseForRequest(self, request, response):
- """
- Cache the given C{response} for the given C{request}.
-
- @param request: An L{IRequest} provider that will be keyed to the
- given C{response}.
-
- @param response: An L{IResponse} provider that will be returned on
- subsequent checks for the given L{IRequest}
-
- @return: A deferred that fires when the response has been added
- to the cache.
- """
- def _cacheResponse((key, responseBody)):
- principalURI = self._principalURI(request.authnUser)
-
- self.log_debug("Adding to cache: %r = %r" % (key,
- response))
-
- if len(self._responses) >= self.CACHE_SIZE:
- leastRecentlyUsedTime = None
- leastRecentlyUsedKey = None
-
- for cacheKey, cacheEntry in self._responses.iteritems():
- if leastRecentlyUsedTime is None:
- leastRecentlyUsedTime = cacheEntry[2]
- leastRecentlyUsedKey = cacheKey
- continue
-
- if leastRecentlyUsedTime < cacheEntry[2]:
- leastRecentlyUsedTime = cacheEntry[2]
- leastRecentlyUsedKey = cacheKey
-
- self.log_warn("Expiring from cache: %r" % (
- leastRecentlyUsedKey,))
-
- del self._responses[leastRecentlyUsedKey]
-
-
- self._responses[key] = (self._tokenForURI(principalURI),
- self._tokenForURI(request.uri),
- self._time(),
- (response.code,
- response.headers,
- responseBody))
-
- self.log_debug("Cache Stats: # keys = %r" % (len(self._responses),))
-
- response.stream = MemoryStream(responseBody)
- return response
-
- if hasattr(request, 'cacheKey'):
- request.cacheKey
- d = succeed(request.cacheKey)
- else:
- d = self._requestKey(request)
-
- d.addCallback(self._getResponseBody, response)
- d.addCallback(_cacheResponse)
- return d
-
-
-
class MemcacheResponseCache(BaseResponseCache):
def __init__(self, docroot, host, port, reactor=None):
self._docroot = docroot
@@ -376,27 +201,22 @@
@return: A C{str} representing the token for the URI.
"""
- class __FauxStaticResource(object):
- def __init__(self, fp):
- self.fp = fp
-
-
- fp = self._docroot
- for childPath in uri.split('/')[:4]:
- fp = fp.child(childPath)
-
return self._getMemcacheProtocol().addCallback(
- lambda p: p.get('cacheToken:%s' % (fp.path,)))
+ lambda p: p.get('cacheToken:%s' % (uri,)))
- def _getTokens(self, principalURI, requestURI):
- def _getSecondToken(pToken):
- d1 = self._tokenForURI(requestURI)
- d1.addCallback(lambda uToken: (pToken, uToken))
+ def _getTokens(self, request):
+ def _tokensForURIs((pURI, rURI)):
+ tokens = []
+ d1 = self._tokenForURI(pURI)
+ d1.addCallback(lambda pToken: tokens.append(pToken))
+ d1.addCallback(lambda _ign: self._tokenForURI(rURI))
+ d1.addCallback(lambda uToken: tokens.append(uToken))
+ d1.addCallback(lambda _ign: tokens)
return d1
- d = self._tokenForURI(principalURI)
- d.addCallback(_getSecondToken)
+ d = self._getURIs(request)
+ d.addCallback(_tokensForURIs)
return d
@@ -463,10 +283,8 @@
(principalToken, uriToken,
resp) = cPickle.loads(value)
+ d2 = self._getTokens(request)
- d2 = self._getTokens(self._principalURI(request.authnUser),
- request.uri)
-
d2.addCallback(_checkTokens, (principalToken, uriToken), resp)
return d2
@@ -479,8 +297,14 @@
def _getProtocol(key):
return self._getMemcacheProtocol().addCallback(_getCache, key)
+ def _handleExceptions(f):
+ f.trap(URINotFoundException)
+ self.log_warn("Could not locate URI: %r" % f.value)
+ return None
+
d = self._hashedRequestKey(request)
d.addCallback(_getProtocol)
+ d.addErrback(_handleExceptions)
return d
@@ -508,7 +332,7 @@
response.headers.removeHeader('date')
response.stream = MemoryStream(responseBody)
- d1 = self._getTokens(principalURI, request.uri)
+ d1 = self._getTokens(request)
d1.addCallback(_makeCacheEntry, (key, responseBody))
return d1
Modified: CalendarServer/trunk/twistedcaldav/directory/principal.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/principal.py 2008-05-29 23:05:56 UTC (rev 2513)
+++ CalendarServer/trunk/twistedcaldav/directory/principal.py 2008-05-30 00:10:24 UTC (rev 2514)
@@ -42,7 +42,7 @@
from twisted.web2.dav.util import joinURL
from twistedcaldav.config import config
-from twistedcaldav.cache import XattrCacheChangeNotifier, PropfindCacheMixin
+from twistedcaldav.cache import DisabledCacheNotifier, PropfindCacheMixin
from twistedcaldav.directory.calendaruserproxy import CalendarUserProxyDatabase
from twistedcaldav.directory.calendaruserproxy import CalendarUserProxyPrincipalResource
@@ -356,7 +356,7 @@
"""
Directory principal resource.
"""
- cacheNotifierFactory = XattrCacheChangeNotifier
+ cacheNotifierFactory = DisabledCacheNotifier
def __init__(self, path, parent, record):
"""
@@ -366,7 +366,7 @@
"""
super(DirectoryPrincipalResource, self).__init__(path)
- self.cacheNotifier = self.cacheNotifierFactory(self.deadProperties())
+ self.cacheNotifier = self.cacheNotifierFactory(self)
if self.isCollection():
slash = "/"
@@ -481,6 +481,9 @@
def principalURL(self):
return self._url
+ def url(self):
+ return self.principalURL()
+
def _getRelatives(self, method, record=None, relatives=None, records=None, proxy=None):
if record is None:
record = self.record
Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_principal.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_principal.py 2008-05-29 23:05:56 UTC (rev 2513)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_principal.py 2008-05-30 00:10:24 UTC (rev 2514)
@@ -34,7 +34,7 @@
from twistedcaldav.directory.principal import DirectoryPrincipalResource
from twistedcaldav.directory.principal import DirectoryCalendarPrincipalResource
-from twistedcaldav.cache import XattrCacheChangeNotifier
+from twistedcaldav.cache import DisabledCacheNotifier
import twistedcaldav.test.util
@@ -229,7 +229,7 @@
"""
for provisioningResource, recordType, recordResource, record in self._allRecords():
self.failUnless(isinstance(recordResource.cacheNotifier,
- XattrCacheChangeNotifier))
+ DisabledCacheNotifier))
def test_displayName(self):
"""
Modified: CalendarServer/trunk/twistedcaldav/root.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/root.py 2008-05-29 23:05:56 UTC (rev 2513)
+++ CalendarServer/trunk/twistedcaldav/root.py 2008-05-30 00:10:24 UTC (rev 2514)
@@ -25,8 +25,9 @@
from twistedcaldav.extensions import DAVFile, CachingXattrPropertyStore
from twistedcaldav.config import config
-from twistedcaldav.cache import ResponseCache, _CachedResponseResource
+from twistedcaldav.cache import _CachedResponseResource
from twistedcaldav.cache import MemcacheResponseCache, MemcacheChangeNotifier
+from twistedcaldav.cache import DisabledCache
from twistedcaldav.log import Logger
from twistedcaldav.static import CalendarHomeFile
from twistedcaldav.directory.principal import DirectoryPrincipalResource
@@ -63,10 +64,8 @@
CalendarHomeFile.cacheNotifierFactory = MemcacheChangeNotifier
DirectoryPrincipalResource.cacheNotifierFactory = MemcacheChangeNotifier
-
else:
- self.responseCache = ResponseCache(self.fp,
- config.ResponseCacheSize)
+ self.responseCache = DisabledCache()
if config.ResponseCompression:
from twisted.web2.filter import gzip
@@ -157,10 +156,14 @@
return d
def _getCachedResource(_ign, request):
- d = self.responseCache.getResponseForRequest(request)
- d.addCallback(_serveResponse)
- return d
+ if not getattr(request, 'checkingCache', False):
+ request.checkingCache = True
+ d = self.responseCache.getResponseForRequest(request)
+ d.addCallback(_serveResponse)
+ return d
+ return super(RootResource, self).locateChild(request, segments)
+
def _serveResponse(response):
if response is None:
request.notInCache = True
Modified: CalendarServer/trunk/twistedcaldav/static.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/static.py 2008-05-29 23:05:56 UTC (rev 2513)
+++ CalendarServer/trunk/twistedcaldav/static.py 2008-05-30 00:10:24 UTC (rev 2514)
@@ -71,7 +71,7 @@
from twistedcaldav.log import Logger
from twistedcaldav.timezoneservice import TimezoneServiceResource
-from twistedcaldav.cache import XattrCacheChangeNotifier, PropfindCacheMixin
+from twistedcaldav.cache import DisabledCacheNotifier, PropfindCacheMixin
log = Logger()
@@ -555,7 +555,7 @@
"""
Calendar home collection resource.
"""
- cacheNotifierFactory = XattrCacheChangeNotifier
+ cacheNotifierFactory = DisabledCacheNotifier
def __init__(self, path, parent, record):
"""
@@ -563,7 +563,7 @@
"""
CalDAVFile.__init__(self, path)
DirectoryCalendarHomeResource.__init__(self, parent, record)
- self.cacheNotifier = self.cacheNotifierFactory(self.deadProperties())
+ self.cacheNotifier = self.cacheNotifierFactory(self)
def provisionChild(self, name):
if config.EnableDropBox:
Modified: CalendarServer/trunk/twistedcaldav/test/test_cache.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_cache.py 2008-05-29 23:05:56 UTC (rev 2513)
+++ CalendarServer/trunk/twistedcaldav/test/test_cache.py 2008-05-30 00:10:24 UTC (rev 2514)
@@ -29,9 +29,6 @@
from twisted.web2.stream import MemoryStream
from twisted.web2.http_headers import Headers
-from twistedcaldav.cache import XattrCacheChangeNotifier
-from twistedcaldav.cache import CacheTokensProperty
-from twistedcaldav.cache import ResponseCache
from twistedcaldav.cache import MemcacheResponseCache
from twistedcaldav.cache import MemcacheChangeNotifier
@@ -48,6 +45,8 @@
class StubRequest(object):
+ resources = {}
+
def __init__(self, method, uri, authnUser, depth='1', body=None):
self.method = method
self.uri = uri
@@ -61,7 +60,11 @@
self.stream = MemoryStream(body)
+ def locateResource(self, uri):
+ return succeed(self.resources.get(uri))
+
+
class StubResponse(object):
def __init__(self, code, headers, body):
self.code = code
@@ -93,34 +96,16 @@
-class XattrCacheChangeNotifierTests(TestCase):
- def setUp(self):
- self.props = InMemoryPropertyStore()
- self.ccn = XattrCacheChangeNotifier(self.props)
- self.ccn._newCacheToken = instancemethod(_newCacheToken,
- self.ccn,
- XattrCacheChangeNotifier)
+class StubURLResource(object):
+ def __init__(self, url):
+ self._url = url
- def assertToken(self, expectedToken):
- token = self.props._properties[CacheTokensProperty.qname()
- ].children[0].data
- self.assertEquals(token, expectedToken)
+ def url(self):
+ return self._url
- def test_cacheTokenPropertyIsProvisioned(self):
- d = self.ccn.changed()
- d.addCallback(lambda _: self.assertToken('token0'))
- return d
-
- def test_changedChangesToken(self):
- d = self.ccn.changed()
- d.addCallback(lambda _: self.ccn.changed())
- d.addCallback(lambda _: self.assertToken('token1'))
- return d
-
-
class MemCacheChangeNotifierTests(TestCase):
def setUp(self):
self.memcache = InMemoryMemcacheProtocol()
@@ -153,7 +138,24 @@
MemcacheChangeNotifier._memcacheProtocol = None
+
class BaseCacheTestMixin(object):
+ def setUp(self):
+ StubRequest.resources = {
+ '/calendars/__uids__/cdaboo/': StubURLResource(
+ '/calendars/__uids__/cdaboo/'),
+ '/principals/__uids__/cdaboo/': StubURLResource(
+ '/principals/__uids__/cdaboo/'),
+ '/calendars/__uids__/dreid/': StubURLResource(
+ '/calendars/__uids__/dreid/'),
+ '/principals/__uids__/dreid/': StubURLResource(
+ '/principals/__uids__/dreid/')}
+
+
+ def tearDown(self):
+ StubRequest.resources = {}
+
+
def assertResponse(self, response, expected):
self.assertEquals(response.code, expected[0])
self.assertEquals(set(response.headers.getAllRawHeaders()),
@@ -164,11 +166,52 @@
return d
+ def test_getResponseForRequestMultiHomedRequestURI(self):
+ request = StubRequest(
+ 'PROPFIND',
+ '/calendars/users/cdaboo/',
+ '/principals/__uids__/cdaboo/')
+
+ request.resources['/calendars/users/cdaboo/'] = StubURLResource(
+ '/calendars/__uids__/cdaboo/')
+
+ d = self.rc.getResponseForRequest(request)
+
+ d.addCallback(self.assertResponse, self.expected_response)
+ return d
+
+
+ def test_getResponseForRequestURINotFound(self):
+ request = StubRequest(
+ 'PROPFIND',
+ '/calendars/__uids__/wsanchez/',
+ '/calendars/__uids__/dreid/')
+
+ d = self.rc.getResponseForRequest(request)
+ d.addCallback(self.assertEquals, None)
+ return d
+
+
+ def test_getResponseForRequestMultiHomedPrincipalURI(self):
+ request = StubRequest(
+ 'PROPFIND',
+ '/calendars/__uids__/cdaboo/',
+ '/principals/users/cdaboo/')
+
+ request.resources['/principals/users/cdaboo/'] = StubURLResource(
+ '/principals/__uids__/cdaboo/')
+
+ d = self.rc.getResponseForRequest(request)
+
+ d.addCallback(self.assertResponse, self.expected_response)
+ return d
+
+
def test_getResponseForRequestNotInCache(self):
d = self.rc.getResponseForRequest(StubRequest(
'PROPFIND',
- '/calendars/users/dreid/',
- '/principals/users/dreid/'))
+ '/calendars/__uids__/dreid/',
+ '/principals/__uids__/dreid/'))
d.addCallback(self.assertEquals, None)
return d
@@ -177,32 +220,32 @@
def test_getResponseForRequestInCache(self):
d = self.rc.getResponseForRequest(StubRequest(
'PROPFIND',
- '/calendars/users/cdaboo/',
- '/principals/users/cdaboo/'))
+ '/calendars/__uids__/cdaboo/',
+ '/principals/__uids__/cdaboo/'))
d.addCallback(self.assertResponse, self.expected_response)
return d
def test_getResponseForRequestPrincipalTokenChanged(self):
- self.tokens['/principals/users/cdaboo/'] = 'principalToken1'
+ self.tokens['/principals/__uids__/cdaboo/'] = 'principalToken1'
d = self.rc.getResponseForRequest(StubRequest(
'PROPFIND',
- '/calendars/users/cdaboo/',
- '/principals/users/cdaboo/'))
+ '/calendars/__uids__/cdaboo/',
+ '/principals/__uids__/cdaboo/'))
d.addCallback(self.assertEquals, None)
return d
def test_getResponseForRequestUriTokenChanged(self):
- self.tokens['/calendars/users/cdaboo/'] = 'uriToken1'
+ self.tokens['/calendars/__uids__/cdaboo/'] = 'uriToken1'
d = self.rc.getResponseForRequest(StubRequest(
'PROPFIND',
- '/calendars/users/cdaboo/',
- '/principals/users/cdaboo/'))
+ '/calendars/__uids__/cdaboo/',
+ '/principals/__uids__/cdaboo/'))
d.addCallback(self.assertEquals, None)
return d
@@ -211,8 +254,8 @@
def test_getResponseForDepthZero(self):
d = self.rc.getResponseForRequest(StubRequest(
'PROPFIND',
- '/calendars/users/cdaboo/',
- '/principals/users/cdaboo/',
+ '/calendars/__uids__/cdaboo/',
+ '/principals/__uids__/cdaboo/',
depth='0'))
d.addCallback(self.assertEquals, None)
@@ -222,8 +265,8 @@
def test_getResponseForBody(self):
d = self.rc.getResponseForRequest(StubRequest(
'PROPFIND',
- '/calendars/users/cdaboo/',
- '/principals/users/cdaboo',
+ '/calendars/__uids__/cdaboo/',
+ '/principals/__uids__/cdaboo/',
body='bazbax'))
d.addCallback(self.assertEquals, None)
@@ -236,8 +279,8 @@
def _assertResponse(ign):
d1 = self.rc.getResponseForRequest(StubRequest(
'PROPFIND',
- '/principals/users/dreid/',
- '/principals/users/dreid/'))
+ '/principals/__uids__/dreid/',
+ '/principals/__uids__/dreid/'))
d1.addCallback(self.assertResponse,
@@ -246,138 +289,34 @@
expected_response.body))
return d1
- d = self.rc.cacheResponseForRequest(
- StubRequest('PROPFIND',
- '/principals/users/dreid/',
- '/principals/users/dreid/'),
- expected_response)
- d.addCallback(_assertResponse)
- return d
+ StubRequest.resources[
+ '/principals/__uids__/dreid/'] = StubURLResource(
+ '/principals/__uids__/dreid/')
-
-
-class ResponseCacheTests(BaseCacheTestMixin, TestCase):
- def setUp(self):
- self.tokens = {
- '/calendars/users/cdaboo/': 'uriToken0',
- '/principals/users/cdaboo/': 'principalToken0',
- '/principals/users/dreid/': 'principalTokenX'}
-
- self.rc = ResponseCache(None)
- self.rc._tokenForURI = self.tokens.get
-
- self.rc._time = (lambda:0)
-
- self.expected_response = (200, Headers({}), "Foo")
-
- expected_key = (
- 'PROPFIND',
- '/principals/users/cdaboo/',
- '/calendars/users/cdaboo/',
- '1',
- hash('foobar'),
- )
-
- self.rc._responses[expected_key] = (
- 'principalToken0', 'uriToken0', '0', self.expected_response)
-
- self.rc._accessList = [expected_key]
-
-
-
-
- def test__tokenForURI(self):
- docroot = FilePath(self.mktemp())
- principal = docroot.child('principals'
- ).child('users'
- ).child('ws'
- ).child('an'
- ).child('wsanchez')
-
- expected_token = "wsanchezToken0"
-
- props = InMemoryPropertyStore()
- props._properties[CacheTokensProperty.qname()
- ] = CacheTokensProperty.fromString(expected_token)
-
- stores = {principal.path: props}
-
- rc = ResponseCache(docroot)
-
- rc.propertyStoreFactory = (lambda rsrc: stores[rsrc.fp.path])
-
- token = rc._tokenForURI('/principals/users/wsanchez')
- self.assertEquals(token, expected_token)
-
-
- def test_cacheSizeExceeded(self):
- self.rc.CACHE_SIZE = 1
- def _assertResponse(ign):
- d1 = self.rc.getResponseForRequest(StubRequest(
- 'PROPFIND',
- '/calendars/users/cdaboo/',
- '/principals/users/cdaboo/'))
-
- d1.addCallback(self.assertEquals, None)
- return d1
-
d = self.rc.cacheResponseForRequest(
StubRequest('PROPFIND',
- '/principals/users/dreid/',
- '/principals/users/dreid/'),
- StubResponse(200, {}, "Foobar"))
+ '/principals/__uids__/dreid/',
+ '/principals/__uids__/dreid/'),
+ expected_response)
d.addCallback(_assertResponse)
return d
-# def test_cacheExpirationBenchmark(self):
-# self.rc.CACHE_SIZE = 70000
-# import time
-# self.rc._responses = {}
-# self.rc._accessList = []
-
-# for x in xrange(0, self.rc.CACHE_SIZE):
-# req = StubRequest('PROPFIND',
-# '/principals/users/user%d' % (x,),
-# '/principals/users/user%d' % (x,))
-# self.rc._responses[req] = (
-# 'pTokenUser%d' % (x,), 'rTokenUser%d' % (x,), 0,
-# (200, {}, 'foobar'))
-
-# self.rc._accessList.append(req)
-
-# def assertTime(result, startTime):
-# duration = time.time() - startTime
-
-# self.failUnless(
-# duration < 0.01,
-# "Took to long to add to the cache: %r" % (duration,))
-
-# startTime = time.time()
-
-# d = self.rc.cacheResponseForRequest(
-# StubRequest('PROPFIND',
-# '/principals/users/dreid/',
-# '/principals/users/dreid/'),
-# StubResponse(200, {}, 'Foobar'))
-
-# d.addCallback(assertTime, startTime)
-# return d
-
-
class MemcacheResponseCacheTests(BaseCacheTestMixin, TestCase):
def setUp(self):
+ super(MemcacheResponseCacheTests, self).setUp()
+
memcacheStub = InMemoryMemcacheProtocol()
self.rc = MemcacheResponseCache(None, None, None, None)
self.rc.logger.setLevel('debug')
self.tokens = {}
- self.tokens['/calendars/users/cdaboo/'] = 'uriToken0'
- self.tokens['/principals/users/cdaboo/'] = 'principalToken0'
- self.tokens['/principals/users/dreid/'] = 'principalTokenX'
+ self.tokens['/calendars/__uids__/cdaboo/'] = 'uriToken0'
+ self.tokens['/principals/__uids__/cdaboo/'] = 'principalToken0'
+ self.tokens['/principals/__uids__/dreid/'] = 'principalTokenX'
def _getToken(uri):
return succeed(self.tokens.get(uri))
@@ -388,8 +327,8 @@
expected_key = hashlib.md5(':'.join([str(t) for t in (
'PROPFIND',
- '/principals/users/cdaboo/',
- '/calendars/users/cdaboo/',
+ '/principals/__uids__/cdaboo/',
+ '/calendars/__uids__/cdaboo/',
'1',
hash('foobar'),
)])).hexdigest()
@@ -404,3 +343,5 @@
self.expected_response[2]))))
self.rc._memcacheProtocol = memcacheStub
+
+
Modified: CalendarServer/trunk/twistedcaldav/test/test_static.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/test_static.py 2008-05-29 23:05:56 UTC (rev 2513)
+++ CalendarServer/trunk/twistedcaldav/test/test_static.py 2008-05-30 00:10:24 UTC (rev 2514)
@@ -17,7 +17,7 @@
from twisted.trial.unittest import TestCase
from twistedcaldav.static import CalendarHomeFile, CalDAVFile
-from twistedcaldav.cache import XattrCacheChangeNotifier
+from twistedcaldav.cache import DisabledCacheNotifier
from twistedcaldav.test.util import StubCacheChangeNotifier
class StubParentResource(object):
@@ -34,7 +34,7 @@
def test_hasCacheNotifier(self):
self.failUnless(isinstance(self.calendarHome.cacheNotifier,
- XattrCacheChangeNotifier))
+ DisabledCacheNotifier))
def test_childrenHaveCacheNotifier(self):
Modified: CalendarServer/trunk/twistedcaldav/test/util.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/test/util.py 2008-05-29 23:05:56 UTC (rev 2513)
+++ CalendarServer/trunk/twistedcaldav/test/util.py 2008-05-30 00:10:24 UTC (rev 2514)
@@ -48,6 +48,9 @@
class StubCacheChangeNotifier(object):
+ def __init__(self, *args, **kwargs):
+ pass
+
changedCount = 0
def changed(self):
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20080529/781576f1/attachment-0001.htm
More information about the calendarserver-changes
mailing list