[CalendarServer-changes] [4121] CalendarServer/trunk/twistedcaldav/directory
source_changes at macosforge.org
source_changes at macosforge.org
Thu Apr 30 16:09:51 PDT 2009
Revision: 4121
http://trac.macosforge.org/projects/calendarserver/changeset/4121
Author: sagen at apple.com
Date: 2009-04-30 16:09:50 -0700 (Thu, 30 Apr 2009)
Log Message:
-----------
Replacing the email-address index with a calendar-user-address index, to allow multiple records with the same email address, but not calendar user address. Also, we only index (internally and in memcached) on the attribute+value that we faulted the record in on, in order to avoid index collisions.
Modified Paths:
--------------
CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py
CalendarServer/trunk/twistedcaldav/directory/cachingappleopendirectory.py
CalendarServer/trunk/twistedcaldav/directory/cachingdirectory.py
CalendarServer/trunk/twistedcaldav/directory/cachingxmlfile.py
CalendarServer/trunk/twistedcaldav/directory/directory.py
CalendarServer/trunk/twistedcaldav/directory/test/test_cachedirectory.py
CalendarServer/trunk/twistedcaldav/directory/test/test_opendirectoryrecords.py
Modified: CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py 2009-04-30 21:49:32 UTC (rev 4120)
+++ CalendarServer/trunk/twistedcaldav/directory/appleopendirectory.py 2009-04-30 23:09:50 UTC (rev 4121)
@@ -42,6 +42,7 @@
from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord
from twistedcaldav.directory.directory import DirectoryError, UnknownRecordTypeError
+from twistedcaldav.scheduling.cuaddress import normalizeCUAddr
class OpenDirectoryService(DirectoryService):
"""
@@ -280,9 +281,17 @@
self._storage(recordType)["disabled names"].add(shortName)
return record
- def recordWithEmailAddress(self, emailAddress):
- return self._recordWithAttribute("emails", "disabled emails", "email", emailAddress)
+ def recordWithCalendarUserAddress(self, address):
+ address = normalizeCUAddr(address)
+ record = None
+ if address.startswith("urn:uuid:"):
+ guid = address[9:]
+ record = self.recordWithGUID(guid)
+ elif address.startswith("mailto:"):
+ record = self._recordWithAttribute("cuas", "disabled cuas", "cua", address)
+ return record if record and record.enabledForCalendaring else None
+
def recordWithGUID(self, guid):
return self._recordWithAttribute("guids", "disabled guids", "guid", guid)
@@ -510,13 +519,13 @@
records = {}
guids = {}
authIDs = {}
- emails = {}
+ cuas = {}
disabledNames = set()
disabledGUIDs = set()
disabledAuthIDs = set()
- disabledEmails = set()
-
+ disabledCUAs = set()
+
if recordType == self.recordType_groups:
groupsForGUID = {}
elif recordType in (self.recordType_resources, self.recordType_locations):
@@ -528,13 +537,13 @@
records = storage["records"]
guids = storage["guids"]
authIDs = storage["authIDs"]
- emails = storage["emails"]
+ cuas = storage["cuas"]
disabledNames = storage["disabled names"]
disabledGUIDs = storage["disabled guids"]
disabledAuthIDs = storage["disabled authIDs"]
- disabledEmails = storage["disabled emails"]
-
+ disabledCUAs = storage["disabled cuas"]
+
if recordType == self.recordType_groups:
groupsForGUID = storage["groupsForGUID"]
elif recordType in (self.recordType_resources, self.recordType_locations):
@@ -657,7 +666,7 @@
disabledGUIDs.add(guid)
disabledNames.update(record.shortNames)
disabledAuthIDs.update(record.authIDs)
- disabledEmails.update(record.emailAddresses)
+ disabledCUAs.update(record.calendarUserAddresses)
if guid in guids:
try:
@@ -674,9 +683,9 @@
del authIDs[authID]
except KeyError:
pass
- for email in record.emailAddresses:
+ for cua in record.calendarUserAddresses:
try:
- del emails[email]
+ del cuas[cua]
except KeyError:
pass
@@ -747,28 +756,31 @@
else:
authIDs[authID] = record
- # Index non-duplicate emails
- def disableEmail(emailAddress, record):
- self.log_warn("Email address %s disabled due to conflict for record: %s"
- % (emailAddress, record))
+ # Index non-duplicate CUAs
+ def disableCUA(cua, record):
+ self.log_warn("CUA %s disabled due to conflict for record: %s"
+ % (cua, record))
- record.emailAddresses.remove(emailAddress)
- disabledEmails.add(emailAddress)
+ record.calendarUserAddresses.remove(cua)
+ disabledCUAs.add(cua)
- if emailAddress in emails:
- del emails[emailAddress]
+ if cua in cuas:
+ del cuas[cua]
+
+ if cua in records:
+ del records[cua]
- for email in frozenset(recordEmailAddresses):
- if email in disabledEmails:
- disableEmail(email, record)
+ for cua in frozenset(calendarUserAddresses):
+ if cua in disabledCUAs:
+ disableCUA(cua, record)
else:
# Check for duplicates
- existing_record = emails.get(email)
+ existing_record = cuas.get(cua)
if existing_record is not None:
- disableEmail(email, record)
- disableEmail(email, existing_record)
+ disableCUA(cua, record)
+ disableCUA(cua, existing_record)
else:
- emails[email] = record
+ cuas[cua] = record
if lookup is None:
#
@@ -779,11 +791,11 @@
"records" : records,
"guids" : guids,
"authIDs" : authIDs,
- "emails" : emails,
+ "cuas" : cuas,
"disabled names" : disabledNames,
"disabled guids" : disabledGUIDs,
"disabled authIDs" : disabledAuthIDs,
- "disabled emails" : disabledEmails,
+ "disabled cuas" : disabledCUAs,
}
# Add group indexing if needed
@@ -819,6 +831,7 @@
"Added %d (%d enabled) records to %s OD record cache; expires in %d seconds"
% (len(self._records[recordType]["guids"]), enabled_count, recordType, cacheTimeout)
)
+ print self._records[recordType]
def _queryDirectory(self, recordType, lookup=None):
attrs = [
@@ -891,15 +904,28 @@
query = None
if lookup is not None:
- queryattr = {
- "shortName" : dsattributes.kDSNAttrRecordName,
- "guid" : dsattributes.kDS1AttrGeneratedUID,
- "authID" : dsattributes.kDSNAttrAltSecurityIdentities,
- "email" : dsattributes.kDSNAttrEMailAddress,
- }.get(lookup[0])
- assert queryattr is not None, "Invalid type for record faulting query"
- query = dsquery.match(queryattr, lookup[1], dsattributes.eDSExact)
+ indexType, indexKey = lookup
+ origIndexKey = indexKey
+ if indexType == "cua":
+ # The directory doesn't contain CUAs, so we need to convert
+ # the CUA to the appropriate field name and value:
+ queryattr, indexKey = cuAddressConverter(indexKey)
+ # queryattr will be one of:
+ # guid, emailAddresses, or recordName
+ # ...which will need to be mapped to DS
+ queryattr = self._ODFields[queryattr]['odField']
+
+ else:
+ queryattr = {
+ "shortName" : dsattributes.kDSNAttrRecordName,
+ "guid" : dsattributes.kDS1AttrGeneratedUID,
+ "authID" : dsattributes.kDSNAttrAltSecurityIdentities,
+ }.get(indexType)
+ assert queryattr is not None, "Invalid type for record faulting query"
+
+ query = dsquery.match(queryattr, indexKey, dsattributes.eDSExact)
+
try:
if query:
self.log_debug("opendirectory.queryRecordsWithAttribute_list(%r,%r,%r,%r,%r,%r,%r)" % (
Modified: CalendarServer/trunk/twistedcaldav/directory/cachingappleopendirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/cachingappleopendirectory.py 2009-04-30 21:49:32 UTC (rev 4120)
+++ CalendarServer/trunk/twistedcaldav/directory/cachingappleopendirectory.py 2009-04-30 23:09:50 UTC (rev 4121)
@@ -44,6 +44,7 @@
CachingDirectoryRecord
from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord
from twistedcaldav.directory.directory import DirectoryError, UnknownRecordTypeError
+from twistedcaldav.directory.principal import cuAddressConverter
class OpenDirectoryService(CachingDirectoryService):
"""
@@ -444,6 +445,26 @@
dsattributes.kDSNAttrMetaNodeLocation,
]
+ origIndexKey = indexKey
+ if indexType == self.INDEX_TYPE_CUA:
+ # The directory doesn't contain CUAs, so we need to convert
+ # the CUA to the appropriate field name and value:
+ queryattr, indexKey = cuAddressConverter(indexKey)
+ # queryattr will be one of:
+ # guid, emailAddresses, or recordName
+ # ...which will need to be mapped to DS
+ queryattr = self._ODFields[queryattr]['odField']
+
+ else:
+ queryattr = {
+ self.INDEX_TYPE_SHORTNAME : dsattributes.kDSNAttrRecordName,
+ self.INDEX_TYPE_GUID : dsattributes.kDS1AttrGeneratedUID,
+ }.get(indexType)
+ assert queryattr is not None, "Invalid type for record faulting query"
+
+ query = dsquery.match(queryattr, indexKey, dsattributes.eDSExact)
+
+
listRecordTypes = []
for recordType in recordTypes:
if recordType == DirectoryService.recordType_users:
@@ -455,15 +476,13 @@
attrs.append(dsattributes.kDSNAttrNestedGroups)
elif recordType == DirectoryService.recordType_locations:
- # Email addresses and locations don't mix
- if indexType != self.INDEX_TYPE_EMAIL:
+ if queryattr != dsattributes.kDSNAttrEMailAddress:
listRecordTypes.append(dsattributes.kDSStdRecordTypePlaces)
# MOR: possibly can be removed
attrs.append(dsattributes.kDSNAttrResourceInfo)
elif recordType == DirectoryService.recordType_resources:
- # Email addresses and resources don't mix
- if indexType != self.INDEX_TYPE_EMAIL:
+ if queryattr != dsattributes.kDSNAttrEMailAddress:
listRecordTypes.append(dsattributes.kDSStdRecordTypeResources)
# MOR: possibly can be removed
attrs.append(dsattributes.kDSNAttrResourceInfo)
@@ -471,13 +490,6 @@
else:
raise UnknownRecordTypeError("Unknown Open Directory record type: %s" % (recordType))
- queryattr = {
- self.INDEX_TYPE_SHORTNAME : dsattributes.kDSNAttrRecordName,
- self.INDEX_TYPE_GUID : dsattributes.kDS1AttrGeneratedUID,
- self.INDEX_TYPE_EMAIL : dsattributes.kDSNAttrEMailAddress,
- }.get(indexType)
- assert queryattr is not None, "Invalid type for record faulting query"
- query = dsquery.match(queryattr, indexKey, dsattributes.eDSExact)
try:
self.log_debug("opendirectory.queryRecordsWithAttribute_list(%r,%r,%r,%r,%r,%r,%r)" % (
@@ -508,8 +520,6 @@
self.log_error("Open Directory (node=%s) error: %s" % (self.realmName, str(ex)))
raise
- enabled_count = 0
-
def _uniqueTupleFromAttribute(attribute):
if attribute:
if isinstance(attribute, str):
@@ -528,7 +538,10 @@
return set([item.lower() if lower else item for item in attribute])
else:
return ()
-
+
+ enabledRecords = []
+ disabledRecords = []
+
for (recordShortName, value) in results:
# Now get useful record info.
@@ -607,7 +620,6 @@
enabledForCalendaring = True
if enabledForCalendaring:
- enabled_count += 1
calendarUserAddresses = self._calendarUserAddresses(recordType, value)
else:
# Some records we want to keep even though they are not enabled for calendaring.
@@ -658,8 +670,21 @@
enabledForCalendaring = enabledForCalendaring,
memberGUIDs = memberGUIDs,
)
- self.recordCacheForType(recordType).addRecord(record)
+ if enabledForCalendaring:
+ enabledRecords.append(record)
+ else:
+ disabledRecords.append(record)
+ record = None
+ if len(enabledRecords) == 1:
+ record = enabledRecords[0]
+ elif len(enabledRecords) == 0 and len(disabledRecords) == 1:
+ record = disabledRecords[0]
+
+ if record:
+ self.log_debug("Storing (%s %s) %s in internal cache" % (indexType, origIndexKey, record))
+ self.recordCacheForType(recordType).addRecord(record, indexType, origIndexKey)
+
def _parseResourceInfo(self, plist, guid, recordType, shortname):
"""
Parse OD ResourceInfo attribute and extract information that the server needs.
Modified: CalendarServer/trunk/twistedcaldav/directory/cachingdirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/cachingdirectory.py 2009-04-30 21:49:32 UTC (rev 4120)
+++ CalendarServer/trunk/twistedcaldav/directory/cachingdirectory.py 2009-04-30 23:09:50 UTC (rev 4121)
@@ -30,8 +30,10 @@
import memcacheclient
import base64
-from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord, DirectoryError
from twistedcaldav.config import config
+from twistedcaldav.directory.directory import DirectoryService, DirectoryRecord, DirectoryError
+from twistedcaldav.log import LoggingMixIn
+from twistedcaldav.scheduling.cuaddress import normalizeCUAddr
class RecordTypeCache(object):
@@ -44,19 +46,16 @@
self.directoryService = directoryService
self.recordType = recordType
- def addRecord(self, record):
+ def addRecord(self, record, indexType, indexKey, useMemcache=True):
raise NotImplementedError()
def removeRecord(self, record):
raise NotImplementedError()
- def replaceRecord(self, oldRecord, newRecord):
- raise NotImplementedError()
-
def findRecord(self, indexType, indexKey):
raise NotImplementedError()
-class DictRecordTypeCache(RecordTypeCache):
+class DictRecordTypeCache(RecordTypeCache, LoggingMixIn):
"""
Cache implementation using a dict. Does not share the cache with other instances.
"""
@@ -68,28 +67,23 @@
self.recordsIndexedBy = {
CachingDirectoryService.INDEX_TYPE_GUID : {},
CachingDirectoryService.INDEX_TYPE_SHORTNAME: {},
- CachingDirectoryService.INDEX_TYPE_EMAIL : {},
+ CachingDirectoryService.INDEX_TYPE_CUA : {},
CachingDirectoryService.INDEX_TYPE_AUTHID : {},
}
- def addRecord(self, record):
-
+ def addRecord(self, record, indexType, indexKey, useMemcache=True):
+
+ useMemcache == useMemcache and config.Memcached.ClientEnabled
+
self.records.add(record)
- for indexType in self.directoryService.indexTypes():
- try:
- indexData = getattr(record, CachingDirectoryService.indexTypeToRecordAttribute[indexType])
- except AttributeError:
- continue
- if isinstance(indexData, str):
- indexData = (indexData,)
- if type(indexData) in (types.ListType, types.TupleType, set):
- for item in indexData:
- self.recordsIndexedBy[indexType][item] = record
- elif indexData is None:
- pass
- else:
- raise AssertionError("Data from record attribute must be str, list or tuple")
-
+
+ self.recordsIndexedBy[indexType][indexKey] = record
+ if useMemcache:
+ key = "dir|%s|%s" % (indexType, indexKey)
+ self.log_debug("Memcache: storing %s" % (key,))
+ self.directoryService.memcacheSet(key, record)
+
+
def removeRecord(self, record):
if record in self.records:
@@ -110,10 +104,6 @@
else:
raise AssertionError("Data from record attribute must be str, list or tuple")
- def replaceRecord(self, oldRecord, newRecord):
- self.removeRecord(oldRecord)
- self.addRecord(newRecord)
-
def findRecord(self, indexType, indexKey):
return self.recordsIndexedBy[indexType].get(indexKey)
@@ -126,13 +116,13 @@
INDEX_TYPE_GUID = "guid"
INDEX_TYPE_SHORTNAME = "shortname"
- INDEX_TYPE_EMAIL = "email"
+ INDEX_TYPE_CUA = "cua"
INDEX_TYPE_AUTHID = "authid"
indexTypeToRecordAttribute = {
"guid" : "guid",
"shortname": "shortNames",
- "email" : "emailAddresses",
+ "cua" : "calendarUserAddresses",
"authid" : "authIDs",
}
@@ -209,7 +199,7 @@
return (
CachingDirectoryService.INDEX_TYPE_GUID,
CachingDirectoryService.INDEX_TYPE_SHORTNAME,
- CachingDirectoryService.INDEX_TYPE_EMAIL,
+ CachingDirectoryService.INDEX_TYPE_CUA,
CachingDirectoryService.INDEX_TYPE_AUTHID,
)
@@ -222,9 +212,17 @@
def recordWithShortName(self, recordType, shortName):
return self._lookupRecord((recordType,), CachingDirectoryService.INDEX_TYPE_SHORTNAME, shortName)
- def recordWithEmailAddress(self, emailAddress):
- return self._lookupRecord(None, CachingDirectoryService.INDEX_TYPE_EMAIL, emailAddress)
+ def recordWithCalendarUserAddress(self, address):
+ address = normalizeCUAddr(address)
+ record = None
+ if address.startswith("urn:uuid:"):
+ guid = address[9:]
+ record = self.recordWithGUID(guid)
+ elif address.startswith("mailto:"):
+ record = self._lookupRecord(None, CachingDirectoryService.INDEX_TYPE_CUA, address)
+ return record if record and record.enabledForCalendaring else None
+
def recordWithAuthID(self, authID):
return self._lookupRecord(None, CachingDirectoryService.INDEX_TYPE_AUTHID, authID)
@@ -273,7 +271,7 @@
self.log_debug("Memcache: miss %s" % (key,))
else:
self.log_debug("Memcache: hit %s" % (key,))
- self.recordCacheForType(record.recordType).addRecord(record)
+ self.recordCacheForType(record.recordType).addRecord(record, indexType, indexKey, useMemcache=False)
return record
# Check negative memcache
@@ -291,24 +289,6 @@
record = lookup()
if record:
self.log_debug("Found record for attribute '%s' with value '%s'" % (indexType, indexKey,))
-
- if config.Memcached.ClientEnabled:
- # share with others via memcache
- for shortName in record.shortNames:
- key = "dir|%s|%s" % (CachingDirectoryService.INDEX_TYPE_SHORTNAME, shortName)
- self.log_debug("Memcache: storing %s" % (key,))
- self.memcacheSet(key, record)
- for emailAddress in record.emailAddresses:
- key = "dir|%s|%s" % (CachingDirectoryService.INDEX_TYPE_EMAIL, emailAddress)
- self.log_debug("Memcache: storing %s" % (key,))
- self.memcacheSet(key, record)
- for authID in record.authIDs:
- key = "dir|%s|%s" % (CachingDirectoryService.INDEX_TYPE_AUTHID, authID)
- self.log_debug("Memcache: storing %s" % (key,))
- self.memcacheSet(key, record)
- key = "dir|%s|%s" % (CachingDirectoryService.INDEX_TYPE_GUID, record.guid)
- self.log_debug("Memcache: storing %s" % (key,))
- self.memcacheSet(key, record)
return record
Modified: CalendarServer/trunk/twistedcaldav/directory/cachingxmlfile.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/cachingxmlfile.py 2009-04-30 21:49:32 UTC (rev 4120)
+++ CalendarServer/trunk/twistedcaldav/directory/cachingxmlfile.py 2009-04-30 23:09:50 UTC (rev 4121)
@@ -76,8 +76,8 @@
matched = indexKey == xmlPrincipal.guid
elif indexType == self.INDEX_TYPE_SHORTNAME:
matched = indexKey in xmlPrincipal.shortNames
- elif indexType == self.INDEX_TYPE_EMAIL:
- matched = indexKey in xmlPrincipal.emailAddresses
+ elif indexType == self.INDEX_TYPE_CUA:
+ matched = indexKey in xmlPrincipal.calendarUserAddresses
if matched:
record = XMLDirectoryRecord(
Modified: CalendarServer/trunk/twistedcaldav/directory/directory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/directory.py 2009-04-30 21:49:32 UTC (rev 4120)
+++ CalendarServer/trunk/twistedcaldav/directory/directory.py 2009-04-30 23:09:50 UTC (rev 4121)
@@ -149,18 +149,14 @@
guid = address[9:]
record = self.recordWithGUID(guid)
elif address.startswith("mailto:"):
- email = address[7:]
- record = self.recordWithEmailAddress(email)
+ for record in self.allRecords():
+ if address in record.calendarUserAddresses:
+ break
+ else:
+ return None
return record if record and record.enabledForCalendaring else None
- def recordWithEmailAddress(self, email):
- for record in self.allRecords():
- if email in record.emailAddresses:
- return record
-
- return None
-
def allRecords(self):
for recordType in self.recordTypes():
for record in self.listRecords(recordType):
Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_cachedirectory.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_cachedirectory.py 2009-04-30 21:49:32 UTC (rev 4120)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_cachedirectory.py 2009-04-30 23:09:50 UTC (rev 4121)
@@ -42,7 +42,7 @@
cacheIt = False
if indexType in (
CachingDirectoryService.INDEX_TYPE_SHORTNAME,
- CachingDirectoryService.INDEX_TYPE_EMAIL,
+ CachingDirectoryService.INDEX_TYPE_CUA,
CachingDirectoryService.INDEX_TYPE_AUTHID,
):
if indexKey in record[indexType]:
@@ -62,10 +62,11 @@
firstName = "",
lastName = "",
emailAddresses = record.get("email"),
- calendarUserAddresses = record.get("email"),
+ calendarUserAddresses = record.get("cua"),
enabledForCalendaring = True,
)
- self.recordCacheForType(recordType).addRecord(cacheRecord)
+ self.recordCacheForType(recordType).addRecord(cacheRecord,
+ indexType, indexKey)
class CachingDirectoryTest(TestCase):
@@ -109,6 +110,7 @@
"guid": guid,
"shortname": shortNames,
"email": emails,
+ "cua": tuple(["mailto:%s" % email for email in emails]),
"authid": tuple(["Kerberos:%s" % email for email in emails])
}
@@ -202,8 +204,8 @@
def test_cacheoneemail(self):
self.dummyRecords()
- self.assertTrue(self.service.recordWithEmailAddress(
- "user03 at example.com"
+ self.assertTrue(self.service.recordWithCalendarUserAddress(
+ "mailto:user03 at example.com"
) is not None)
self.assertTrue(self.service.queried)
self.verifyRecords(DirectoryService.recordType_users, set((
@@ -215,8 +217,8 @@
# Make sure it really is cached and won't cause another query
self.service.queried = False
- self.assertTrue(self.service.recordWithEmailAddress(
- "user03 at example.com"
+ self.assertTrue(self.service.recordWithCalendarUserAddress(
+ "mailto:user03 at example.com"
) is not None)
self.assertFalse(self.service.queried)
Modified: CalendarServer/trunk/twistedcaldav/directory/test/test_opendirectoryrecords.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/directory/test/test_opendirectoryrecords.py 2009-04-30 21:49:32 UTC (rev 4120)
+++ CalendarServer/trunk/twistedcaldav/directory/test/test_opendirectoryrecords.py 2009-04-30 23:09:50 UTC (rev 4121)
@@ -308,7 +308,7 @@
self.assertFalse(self.service.recordWithShortName(DirectoryService.recordType_users, "user02").authIDs)
self.assertFalse(self.service.recordWithShortName(DirectoryService.recordType_users, "user03").authIDs)
- def test_duplicateEmail(self):
+ def test_duplicateCUAs(self):
self.loadRecords({
DirectoryService.recordType_users: [
fakeODRecord("User 01"),
@@ -320,9 +320,9 @@
self.verifyRecords(DirectoryService.recordType_users, ("user01", "user02", "user03"))
self.verifyDisabledRecords(DirectoryService.recordType_users, (), ())
- self.assertTrue (self.service.recordWithShortName(DirectoryService.recordType_users, "user01").emailAddresses)
- self.assertFalse(self.service.recordWithShortName(DirectoryService.recordType_users, "user02").emailAddresses)
- self.assertFalse(self.service.recordWithShortName(DirectoryService.recordType_users, "user03").emailAddresses)
+ self.assertTrue (self.service.recordWithShortName(DirectoryService.recordType_users, "user01").calendarUserAddresses)
+ self.assertFalse("mailto:shared at example.com" in self.service.recordWithShortName(DirectoryService.recordType_users, "user02").calendarUserAddresses)
+ self.assertFalse("mailto:shared at example.com" in self.service.recordWithShortName(DirectoryService.recordType_users, "user03").calendarUserAddresses)
def test_duplicateRecords(self):
self.loadRecords({
@@ -648,7 +648,7 @@
self.verifyQuery(self.service.recordWithAuthID, "Kerberos:location05 at example.com")
self.verifyNoQuery(self.service.recordWithAuthID, "Kerberos:location05 at example.com")
- def test_negativeCacheEmailAddress(self):
+ def test_negativeCacheCalendarUserAddress(self):
self.loadRecords({
DirectoryService.recordType_users: [
fakeODRecord("User 01"),
@@ -676,21 +676,22 @@
],
})
- self.assertTrue(self.service.recordWithEmailAddress("user01 at example.com"))
- self.verifyQuery(self.service.recordWithEmailAddress, "user05 at example.com")
- self.verifyNoQuery(self.service.recordWithEmailAddress, "user05 at example.com")
+ self.assertTrue(self.service.recordWithCalendarUserAddress("mailto:user01 at example.com"))
+ self.verifyQuery(self.service.recordWithCalendarUserAddress, "mailto:user05 at example.com")
+ self.verifyNoQuery(self.service.recordWithCalendarUserAddress, "mailto:user05 at example.com")
- self.assertTrue(self.service.recordWithEmailAddress("group01 at example.com"))
- self.verifyQuery(self.service.recordWithEmailAddress, "group05 at example.com")
- self.verifyNoQuery(self.service.recordWithEmailAddress, "group05 at example.com")
+ # Groups don't have CUAs
+ # self.assertTrue(self.service.recordWithCalendarUserAddress("mailto:group01 at example.com"))
+ # self.verifyQuery(self.service.recordWithCalendarUserAddress, "mailto:group05 at example.com")
+ # self.verifyNoQuery(self.service.recordWithCalendarUserAddress, "mailto:group05 at example.com")
- self.assertTrue(self.service.recordWithEmailAddress("resource01 at example.com"))
- self.verifyQuery(self.service.recordWithEmailAddress, "resource05 at example.com")
- self.verifyNoQuery(self.service.recordWithEmailAddress, "resource05 at example.com")
+ self.assertTrue(self.service.recordWithCalendarUserAddress("mailto:resource01 at example.com"))
+ self.verifyQuery(self.service.recordWithCalendarUserAddress, "mailto:resource05 at example.com")
+ self.verifyNoQuery(self.service.recordWithCalendarUserAddress, "mailto:resource05 at example.com")
- self.assertTrue(self.service.recordWithEmailAddress("location01 at example.com"))
- self.verifyQuery(self.service.recordWithEmailAddress, "location05 at example.com")
- self.verifyNoQuery(self.service.recordWithEmailAddress, "location05 at example.com")
+ self.assertTrue(self.service.recordWithCalendarUserAddress("mailto:location01 at example.com"))
+ self.verifyQuery(self.service.recordWithCalendarUserAddress, "mailto:location05 at example.com")
+ self.verifyNoQuery(self.service.recordWithCalendarUserAddress, "mailto:location05 at example.com")
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090430/78bc7320/attachment-0001.html>
More information about the calendarserver-changes
mailing list