[CalendarServer-changes] [9369] CalendarServer/trunk/contrib/performance/loadtest
source_changes at macosforge.org
source_changes at macosforge.org
Mon Jun 18 11:16:57 PDT 2012
Revision: 9369
http://trac.macosforge.org/projects/calendarserver/changeset/9369
Author: cdaboo at apple.com
Date: 2012-06-18 11:16:57 -0700 (Mon, 18 Jun 2012)
Log Message:
-----------
Remove some hard-coded dependencies on specific paths and calendar-user addresses.
Modified Paths:
--------------
CalendarServer/trunk/contrib/performance/loadtest/config.dist.plist
CalendarServer/trunk/contrib/performance/loadtest/config.plist
CalendarServer/trunk/contrib/performance/loadtest/ical.py
CalendarServer/trunk/contrib/performance/loadtest/profiles.py
CalendarServer/trunk/contrib/performance/loadtest/sim.py
CalendarServer/trunk/contrib/performance/loadtest/test_ical.py
CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py
Modified: CalendarServer/trunk/contrib/performance/loadtest/config.dist.plist
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/config.dist.plist 2012-06-18 18:11:20 UTC (rev 9368)
+++ CalendarServer/trunk/contrib/performance/loadtest/config.dist.plist 2012-06-18 18:16:57 UTC (rev 9369)
@@ -34,7 +34,7 @@
<!-- Identify the server to be load tested. -->
<key>server</key>
- <string>https://127.0.0.1:8443/</string>
+ <string>https://127.0.0.1:8443</string>
<!-- The template URI for doing initial principal lookup on. -->
<key>principalPathTemplate</key>
Modified: CalendarServer/trunk/contrib/performance/loadtest/config.plist
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/config.plist 2012-06-18 18:11:20 UTC (rev 9368)
+++ CalendarServer/trunk/contrib/performance/loadtest/config.plist 2012-06-18 18:16:57 UTC (rev 9369)
@@ -21,7 +21,7 @@
<dict>
<!-- Identify the server to be load tested. -->
<key>server</key>
- <string>https://127.0.0.1:8443/</string>
+ <string>https://127.0.0.1:8443</string>
<!-- The template URI for doing initial principal lookup on. -->
<key>principalPathTemplate</key>
Modified: CalendarServer/trunk/contrib/performance/loadtest/ical.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/ical.py 2012-06-18 18:11:20 UTC (rev 9368)
+++ CalendarServer/trunk/contrib/performance/loadtest/ical.py 2012-06-18 18:16:57 UTC (rev 9369)
@@ -380,6 +380,9 @@
# The principalURL found during discovery
self.principalURL = None
+ # The principal collection found during startup
+ self.principalCollection = None
+
# Keep track of the events on this account, keys are event
# URIs (which are unambiguous across different calendars
# because they start with the uri of the calendar they are
@@ -495,7 +498,7 @@
response = yield self._request(
allowedStatus,
'PROPFIND',
- self.root + url[1:].encode('utf-8'),
+ self.root + url.encode('utf-8'),
hdrs,
StringProducer(body),
method_label=method_label,
@@ -516,7 +519,7 @@
response = yield self._request(
(OK, MULTI_STATUS,),
'PROPPATCH',
- self.root + url[1:].encode('utf-8'),
+ self.root + url.encode('utf-8'),
hdrs,
StringProducer(body),
method_label=method_label,
@@ -540,7 +543,7 @@
response = yield self._request(
allowedStatus,
'REPORT',
- self.root + url[1:].encode('utf-8'),
+ self.root + url.encode('utf-8'),
hdrs,
StringProducer(body),
method_label=method_label,
@@ -639,6 +642,36 @@
returnValue((calendars, result,))
+ @inlineCallbacks
+ def _extractPrincipalDetails(self):
+ # Using the actual principal URL, retrieve principal information
+ principal = yield self._principalPropfind()
+
+ hrefs = principal.getHrefProperties()
+
+ # Remember our outbox and ignore notifications
+ self.outbox = hrefs[caldavxml.schedule_outbox_URL].toString()
+ self.notificationURL = None
+
+ # Remember our own email-like principal address
+ cuaddrs = hrefs[caldavxml.calendar_user_address_set]
+ if isinstance(cuaddrs, basestring):
+ cuaddrs = (cuaddrs,)
+ for cuaddr in cuaddrs:
+ if cuaddr.toString().startswith(u"mailto:"):
+ self.email = cuaddr.toString()
+ elif cuaddr.toString().startswith(u"urn:"):
+ self.uuid = cuaddr.toString()
+ if self.email is None:
+ raise ValueError("Cannot operate without a mail-style principal URL")
+
+ # Do another kind of thing I guess
+ self.principalCollection = hrefs[davxml.principal_collection_set].toString()
+ yield self._principalSearchPropertySetReport(self.principalCollection)
+
+ returnValue(principal)
+
+
def _extractCalendars(self, results, calendarHome=None):
"""
Parse a calendar home PROPFIND response and create local state
@@ -1212,7 +1245,7 @@
def _makeSelfAttendee(self):
attendee = Property(
name=u'ATTENDEE',
- value=self.uuid,
+ value=self.email,
params={
'CN': self.record.commonName,
'CUTYPE': 'INDIVIDUAL',
@@ -1225,7 +1258,7 @@
def _makeSelfOrganizer(self):
organizer = Property(
name=u'ORGANIZER',
- value=self.uuid,
+ value=self.email,
params={
'CN': self.record.commonName,
},
@@ -1263,7 +1296,7 @@
response = yield self._request(
(NO_CONTENT, PRECONDITION_FAILED,),
'PUT',
- self.root + href[1:].encode('utf-8'),
+ self.root + href.encode('utf-8'),
Headers({
'content-type': ['text/calendar'],
'if-match': [event.etag]}),
@@ -1286,30 +1319,34 @@
# prefix = name[:4].lower()
prefix = random.choice(["chris", "cyru", "dre", "eric", "morg",
"well", "wilfr", "witz"])
+
+ email = attendee.value()
+ if email.startswith("mailto:"):
+ email = email[7:]
+ elif attendee.hasParameter('EMAIL'):
+ email = attendee.parameterValue('EMAIL').encode("utf-8")
- email = attendee.parameterValue('EMAIL').encode("utf-8")
-
# First try to discover some names to supply to the
# auto-completion
- response = yield self._request(
- MULTI_STATUS, 'REPORT', self.root + 'principals/',
- Headers({'content-type': ['text/xml']}),
- StringProducer(self._USER_LIST_PRINCIPAL_PROPERTY_SEARCH % {
- 'displayname': prefix,
- 'email': prefix,
- 'firstname': prefix,
- 'lastname': prefix,
- }),
+ yield self._report(
+ self.principalCollection,
+ self._USER_LIST_PRINCIPAL_PROPERTY_SEARCH % {
+ 'displayname': prefix,
+ 'email': prefix,
+ 'firstname': prefix,
+ 'lastname': prefix,
+ },
+ depth=None,
method_label="REPORT{psearch}",
- )
- yield readBody(response)
+ )
# Now learn about the attendee's availability
yield self.requestAvailability(
vevent.mainComponent().getStartDateUTC(),
vevent.mainComponent().getEndDateUTC(),
[self.email, u'mailto:' + email],
- [vevent.resourceUID()])
+ [vevent.resourceUID()]
+ )
@inlineCallbacks
@@ -1338,7 +1375,7 @@
response = yield self._request(
okCodes,
'PUT',
- self.root + href[1:].encode('utf-8'),
+ self.root + href.encode('utf-8'),
headers, StringProducer(vevent.getTextWithTimezones(includeTimezones=True)),
method_label="PUT{attendee-%s}" % (label_suffix,),
)
@@ -1357,7 +1394,7 @@
response = yield self._request(
NO_CONTENT,
'DELETE',
- self.root + href[1:].encode('utf-8'),
+ self.root + href.encode('utf-8'),
method_label="DELETE{event}",
)
returnValue(response)
@@ -1379,7 +1416,7 @@
response = yield self._request(
CREATED,
'PUT',
- self.root + href[1:].encode('utf-8'),
+ self.root + href.encode('utf-8'),
headers,
StringProducer(vcalendar.getTextWithTimezones(includeTimezones=True)),
method_label="PUT{organizer-%s}" % (label_suffix,) if invite else "PUT{event}",
@@ -1397,7 +1434,7 @@
# Do lookup and free busy of each attendee (not self)
attendees = list(vevent.mainComponent().properties('ATTENDEE'))
for attendee in attendees:
- if attendee.value() == self.uuid:
+ if attendee.value() in (self.uuid, self.email):
continue
yield self._attendeeAutoComplete(vevent, attendee)
@@ -1424,7 +1461,7 @@
response = yield self._request(
OK,
'GET',
- self.root + href[1:].encode('utf-8'),
+ self.root + href.encode('utf-8'),
method_label="GET{event}",
)
headers = response.headers
@@ -1455,7 +1492,7 @@
@return: A C{Deferred} which fires with a C{dict}. Keys in the dict
are user UUIDs (those requested) and values are something else.
"""
- outbox = self.root + self.outbox[1:]
+ outbox = self.root + self.outbox
if mask:
maskStr = u'\r\n'.join(['X-CALENDARSERVER-MASK-UID:' + uid
@@ -1578,30 +1615,7 @@
self.principalURL = hrefs[davxml.principal_URL].toString()
# Using the actual principal URL, retrieve principal information
- principal = yield self._principalPropfind()
-
- hrefs = principal.getHrefProperties()
-
- # Remember our outbox and notifications
- self.outbox = hrefs[caldavxml.schedule_outbox_URL].toString()
- try:
- self.notificationURL = hrefs[csxml.notification_URL].toString()
- except KeyError:
- self.notificationURL = None
-
- # Remember our own email-like principal address
- for principalURL in hrefs[caldavxml.calendar_user_address_set]:
- if principalURL.toString().startswith(u"mailto:"):
- self.email = principalURL.toString()
- elif principalURL.toString().startswith(u"urn:"):
- self.uuid = principalURL.toString()
- if self.email is None:
- raise ValueError("Cannot operate without a mail-style principal URL")
-
- # Do another kind of thing I guess
- principalCollection = hrefs[davxml.principal_collection_set].toString()
- (yield self._principalSearchPropertySetReport(principalCollection))
-
+ principal = (yield self._extractPrincipalDetails())
returnValue(principal)
@@ -1691,30 +1705,7 @@
self.principalURL = hrefs[davxml.principal_URL].toString()
# Using the actual principal URL, retrieve principal information
- principal = yield self._principalPropfind()
-
- hrefs = principal.getHrefProperties()
-
- # Remember our outbox and notifications
- self.outbox = hrefs[caldavxml.schedule_outbox_URL].toString()
- try:
- self.notificationURL = hrefs[csxml.notification_URL].toString()
- except KeyError:
- self.notificationURL = None
-
- # Remember our own email-like principal address
- for principalURL in hrefs[caldavxml.calendar_user_address_set]:
- if principalURL.toString().startswith(u"mailto:"):
- self.email = principalURL.toString()
- elif principalURL.toString().startswith(u"urn:"):
- self.uuid = principalURL.toString()
- if self.email is None:
- raise ValueError("Cannot operate without a mail-style principal URL")
-
- # Do another kind of thing I guess
- principalCollection = hrefs[davxml.principal_collection_set].toString()
- yield self._principalSearchPropertySetReport(principalCollection)
-
+ principal = yield self._extractPrincipalDetails()
returnValue(principal)
@@ -1779,20 +1770,6 @@
@inlineCallbacks
- def _principalPropfindInitial(self):
- """
- Issue a PROPFIND on the /principals/ URL to retrieve
- the /principals/__uids__/<guid> principal URL
- """
- _ignore_response, result = yield self._propfind(
- '/principals/',
- self._STARTUP_PRINCIPAL_PROPFIND_INITIAL,
- method_label="PROPFIND{find-principal}",
- )
- returnValue(result['/principals/'])
-
-
- @inlineCallbacks
def _pollFirstTime1(self, homeNode, calendars):
# Patch calendar properties
for cal in calendars:
@@ -1899,27 +1876,7 @@
self.principalURL = hrefs[davxml.principal_URL].toString()
# Using the actual principal URL, retrieve principal information
- principal = yield self._principalPropfind()
-
- hrefs = principal.getHrefProperties()
-
- # Remember our outbox and ignore notifications
- self.outbox = hrefs[caldavxml.schedule_outbox_URL].toString()
- self.notificationURL = None
-
- # Remember our own email-like principal address
- for principalURL in hrefs[caldavxml.calendar_user_address_set]:
- if principalURL.toString().startswith(u"mailto:"):
- self.email = principalURL.toString()
- elif principalURL.toString().startswith(u"urn:"):
- self.uuid = principalURL.toString()
- if self.email is None:
- raise ValueError("Cannot operate without a mail-style principal URL")
-
- # Do another kind of thing I guess
- principalCollection = hrefs[davxml.principal_collection_set].toString()
- yield self._principalSearchPropertySetReport(principalCollection)
-
+ principal = yield self._extractPrincipalDetails()
returnValue(principal)
Modified: CalendarServer/trunk/contrib/performance/loadtest/profiles.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/profiles.py 2012-06-18 18:11:20 UTC (rev 9368)
+++ CalendarServer/trunk/contrib/performance/loadtest/profiles.py 2012-06-18 18:16:57 UTC (rev 9369)
@@ -174,7 +174,7 @@
given event.
"""
selfRecord = self._sim.getUserRecord(self._number)
- invitees = set([u'urn:uuid:%s' % (selfRecord.uid,)])
+ invitees = set([u'mailto:%s' % (selfRecord.email,)])
for att in attendees:
invitees.add(att.value())
@@ -185,23 +185,22 @@
record = self._sim.getUserRecord(invitee)
except IndexError:
continue
+ cuaddr = u'mailto:%s' % (record.email,)
uuid = u'urn:uuid:%s' % (record.uid,)
- if uuid not in invitees:
+ if cuaddr not in invitees and uuid not in invitees:
break
else:
return fail(CannotAddAttendee("Can't find uninvited user to invite."))
attendee = Property(
name=u'ATTENDEE',
- value=uuid.encode("utf-8"),
+ value=cuaddr.encode("utf-8"),
params={
'CN': record.commonName,
'CUTYPE': 'INDIVIDUAL',
- 'EMAIL': record.email,
'PARTSTAT': 'NEEDS-ACTION',
'ROLE': 'REQ-PARTICIPANT',
'RSVP': 'TRUE',
- #'SCHEDULE-STATUS': '1.2',
},
)
@@ -320,7 +319,7 @@
given event.
"""
selfRecord = self._sim.getUserRecord(self._number)
- invitees = set([u'urn:uuid:%s' % (selfRecord.uid,)])
+ invitees = set([u'mailto:%s' % (selfRecord.email,)])
for att in attendees:
invitees.add(att.value())
@@ -331,23 +330,21 @@
record = self._sim.getUserRecord(invitee)
except IndexError:
continue
- uuid = u'urn:uuid:%s' % (record.uid,)
- if uuid not in invitees:
+ cuaddr = u'mailto:%s' % (record.email,)
+ if cuaddr not in invitees:
break
else:
raise CannotAddAttendee("Can't find uninvited user to invite.")
attendee = Property(
name=u'ATTENDEE',
- value=uuid.encode("utf-8"),
+ value=cuaddr.encode("utf-8"),
params={
'CN': record.commonName,
'CUTYPE': 'INDIVIDUAL',
- 'EMAIL': record.email,
'PARTSTAT': 'NEEDS-ACTION',
'ROLE': 'REQ-PARTICIPANT',
'RSVP': 'TRUE',
- #'SCHEDULE-STATUS': '1.2',
},
)
Modified: CalendarServer/trunk/contrib/performance/loadtest/sim.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/sim.py 2012-06-18 18:11:20 UTC (rev 9368)
+++ CalendarServer/trunk/contrib/performance/loadtest/sim.py 2012-06-18 18:16:57 UTC (rev 9369)
@@ -242,7 +242,7 @@
workerID = config.get("workerID", 0)
workerCount = config.get("workerCount", 1)
configTemplate = None
- server = 'http://127.0.0.1:8008/'
+ server = 'http://127.0.0.1:8008'
principalPathTemplate = "/principals/users/%s/"
webadminPort = None
serializationPath = None
Modified: CalendarServer/trunk/contrib/performance/loadtest/test_ical.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/test_ical.py 2012-06-18 18:11:20 UTC (rev 9368)
+++ CalendarServer/trunk/contrib/performance/loadtest/test_ical.py 2012-06-18 18:16:57 UTC (rev 9369)
@@ -1160,7 +1160,7 @@
u"user91", u"user91", u"User 91", u"user91 at example.org")
self.client = OS_X_10_6(
None,
- "http://127.0.0.1/",
+ "http://127.0.0.1",
"/principals/users/%s/",
None,
self.record,
@@ -1361,12 +1361,13 @@
self.client.uuid = u'urn:uuid:user01'
self.client.email = u'mailto:user01 at example.com'
+ self.client.principalCollection = "/principals/"
self.client.outbox = "/calendars/__uids__/user01/outbox/"
@inlineCallbacks
def _testReport(*args, **kwargs):
expectedResponseCode, method, url, headers, body = args
- self.assertEqual(expectedResponseCode, MULTI_STATUS)
+ self.assertEqual(expectedResponseCode, (MULTI_STATUS,))
self.assertEqual(method, 'REPORT')
self.assertEqual(url, 'http://127.0.0.1/principals/')
self.assertIsInstance(url, str)
@@ -1377,7 +1378,7 @@
response = MemoryResponse(
('HTTP', '1', '1'), MULTI_STATUS, "MultiStatus", Headers({}),
- StringProducer(""))
+ StringProducer("<?xml version='1.0' encoding='UTF-8'?><multistatus xmlns='DAV:' />"))
returnValue(response)
Modified: CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py 2012-06-18 18:11:20 UTC (rev 9368)
+++ CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py 2012-06-18 18:16:57 UTC (rev 9369)
@@ -278,7 +278,7 @@
def _makeSelfAttendee(self):
attendee = Property(
name=u'ATTENDEE',
- value=self.uuid,
+ value=self.email,
params={
'CN': self.record.commonName,
'CUTYPE': 'INDIVIDUAL',
@@ -291,7 +291,7 @@
def _makeSelfOrganizer(self):
organizer = Property(
name=u'ORGANIZER',
- value=self.uuid,
+ value=self.email,
params={
'CN': self.record.commonName,
},
@@ -401,7 +401,6 @@
for paramname, paramvalue in {
'CN': 'User %d' % (userNumber + 1,),
'CUTYPE': 'INDIVIDUAL',
- 'EMAIL': 'user%d at example.com' % (userNumber + 1,),
'PARTSTAT': 'NEEDS-ACTION',
'ROLE': 'REQ-PARTICIPANT',
'RSVP': 'TRUE'
@@ -431,7 +430,6 @@
for paramname, paramvalue in {
'CN': 'User %d' % (otherNumber,),
'CUTYPE': 'INDIVIDUAL',
- 'EMAIL': 'user%d at example.com' % (otherNumber,),
'PARTSTAT': 'NEEDS-ACTION',
'ROLE': 'REQ-PARTICIPANT',
'RSVP': 'TRUE'
@@ -463,7 +461,6 @@
for paramname, paramvalue in {
'CN': 'User %02d' % (anotherNumber,),
'CUTYPE': 'INDIVIDUAL',
- 'EMAIL': 'user%02d at example.com' % (anotherNumber,),
'PARTSTAT': 'NEEDS-ACTION',
'ROLE': 'REQ-PARTICIPANT',
'RSVP': 'TRUE'
@@ -589,7 +586,7 @@
inviter._invite()
self.assertEquals(len(client._events), 1)
attendees = tuple(client._events.values()[0].vevent.mainComponent().properties('ATTENDEE'))
- expected = set(("urn:uuid:user%02d" % (userNumber,), "urn:uuid:user%02d" % (userNumber + 1,),))
+ expected = set(("mailto:user%02d at example.com" % (userNumber,), "mailto:user%02d at example.com" % (userNumber + 1,),))
for attendee in attendees:
expected.remove(attendee.value())
self.assertEqual(len(expected), 0)
@@ -618,7 +615,7 @@
inviter._invite()
self.assertEquals(len(client._events), 1)
attendees = tuple(client._events.values()[0].vevent.mainComponent().properties('ATTENDEE'))
- expected = set(("urn:uuid:user%02d" % (selfNumber,), "urn:uuid:user%02d" % (otherNumber,),))
+ expected = set(("mailto:user%02d at example.com" % (selfNumber,), "mailto:user%02d at example.com" % (otherNumber,),))
for attendee in attendees:
expected.remove(attendee.value())
self.assertEqual(len(expected), 0)
@@ -649,9 +646,9 @@
self.assertEquals(len(client._events), 1)
attendees = tuple(client._events.values()[0].vevent.mainComponent().properties('ATTENDEE'))
expected = set((
- "urn:uuid:user%02d" % (selfNumber,),
- "urn:uuid:user%02d" % (inviteeNumber,),
- "urn:uuid:user%02d" % (anotherNumber,),
+ "mailto:user%02d at example.com" % (selfNumber,),
+ "mailto:user%02d at example.com" % (inviteeNumber,),
+ "mailto:user%02d at example.com" % (anotherNumber,),
))
for attendee in attendees:
expected.remove(attendee.value())
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120618/13831518/attachment-0001.html>
More information about the calendarserver-changes
mailing list