[CalendarServer-changes] [6699] CalendarServer/trunk/contrib/performance/loadtest
source_changes at macosforge.org
source_changes at macosforge.org
Fri Dec 17 10:03:03 PST 2010
Revision: 6699
http://trac.macosforge.org/projects/calendarserver/changeset/6699
Author: exarkun at twistedmatrix.com
Date: 2010-12-17 10:02:58 -0800 (Fri, 17 Dec 2010)
Log Message:
-----------
Notice ctag changes and download new/changed events
Modified Paths:
--------------
CalendarServer/trunk/contrib/performance/loadtest/ical.py
CalendarServer/trunk/contrib/performance/loadtest/population.py
Added Paths:
-----------
CalendarServer/trunk/contrib/performance/loadtest/request-data/sl_calendar_propfind.request
CalendarServer/trunk/contrib/performance/loadtest/request-data/sl_calendar_report.request
Modified: CalendarServer/trunk/contrib/performance/loadtest/ical.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/ical.py 2010-12-17 17:23:04 UTC (rev 6698)
+++ CalendarServer/trunk/contrib/performance/loadtest/ical.py 2010-12-17 18:02:58 UTC (rev 6699)
@@ -43,6 +43,12 @@
SUPPORTED_REPORT_SET = '{DAV:}supported-report-set'
+class Event(object):
+ def __init__(self, url, etag):
+ self.url = url
+ self.etag = etag
+
+
class Calendar(object):
def __init__(self, resourceType, name, url, ctag):
self.resourceType = resourceType
@@ -67,13 +73,27 @@
_STARTUP_NOTIFICATION_PROPFIND = loadRequestBody('sl_startup_notification_propfind')
_STARTUP_PRINCIPAL_REPORT = loadRequestBody('sl_startup_principal_report')
+ _CALENDAR_PROPFIND = loadRequestBody('sl_calendar_propfind')
+ _CALENDAR_REPORT = loadRequestBody('sl_calendar_report')
+
+
def __init__(self, reactor, host, port, user, auth):
self.reactor = reactor
self.agent = AuthHandlerAgent(Agent(self.reactor), auth)
self.root = 'http://%s:%d/' % (host, port)
self.user = user
+ # Keep track of the calendars on this account, keys are
+ # Calendar URIs, values are Calendar instances.
+ self._calendars = {}
+ # 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
+ # part of), values are Event instances.
+ self._events = {}
+
+
def _request(self, method, url, headers, body):
# XXX Do return code checking here.
headers.setRawHeaders('User-Agent', [self.USER_AGENT])
@@ -90,9 +110,9 @@
return d
- def _parsePROPFINDResponse(self, response):
+ def _parseMultiStatus(self, response):
"""
- Construct a principal from the body a response to a
+ Parse a <multistatus>
I{PROPFIND} request for the principal URL.
@type response: C{str}
@@ -115,7 +135,7 @@
Parse
"""
calendars = []
- principals = self._parsePROPFINDResponse(response)
+ principals = self._parseMultiStatus(response)
# XXX Here, it would be really great to somehow use
# CalDAVClientLibrary.client.principal.CalDAVPrincipal.listCalendars
@@ -149,7 +169,7 @@
'depth': ['0']}),
StringProducer(self._STARTUP_PRINCIPAL_PROPFIND))
d.addCallback(readBody)
- d.addCallback(self._parsePROPFINDResponse)
+ d.addCallback(self._parseMultiStatus)
d.addCallback(getitem, principalURL)
return d
@@ -182,13 +202,65 @@
StringProducer(self._STARTUP_CALENDARHOME_PROPFIND))
d.addCallback(readBody)
d.addCallback(self._extractCalendars)
- def report(result):
- # pprint(result)
- pass
- d.addCallback(report)
return d
+ @inlineCallbacks
+ def _updateCalendar(self, calendar):
+ url = calendar.url
+ if url.startswith('/'):
+ url = url[1:]
+
+ # First do a PROPFIND on the calendar to learn about events it
+ # might have.
+ response = yield self._request(
+ 'PROPFIND',
+ self.root + url,
+ Headers({'content-type': ['text/xml'], 'depth': ['1']}),
+ StringProducer(self._CALENDAR_PROPFIND))
+
+ # XXX Check the response status code
+
+ body = yield readBody(response)
+
+ result = self._parseMultiStatus(body)
+ for responseHref in result:
+ if responseHref == calendar.url:
+ continue
+
+ etag = result[responseHref].getTextProperties()[davxml.getetag]
+ if responseHref not in self._events:
+ self._events[responseHref] = Event(responseHref, None)
+
+ if self._events[responseHref].etag != etag:
+ response = yield self._updateEvent(url, responseHref)
+ body = yield readBody(response)
+ result = self._parseMultiStatus(body)[responseHref]
+ etag = result.getTextProperties()[davxml.getetag]
+ self._events[responseHref].etag = etag
+
+
+ def _updateEvent(self, calendar, event):
+ # Next do a REPORT on each event that might have information
+ # we don't know about.
+ return self._request(
+ 'REPORT',
+ self.root + calendar,
+ Headers({'content-type': ['text/xml']}),
+ StringProducer(self._CALENDAR_REPORT % {'href': event}))
+
+
+ def _checkCalendarsForEvents(self, calendarHomeSet):
+ d = self._calendarHomePropfind(calendarHomeSet)
+ def cbCalendars(calendars):
+ for cal in calendars:
+ if self._calendars.setdefault(cal.url, cal).ctag != cal.ctag or True:
+ self._updateCalendar(cal)
+ break
+ d.addCallback(cbCalendars)
+ return d
+
+
def _notificationPropfind(self, notificationURL):
if notificationURL.startswith('/'):
notificationURL = notificationURL[1:]
@@ -229,16 +301,14 @@
(yield self._principalsReport(principalCollection))
# Whatever
- calendarHome = hrefs[caldavxml.calendar_home_set].toString()
- (yield self._calendarHomePropfind(calendarHome))
# Learn stuff I guess
- notificationURL = hrefs[csxml.notification_URL].toString()
- (yield self._notificationPropfind(notificationURL))
+ # notificationURL = hrefs[csxml.notification_URL].toString()
+ # (yield self._notificationPropfind(notificationURL))
# More too
- principalURL = hrefs[davxml.principal_URL].toString()
- (yield self._principalReport(principalURL))
+ # principalURL = hrefs[davxml.principal_URL].toString()
+ # (yield self._principalReport(principalURL))
returnValue(principal)
@@ -254,7 +324,7 @@
# Poll Calendar Home (and notifications?) every 15 (or
# whatever) minutes
pollCalendarHome = LoopingCall(
- self._calendarHomePropfind,
+ self._checkCalendarsForEvents,
hrefs[caldavxml.calendar_home_set].toString())
pollCalendarHome.start(self.CALENDAR_HOME_POLL_INTERVAL)
Modified: CalendarServer/trunk/contrib/performance/loadtest/population.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/population.py 2010-12-17 17:23:04 UTC (rev 6698)
+++ CalendarServer/trunk/contrib/performance/loadtest/population.py 2010-12-17 18:02:58 UTC (rev 6699)
@@ -136,12 +136,11 @@
simulator = CalendarClientSimulator(
populator, parameters, reactor, '127.0.0.1', 8008)
- # Uh yea let's see
+ # Add some clients.
call = LoopingCall(simulator.add, 1)
- call.start(1)
- reactor.callLater(60, call.stop)
+ call.start(3)
+ reactor.callLater(3 * 90, call.stop)
-
reactor.run()
if __name__ == '__main__':
Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/sl_calendar_propfind.request
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/request-data/sl_calendar_propfind.request (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/sl_calendar_propfind.request 2010-12-17 18:02:58 UTC (rev 6699)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<x0:propfind xmlns:x0="DAV:" xmlns:x1="http://calendarserver.org/ns/">
+ <x0:prop>
+ <x0:getetag/>
+ <x0:resourcetype/>
+ <x1:notificationtype/>
+ </x0:prop>
+</x0:propfind>
Added: CalendarServer/trunk/contrib/performance/loadtest/request-data/sl_calendar_report.request
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/request-data/sl_calendar_report.request (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/request-data/sl_calendar_report.request 2010-12-17 18:02:58 UTC (rev 6699)
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<x0:calendar-multiget xmlns:x0="urn:ietf:params:xml:ns:caldav" xmlns:x1="DAV:"><x1:prop><x1:getetag/><x0:calendar-data/><x0:schedule-tag/></x1:prop><x1:href>%(href)s</x1:href></x0:calendar-multiget>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20101217/ff987134/attachment-0001.html>
More information about the calendarserver-changes
mailing list