[CalendarServer-changes] [6931] CalendarServer/trunk/contrib/performance
source_changes at macosforge.org
source_changes at macosforge.org
Tue Feb 15 12:54:05 PST 2011
Revision: 6931
http://trac.macosforge.org/projects/calendarserver/changeset/6931
Author: exarkun at twistedmatrix.com
Date: 2011-02-15 12:54:05 -0800 (Tue, 15 Feb 2011)
Log Message:
-----------
Put benchmark implementations all beneath a single package
Modified Paths:
--------------
CalendarServer/trunk/contrib/performance/benchmark.py
Added Paths:
-----------
CalendarServer/trunk/contrib/performance/benchmarks/
CalendarServer/trunk/contrib/performance/benchmarks/__init__.py
CalendarServer/trunk/contrib/performance/benchmarks/event.py
CalendarServer/trunk/contrib/performance/benchmarks/event_add_attendee.py
CalendarServer/trunk/contrib/performance/benchmarks/event_change_date.py
CalendarServer/trunk/contrib/performance/benchmarks/event_change_summary.py
CalendarServer/trunk/contrib/performance/benchmarks/event_delete.py
CalendarServer/trunk/contrib/performance/benchmarks/event_delete_attendee.py
CalendarServer/trunk/contrib/performance/benchmarks/event_move.py
CalendarServer/trunk/contrib/performance/benchmarks/find_calendars.py
CalendarServer/trunk/contrib/performance/benchmarks/find_events.py
CalendarServer/trunk/contrib/performance/benchmarks/vfreebusy.py
Removed Paths:
-------------
CalendarServer/trunk/contrib/performance/event.py
CalendarServer/trunk/contrib/performance/event_add_attendee.py
CalendarServer/trunk/contrib/performance/event_change_date.py
CalendarServer/trunk/contrib/performance/event_change_summary.py
CalendarServer/trunk/contrib/performance/event_delete.py
CalendarServer/trunk/contrib/performance/event_delete_attendee.py
CalendarServer/trunk/contrib/performance/event_move.py
CalendarServer/trunk/contrib/performance/find_calendars.py
CalendarServer/trunk/contrib/performance/find_events.py
CalendarServer/trunk/contrib/performance/vfreebusy.py
Modified: CalendarServer/trunk/contrib/performance/benchmark.py
===================================================================
--- CalendarServer/trunk/contrib/performance/benchmark.py 2011-02-15 19:50:17 UTC (rev 6930)
+++ CalendarServer/trunk/contrib/performance/benchmark.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -31,6 +31,7 @@
Deferred, inlineCallbacks, gatherResults)
from twisted.internet import reactor
from twisted.python.log import msg
+from twisted.python.modules import getModule
from stats import SQLDuration, Bytes
@@ -431,6 +432,14 @@
pid.getContent() for pid in run.globChildren('*instance*')]
+_benchmarks = getModule("benchmarks")
+def resolveBenchmark(name):
+ for module in _benchmarks.iterModules():
+ if module.name == ".".join((_benchmarks.name, name)):
+ return module.load()
+ raise ValueError("Unknown benchmark: %r" % (name,))
+
+
def main():
from twisted.python.log import startLogging, err
@@ -458,7 +467,7 @@
d = benchmark(
options['host'], options['port'], pids, options['label'],
options['parameters'],
- [(arg, namedAny(arg).measure) for arg in options['benchmarks']])
+ [(arg, resolveBenchmark(arg).measure) for arg in options['benchmarks']])
d.addErrback(err, "Failure at benchmark runner top-level")
reactor.callWhenRunning(d.addCallback, lambda ign: reactor.stop())
reactor.run()
Added: CalendarServer/trunk/contrib/performance/benchmarks/__init__.py
===================================================================
--- CalendarServer/trunk/contrib/performance/benchmarks/__init__.py (rev 0)
+++ CalendarServer/trunk/contrib/performance/benchmarks/__init__.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -0,0 +1,3 @@
+"""
+Package containing implementations of all of the microbenchmarks.
+"""
Copied: CalendarServer/trunk/contrib/performance/benchmarks/event.py (from rev 6927, CalendarServer/trunk/contrib/performance/event.py)
===================================================================
--- CalendarServer/trunk/contrib/performance/benchmarks/event.py (rev 0)
+++ CalendarServer/trunk/contrib/performance/benchmarks/event.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -0,0 +1,153 @@
+##
+# Copyright (c) 2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+Benchmark a server's handling of event creation.
+"""
+
+from itertools import count
+from urllib2 import HTTPDigestAuthHandler
+from uuid import uuid4
+from datetime import datetime, timedelta
+
+from twisted.internet.defer import inlineCallbacks, returnValue
+from twisted.internet import reactor
+from twisted.web.client import Agent
+from twisted.web.http_headers import Headers
+from twisted.web.http import CREATED
+
+from httpauth import AuthHandlerAgent
+from httpclient import StringProducer
+from benchlib import initialize, sample
+
+# XXX Represent these as vobjects? Would make it easier to add more vevents.
+event = """\
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Apple Inc.//iCal 4.0.3//EN
+BEGIN:VTIMEZONE
+TZID:America/Los_Angeles
+BEGIN:STANDARD
+DTSTART:20071104T020000
+RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
+TZNAME:PST
+TZOFFSETFROM:-0700
+TZOFFSETTO:-0800
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:20070311T020000
+RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
+TZNAME:PDT
+TZOFFSETFROM:-0800
+TZOFFSETTO:-0700
+END:DAYLIGHT
+END:VTIMEZONE
+%(VEVENTS)s\
+END:VCALENDAR
+"""
+
+attendee = """\
+ATTENDEE;CN=User %(SEQUENCE)02d;CUTYPE=INDIVIDUAL;EMAIL=user%(SEQUENCE)02d at example.com;PARTSTAT=NE
+ EDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:urn:uuid:user%(SEQUENCE)02d
+"""
+
+organizer = """\
+ORGANIZER;CN=User %(SEQUENCE)02d;EMAIL=user%(SEQUENCE)02d at example.com:urn:uuid:user%(SEQUENCE)02d
+ATTENDEE;CN=User %(SEQUENCE)02d;EMAIL=user%(SEQUENCE)02d at example.com;PARTSTAT=ACCEPTE
+ D:urn:uuid:user%(SEQUENCE)02d
+"""
+
+def makeOrganizer(sequence):
+ return organizer % {'SEQUENCE': sequence}
+
+def makeAttendees(count):
+ return ''.join([
+ attendee % {'SEQUENCE': n} for n in range(2, count + 2)])
+
+
+def formatDate(d):
+ return ''.join(filter(str.isalnum, d.isoformat()))
+
+
+SUMMARY = "STUFF IS THINGS"
+
+def makeEvent(i, organizerSequence, attendeeCount):
+ s = """\
+BEGIN:VEVENT
+UID:%(UID)s
+DTSTART;TZID=America/Los_Angeles:%(START)s
+DTEND;TZID=America/Los_Angeles:%(END)s
+CREATED:20100729T193912Z
+DTSTAMP:20100729T195557Z
+%(ORGANIZER)s\
+%(ATTENDEES)s\
+SEQUENCE:0
+SUMMARY:%(summary)s
+TRANSP:OPAQUE
+END:VEVENT
+"""
+ base = datetime(2010, 7, 30, 11, 15, 00)
+ interval = timedelta(0, 5)
+ duration = timedelta(0, 3)
+ return event % {
+ 'VEVENTS': s % {
+ 'UID': uuid4(),
+ 'START': formatDate(base + i * interval),
+ 'END': formatDate(base + i * interval + duration),
+ 'ORGANIZER': makeOrganizer(organizerSequence),
+ 'ATTENDEES': makeAttendees(attendeeCount),
+ 'summary': SUMMARY,
+ },
+ }
+
+
+ at inlineCallbacks
+def measure(host, port, dtrace, attendeeCount, samples):
+ organizerSequence = 1
+ user = password = "user%02d" % (organizerSequence,)
+ root = "/"
+ principal = "/"
+ calendar = "event-creation-benchmark"
+
+ authinfo = HTTPDigestAuthHandler()
+ authinfo.add_password(
+ realm="Test Realm",
+ uri="http://%s:%d/" % (host, port),
+ user=user,
+ passwd=password)
+ agent = AuthHandlerAgent(Agent(reactor), authinfo)
+
+ # First set things up
+ yield initialize(agent, host, port, user, password, root, principal, calendar)
+
+ method = 'PUT'
+ uri = 'http://%s:%d/calendars/__uids__/%s/%s/foo-%%d.ics' % (
+ host, port, user, calendar)
+ headers = Headers({"content-type": ["text/calendar"]})
+
+ # An infinite stream of VEVENTs to PUT to the server.
+ events = ((i, makeEvent(i, organizerSequence, attendeeCount)) for i in count(2))
+
+ # Sample it a bunch of times
+ samples = yield sample(
+ dtrace, samples,
+ agent, ((method, uri % (i,), headers, StringProducer(body))
+ for (i, body)
+ in events).next,
+ CREATED)
+ returnValue(samples)
+
Copied: CalendarServer/trunk/contrib/performance/benchmarks/event_add_attendee.py (from rev 6927, CalendarServer/trunk/contrib/performance/event_add_attendee.py)
===================================================================
--- CalendarServer/trunk/contrib/performance/benchmarks/event_add_attendee.py (rev 0)
+++ CalendarServer/trunk/contrib/performance/benchmarks/event_add_attendee.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -0,0 +1,36 @@
+##
+# Copyright (c) 2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+import _event_change
+
+from event import makeAttendees
+
+
+def measure(host, port, dtrace, attendeeCount, samples):
+ attendees = makeAttendees(attendeeCount)
+
+ def addAttendees(event, i):
+ """
+ Add C{i} new attendees to the given event.
+ """
+ # Find the last CREATED line
+ created = event.rfind('CREATED')
+ # Insert the attendees before it.
+ return event[:created] + attendees + event[created:]
+
+ return _event_change.measure(
+ host, port, dtrace, 0, samples, "add-attendee",
+ addAttendees, eventPerSample=True)
Copied: CalendarServer/trunk/contrib/performance/benchmarks/event_change_date.py (from rev 6927, CalendarServer/trunk/contrib/performance/event_change_date.py)
===================================================================
--- CalendarServer/trunk/contrib/performance/benchmarks/event_change_date.py (rev 0)
+++ CalendarServer/trunk/contrib/performance/benchmarks/event_change_date.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -0,0 +1,51 @@
+##
+# Copyright (c) 2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+Benchmark a change in the date boundaries of an event.
+"""
+
+
+import datetime
+
+import _event_change
+
+TIME_FORMAT = '%Y%m%dT%H%M%S'
+
+def _increment(event, marker, amount):
+ # Find the last occurrence of the marker
+ dtstart = event.rfind(marker)
+ # Find the end of that line
+ eol = event.find('\n', dtstart)
+ # Find the : preceding the date on that line
+ colon = event.find(':', dtstart)
+ # Replace the text between the colon and the eol with the new timestamp
+ old = datetime.datetime.strptime(event[colon + 1:eol], TIME_FORMAT)
+ new = old + amount
+ return event[:colon + 1] + new.strftime(TIME_FORMAT) + event[eol:]
+
+
+def replaceTimestamp(event, i):
+ offset = datetime.timedelta(hours=i)
+ return _increment(
+ _increment(event, 'DTSTART', offset),
+ 'DTEND', offset)
+
+
+def measure(host, port, dtrace, attendeeCount, samples):
+ return _event_change.measure(
+ host, port, dtrace, attendeeCount, samples, "change-date",
+ replaceTimestamp)
Copied: CalendarServer/trunk/contrib/performance/benchmarks/event_change_summary.py (from rev 6927, CalendarServer/trunk/contrib/performance/event_change_summary.py)
===================================================================
--- CalendarServer/trunk/contrib/performance/benchmarks/event_change_summary.py (rev 0)
+++ CalendarServer/trunk/contrib/performance/benchmarks/event_change_summary.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -0,0 +1,28 @@
+##
+# Copyright (c) 2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+from event import SUMMARY
+
+import _event_change
+
+def replaceSummary(event, i):
+ return event.replace(SUMMARY, 'Replacement summary %d' % (i,))
+
+
+def measure(host, port, dtrace, attendeeCount, samples):
+ return _event_change.measure(
+ host, port, dtrace, attendeeCount, samples, "change-summary",
+ replaceSummary)
Copied: CalendarServer/trunk/contrib/performance/benchmarks/event_delete.py (from rev 6927, CalendarServer/trunk/contrib/performance/event_delete.py)
===================================================================
--- CalendarServer/trunk/contrib/performance/benchmarks/event_delete.py (rev 0)
+++ CalendarServer/trunk/contrib/performance/benchmarks/event_delete.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -0,0 +1,77 @@
+##
+# Copyright (c) 2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+Benchmark a server's handling of event deletion.
+"""
+
+from itertools import count
+from urllib2 import HTTPDigestAuthHandler
+
+from twisted.internet import reactor
+from twisted.internet.defer import inlineCallbacks, returnValue
+from twisted.web.client import Agent
+from twisted.web.http_headers import Headers
+from twisted.web.http import NO_CONTENT
+
+from httpauth import AuthHandlerAgent
+from httpclient import StringProducer
+
+from benchlib import initialize, sample
+from event import makeEvent
+
+ at inlineCallbacks
+def measure(host, port, dtrace, attendeeCount, samples):
+ organizerSequence = 1
+ user = password = "user%02d" % (organizerSequence,)
+ root = "/"
+ principal = "/"
+ calendar = "event-deletion-benchmark"
+
+ authinfo = HTTPDigestAuthHandler()
+ authinfo.add_password(
+ realm="Test Realm",
+ uri="http://%s:%d/" % (host, port),
+ user=user,
+ passwd=password)
+ agent = AuthHandlerAgent(Agent(reactor), authinfo)
+
+ # Set up the calendar first
+ yield initialize(agent, host, port, user, password, root, principal, calendar)
+
+ # An infinite stream of VEVENTs to PUT to the server.
+ events = ((i, makeEvent(i, organizerSequence, attendeeCount))
+ for i in count(2))
+
+ # Create enough events to delete
+ uri = 'http://%s:%d/calendars/__uids__/%s/%s/foo-%%d.ics' % (
+ host, port, user, calendar)
+ headers = Headers({"content-type": ["text/calendar"]})
+ urls = []
+ for i, body in events:
+ urls.append(uri % (i,))
+ yield agent.request(
+ 'PUT', urls[-1], headers, StringProducer(body))
+ if len(urls) == samples:
+ break
+
+ # Now delete them all
+ samples = yield sample(
+ dtrace, samples,
+ agent, (('DELETE', url) for url in urls).next,
+ NO_CONTENT)
+ returnValue(samples)
+
Copied: CalendarServer/trunk/contrib/performance/benchmarks/event_delete_attendee.py (from rev 6927, CalendarServer/trunk/contrib/performance/event_delete_attendee.py)
===================================================================
--- CalendarServer/trunk/contrib/performance/benchmarks/event_delete_attendee.py (rev 0)
+++ CalendarServer/trunk/contrib/performance/benchmarks/event_delete_attendee.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -0,0 +1,35 @@
+##
+# Copyright (c) 2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+import _event_change
+
+def measure(host, port, dtrace, attendeeCount, samples):
+ def deleteAttendees(event, i):
+ """
+ Add C{i} new attendees to the given event.
+ """
+ for n in range(attendeeCount):
+ # Find the beginning of an ATTENDEE line
+ attendee = event.find('ATTENDEE')
+ # And the end of it
+ eol = event.find('\n', attendee)
+ # And remove it
+ event = event[:attendee] + event[eol:]
+ return event
+
+ return _event_change.measure(
+ host, port, dtrace, attendeeCount, samples, "delete-attendee",
+ deleteAttendees, eventPerSample=True)
Copied: CalendarServer/trunk/contrib/performance/benchmarks/event_move.py (from rev 6927, CalendarServer/trunk/contrib/performance/event_move.py)
===================================================================
--- CalendarServer/trunk/contrib/performance/benchmarks/event_move.py (rev 0)
+++ CalendarServer/trunk/contrib/performance/benchmarks/event_move.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -0,0 +1,77 @@
+##
+# Copyright (c) 2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+from itertools import count, cycle
+from urllib2 import HTTPDigestAuthHandler
+
+from twisted.internet import reactor
+from twisted.internet.defer import inlineCallbacks, returnValue
+from twisted.web.client import Agent
+from twisted.web.http_headers import Headers
+from twisted.web.http import CREATED
+
+from httpauth import AuthHandlerAgent
+from httpclient import StringProducer
+
+from benchlib import initialize, sample
+from event import makeEvent
+
+ at inlineCallbacks
+def measure(host, port, dtrace, attendeeCount, samples):
+ organizerSequence = 1
+ user = password = "user%02d" % (organizerSequence,)
+ root = "/"
+ principal = "/"
+
+ # Two calendars between which to move the event.
+ fooCalendar = "event-move-foo-benchmark"
+ barCalendar = "event-move-bar-benchmark"
+
+ authinfo = HTTPDigestAuthHandler()
+ authinfo.add_password(
+ realm="Test Realm",
+ uri="http://%s:%d/" % (host, port),
+ user=user,
+ passwd=password)
+ agent = AuthHandlerAgent(Agent(reactor), authinfo)
+
+ # Set up the calendars first
+ for calendar in [fooCalendar, barCalendar]:
+ yield initialize(
+ agent, host, port, user, password, root, principal, calendar)
+
+ fooURI = 'http://%s:%d/calendars/__uids__/%s/%s/some-event.ics' % (
+ host, port, user, fooCalendar)
+ barURI = 'http://%s:%d/calendars/__uids__/%s/%s/some-event.ics' % (
+ host, port, user, barCalendar)
+
+ # Create the event that will move around
+ headers = Headers({"content-type": ["text/calendar"]})
+ yield agent.request(
+ 'PUT', fooURI, headers,
+ StringProducer(makeEvent(1, organizerSequence, attendeeCount)))
+
+ # Move it around sooo much
+ source = cycle([fooURI, barURI])
+ dest = cycle([barURI, fooURI])
+
+ params = (
+ ('MOVE', source.next(),
+ Headers({"destination": [dest.next()], "overwrite": ["F"]}))
+ for i in count(1))
+
+ samples = yield sample(dtrace, samples, agent, params.next, CREATED)
+ returnValue(samples)
Copied: CalendarServer/trunk/contrib/performance/benchmarks/find_calendars.py (from rev 6927, CalendarServer/trunk/contrib/performance/find_calendars.py)
===================================================================
--- CalendarServer/trunk/contrib/performance/benchmarks/find_calendars.py (rev 0)
+++ CalendarServer/trunk/contrib/performance/benchmarks/find_calendars.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -0,0 +1,104 @@
+##
+# Copyright (c) 2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+from itertools import count
+from urllib2 import HTTPDigestAuthHandler
+
+from twisted.internet import reactor
+from twisted.internet.defer import inlineCallbacks, returnValue
+from twisted.web.client import Agent
+from twisted.web.http_headers import Headers
+from twisted.web.http import MULTI_STATUS
+
+from httpauth import AuthHandlerAgent
+from httpclient import StringProducer
+
+from benchlib import CalDAVAccount, sample
+
+PROPFIND = """\
+<?xml version="1.0" encoding="utf-8"?>
+<x0:propfind xmlns:x0="DAV:" xmlns:x3="http://apple.com/ns/ical/" xmlns:x1="http://calendarserver.org/ns/" xmlns:x2="urn:ietf:params:xml:ns:caldav">
+ <x0:prop>
+ <x1:xmpp-server/>
+ <x1:xmpp-uri/>
+ <x1:getctag/>
+ <x0:displayname/>
+ <x2:calendar-description/>
+ <x3:calendar-color/>
+ <x3:calendar-order/>
+ <x2:supported-calendar-component-set/>
+ <x0:resourcetype/>
+ <x0:owner/>
+ <x2:calendar-free-busy-set/>
+ <x2:schedule-calendar-transp/>
+ <x2:schedule-default-calendar-URL/>
+ <x0:quota-available-bytes/>
+ <x0:quota-used-bytes/>
+ <x2:calendar-timezone/>
+ <x0:current-user-privilege-set/>
+ <x1:source/>
+ <x1:subscribed-strip-alarms/>
+ <x1:subscribed-strip-attachments/>
+ <x1:subscribed-strip-todos/>
+ <x3:refreshrate/>
+ <x1:push-transports/>
+ <x1:pushkey/>
+ <x1:publish-url/>
+ </x0:prop>
+</x0:propfind>
+"""
+
+ at inlineCallbacks
+def measure(host, port, dtrace, numCalendars, samples):
+ # There's already the "calendar" calendar
+ numCalendars -= 1
+
+ user = password = "user10"
+ root = "/"
+ principal = "/"
+
+ authinfo = HTTPDigestAuthHandler()
+ authinfo.add_password(
+ realm="Test Realm",
+ uri="http://%s:%d/" % (host, port),
+ user=user,
+ passwd=password)
+ agent = AuthHandlerAgent(Agent(reactor), authinfo)
+
+ # Create the number of calendars necessary
+ account = CalDAVAccount(
+ agent,
+ "%s:%d" % (host, port),
+ user=user, password=password,
+ root=root, principal=principal)
+ cal = "/calendars/users/%s/propfind-%%d/" % (user,)
+ for i in range(numCalendars):
+ yield account.makeCalendar(cal % (i,))
+
+ body = StringProducer(PROPFIND)
+ params = (
+ ('PROPFIND', 'http://%s:%d/calendars/__uids__/%s/' % (host, port, user),
+ Headers({"depth": ["1"], "content-type": ["text/xml"]}), body)
+ for i in count(1))
+
+ samples = yield sample(dtrace, samples, agent, params.next, MULTI_STATUS)
+
+ # Delete the calendars we created to leave the server in roughly
+ # the same state as we found it.
+ for i in range(numCalendars):
+ yield account.deleteResource(cal % (i,))
+
+ returnValue(samples)
Copied: CalendarServer/trunk/contrib/performance/benchmarks/find_events.py (from rev 6927, CalendarServer/trunk/contrib/performance/find_events.py)
===================================================================
--- CalendarServer/trunk/contrib/performance/benchmarks/find_events.py (rev 0)
+++ CalendarServer/trunk/contrib/performance/benchmarks/find_events.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -0,0 +1,98 @@
+##
+# Copyright (c) 2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+from itertools import count
+from urllib2 import HTTPDigestAuthHandler
+
+from twisted.internet import reactor
+from twisted.internet.defer import inlineCallbacks, returnValue, gatherResults
+from twisted.internet.task import cooperate
+from twisted.web.client import Agent
+from twisted.web.http_headers import Headers
+from twisted.web.http import MULTI_STATUS
+
+from httpauth import AuthHandlerAgent
+from httpclient import StringProducer
+
+from benchlib import CalDAVAccount, sample
+from event import makeEvent
+
+PROPFIND = """\
+<?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>
+"""
+
+def uploadEvents(numEvents, agent, uri, cal):
+ def worker():
+ for i in range(numEvents):
+ event = makeEvent(i, 1, 0)
+ yield agent.request(
+ 'PUT',
+ '%s%s%d.ics' % (uri, cal, i),
+ Headers({"content-type": ["text/calendar"]}),
+ StringProducer(event))
+ worker = worker()
+ return gatherResults([
+ cooperate(worker).whenDone() for i in range(3)])
+
+
+ at inlineCallbacks
+def measure(host, port, dtrace, numEvents, samples):
+ user = password = "user11"
+ root = "/"
+ principal = "/"
+
+ uri = "http://%s:%d/" % (host, port)
+ authinfo = HTTPDigestAuthHandler()
+ authinfo.add_password(
+ realm="Test Realm",
+ uri=uri,
+ user=user,
+ passwd=password)
+ agent = AuthHandlerAgent(Agent(reactor), authinfo)
+
+ # Create the number of calendars necessary
+ account = CalDAVAccount(
+ agent,
+ "%s:%d" % (host, port),
+ user=user, password=password,
+ root=root, principal=principal)
+ cal = "calendars/users/%s/find-events/" % (user,)
+ yield account.makeCalendar("/" + cal)
+
+ # Create the indicated number of events on the calendar
+ yield uploadEvents(numEvents, agent, uri, cal)
+
+ body = StringProducer(PROPFIND)
+ params = (
+ ('PROPFIND',
+ '%scalendars/__uids__/%s/find-events/' % (uri, user),
+ Headers({"depth": ["1"], "content-type": ["text/xml"]}), body)
+ for i in count(1))
+
+ samples = yield sample(dtrace, samples, agent, params.next, MULTI_STATUS)
+
+ # Delete the calendar we created to leave the server in roughly
+ # the same state as we found it.
+ yield account.deleteResource("/" + cal)
+
+ returnValue(samples)
Copied: CalendarServer/trunk/contrib/performance/benchmarks/vfreebusy.py (from rev 6927, CalendarServer/trunk/contrib/performance/vfreebusy.py)
===================================================================
--- CalendarServer/trunk/contrib/performance/benchmarks/vfreebusy.py (rev 0)
+++ CalendarServer/trunk/contrib/performance/benchmarks/vfreebusy.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -0,0 +1,147 @@
+##
+# Copyright (c) 2010 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+"""
+Benchmark a server's handling of VFREEBUSY requests.
+"""
+
+from urllib2 import HTTPDigestAuthHandler
+from uuid import uuid4
+from datetime import datetime, timedelta
+
+from twisted.internet.defer import inlineCallbacks, returnValue
+from twisted.internet import reactor
+from twisted.web.client import Agent
+from twisted.web.http_headers import Headers
+from twisted.web.http import OK
+
+from httpauth import AuthHandlerAgent
+from httpclient import StringProducer
+from benchlib import initialize, sample
+
+# XXX Represent these as vobjects? Would make it easier to add more vevents.
+event = """\
+BEGIN:VCALENDAR
+VERSION:2.0
+CALSCALE:GREGORIAN
+PRODID:-//Apple Inc.//iCal 4.0.3//EN
+BEGIN:VTIMEZONE
+TZID:America/New_York
+BEGIN:STANDARD
+DTSTART:20071104T020000
+RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+BEGIN:DAYLIGHT
+DTSTART:20070311T020000
+RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+END:VTIMEZONE
+%(VEVENTS)s\
+END:VCALENDAR
+"""
+
+vfreebusy = """\
+BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+VERSION:2.0
+METHOD:REQUEST
+PRODID:-//Apple Inc.//iCal 4.0.3//EN
+BEGIN:VFREEBUSY
+UID:81F582C8-4E7F-491C-85F4-E541864BE0FA
+DTEND:20100730T150000Z
+ATTENDEE:urn:uuid:user02
+DTSTART:20100730T140000Z
+X-CALENDARSERVER-MASK-UID:EC75A61B-08A3-44FD-BFBB-2457BBD0D490
+DTSTAMP:20100729T174751Z
+ORGANIZER:mailto:user01 at example.com
+SUMMARY:Availability for urn:uuid:user02
+END:VFREEBUSY
+END:VCALENDAR
+"""
+
+def formatDate(d):
+ return ''.join(filter(str.isalnum, d.isoformat()))
+
+def makeEvent(i):
+ s = """\
+BEGIN:VEVENT
+UID:%(UID)s
+DTSTART;TZID=America/New_York:%(START)s
+DTEND;TZID=America/New_York:%(END)s
+CREATED:20100729T193912Z
+DTSTAMP:20100729T195557Z
+SEQUENCE:%(SEQUENCE)s
+SUMMARY:STUFF IS THINGS
+TRANSP:OPAQUE
+END:VEVENT
+"""
+ base = datetime(2010, 7, 30, 11, 15, 00)
+ interval = timedelta(hours=2)
+ duration = timedelta(hours=1)
+ return event % {
+ 'VEVENTS': s % {
+ 'UID': uuid4(),
+ 'START': formatDate(base + i * interval),
+ 'END': formatDate(base + i * interval + duration),
+ 'SEQUENCE': i,
+ },
+ }
+
+
+def makeEvents(n):
+ return [makeEvent(i) for i in range(n)]
+
+
+ at inlineCallbacks
+def measure(host, port, dtrace, events, samples):
+ user = password = "user01"
+ root = "/"
+ principal = "/"
+ calendar = "vfreebusy-benchmark"
+
+ authinfo = HTTPDigestAuthHandler()
+ authinfo.add_password(
+ realm="Test Realm",
+ uri="http://%s:%d/" % (host, port),
+ user=user,
+ passwd=password)
+ agent = AuthHandlerAgent(Agent(reactor), authinfo)
+
+ # First set things up
+ account = yield initialize(
+ agent, host, port, user, password, root, principal, calendar)
+
+ base = "/calendars/users/%s/%s/foo-%%d.ics" % (user, calendar)
+ for i, cal in enumerate(makeEvents(events)):
+ yield account.writeData(base % (i,), cal, "text/calendar")
+
+ method = 'POST'
+ uri = 'http://%s:%d/calendars/__uids__/%s/outbox/' % (host, port, user)
+ headers = Headers({"content-type": ["text/calendar"]})
+ body = StringProducer(vfreebusy)
+
+ samples = yield sample(
+ dtrace, samples,
+ agent, lambda: (method, uri, headers, body),
+ OK)
+ returnValue(samples)
+
Deleted: CalendarServer/trunk/contrib/performance/event.py
===================================================================
--- CalendarServer/trunk/contrib/performance/event.py 2011-02-15 19:50:17 UTC (rev 6930)
+++ CalendarServer/trunk/contrib/performance/event.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -1,153 +0,0 @@
-##
-# Copyright (c) 2010 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-"""
-Benchmark a server's handling of event creation.
-"""
-
-from itertools import count
-from urllib2 import HTTPDigestAuthHandler
-from uuid import uuid4
-from datetime import datetime, timedelta
-
-from twisted.internet.defer import inlineCallbacks, returnValue
-from twisted.internet import reactor
-from twisted.web.client import Agent
-from twisted.web.http_headers import Headers
-from twisted.web.http import CREATED
-
-from httpauth import AuthHandlerAgent
-from httpclient import StringProducer
-from benchlib import initialize, sample
-
-# XXX Represent these as vobjects? Would make it easier to add more vevents.
-event = """\
-BEGIN:VCALENDAR
-VERSION:2.0
-CALSCALE:GREGORIAN
-PRODID:-//Apple Inc.//iCal 4.0.3//EN
-BEGIN:VTIMEZONE
-TZID:America/Los_Angeles
-BEGIN:STANDARD
-DTSTART:20071104T020000
-RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
-TZNAME:PST
-TZOFFSETFROM:-0700
-TZOFFSETTO:-0800
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:20070311T020000
-RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
-TZNAME:PDT
-TZOFFSETFROM:-0800
-TZOFFSETTO:-0700
-END:DAYLIGHT
-END:VTIMEZONE
-%(VEVENTS)s\
-END:VCALENDAR
-"""
-
-attendee = """\
-ATTENDEE;CN=User %(SEQUENCE)02d;CUTYPE=INDIVIDUAL;EMAIL=user%(SEQUENCE)02d at example.com;PARTSTAT=NE
- EDS-ACTION;ROLE=REQ-PARTICIPANT;RSVP=TRUE:urn:uuid:user%(SEQUENCE)02d
-"""
-
-organizer = """\
-ORGANIZER;CN=User %(SEQUENCE)02d;EMAIL=user%(SEQUENCE)02d at example.com:urn:uuid:user%(SEQUENCE)02d
-ATTENDEE;CN=User %(SEQUENCE)02d;EMAIL=user%(SEQUENCE)02d at example.com;PARTSTAT=ACCEPTE
- D:urn:uuid:user%(SEQUENCE)02d
-"""
-
-def makeOrganizer(sequence):
- return organizer % {'SEQUENCE': sequence}
-
-def makeAttendees(count):
- return ''.join([
- attendee % {'SEQUENCE': n} for n in range(2, count + 2)])
-
-
-def formatDate(d):
- return ''.join(filter(str.isalnum, d.isoformat()))
-
-
-SUMMARY = "STUFF IS THINGS"
-
-def makeEvent(i, organizerSequence, attendeeCount):
- s = """\
-BEGIN:VEVENT
-UID:%(UID)s
-DTSTART;TZID=America/Los_Angeles:%(START)s
-DTEND;TZID=America/Los_Angeles:%(END)s
-CREATED:20100729T193912Z
-DTSTAMP:20100729T195557Z
-%(ORGANIZER)s\
-%(ATTENDEES)s\
-SEQUENCE:0
-SUMMARY:%(summary)s
-TRANSP:OPAQUE
-END:VEVENT
-"""
- base = datetime(2010, 7, 30, 11, 15, 00)
- interval = timedelta(0, 5)
- duration = timedelta(0, 3)
- return event % {
- 'VEVENTS': s % {
- 'UID': uuid4(),
- 'START': formatDate(base + i * interval),
- 'END': formatDate(base + i * interval + duration),
- 'ORGANIZER': makeOrganizer(organizerSequence),
- 'ATTENDEES': makeAttendees(attendeeCount),
- 'summary': SUMMARY,
- },
- }
-
-
- at inlineCallbacks
-def measure(host, port, dtrace, attendeeCount, samples):
- organizerSequence = 1
- user = password = "user%02d" % (organizerSequence,)
- root = "/"
- principal = "/"
- calendar = "event-creation-benchmark"
-
- authinfo = HTTPDigestAuthHandler()
- authinfo.add_password(
- realm="Test Realm",
- uri="http://%s:%d/" % (host, port),
- user=user,
- passwd=password)
- agent = AuthHandlerAgent(Agent(reactor), authinfo)
-
- # First set things up
- yield initialize(agent, host, port, user, password, root, principal, calendar)
-
- method = 'PUT'
- uri = 'http://%s:%d/calendars/__uids__/%s/%s/foo-%%d.ics' % (
- host, port, user, calendar)
- headers = Headers({"content-type": ["text/calendar"]})
-
- # An infinite stream of VEVENTs to PUT to the server.
- events = ((i, makeEvent(i, organizerSequence, attendeeCount)) for i in count(2))
-
- # Sample it a bunch of times
- samples = yield sample(
- dtrace, samples,
- agent, ((method, uri % (i,), headers, StringProducer(body))
- for (i, body)
- in events).next,
- CREATED)
- returnValue(samples)
-
Deleted: CalendarServer/trunk/contrib/performance/event_add_attendee.py
===================================================================
--- CalendarServer/trunk/contrib/performance/event_add_attendee.py 2011-02-15 19:50:17 UTC (rev 6930)
+++ CalendarServer/trunk/contrib/performance/event_add_attendee.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -1,36 +0,0 @@
-##
-# Copyright (c) 2010 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-import _event_change
-
-from event import makeAttendees
-
-
-def measure(host, port, dtrace, attendeeCount, samples):
- attendees = makeAttendees(attendeeCount)
-
- def addAttendees(event, i):
- """
- Add C{i} new attendees to the given event.
- """
- # Find the last CREATED line
- created = event.rfind('CREATED')
- # Insert the attendees before it.
- return event[:created] + attendees + event[created:]
-
- return _event_change.measure(
- host, port, dtrace, 0, samples, "add-attendee",
- addAttendees, eventPerSample=True)
Deleted: CalendarServer/trunk/contrib/performance/event_change_date.py
===================================================================
--- CalendarServer/trunk/contrib/performance/event_change_date.py 2011-02-15 19:50:17 UTC (rev 6930)
+++ CalendarServer/trunk/contrib/performance/event_change_date.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -1,51 +0,0 @@
-##
-# Copyright (c) 2010 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-"""
-Benchmark a change in the date boundaries of an event.
-"""
-
-
-import datetime
-
-import _event_change
-
-TIME_FORMAT = '%Y%m%dT%H%M%S'
-
-def _increment(event, marker, amount):
- # Find the last occurrence of the marker
- dtstart = event.rfind(marker)
- # Find the end of that line
- eol = event.find('\n', dtstart)
- # Find the : preceding the date on that line
- colon = event.find(':', dtstart)
- # Replace the text between the colon and the eol with the new timestamp
- old = datetime.datetime.strptime(event[colon + 1:eol], TIME_FORMAT)
- new = old + amount
- return event[:colon + 1] + new.strftime(TIME_FORMAT) + event[eol:]
-
-
-def replaceTimestamp(event, i):
- offset = datetime.timedelta(hours=i)
- return _increment(
- _increment(event, 'DTSTART', offset),
- 'DTEND', offset)
-
-
-def measure(host, port, dtrace, attendeeCount, samples):
- return _event_change.measure(
- host, port, dtrace, attendeeCount, samples, "change-date",
- replaceTimestamp)
Deleted: CalendarServer/trunk/contrib/performance/event_change_summary.py
===================================================================
--- CalendarServer/trunk/contrib/performance/event_change_summary.py 2011-02-15 19:50:17 UTC (rev 6930)
+++ CalendarServer/trunk/contrib/performance/event_change_summary.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -1,28 +0,0 @@
-##
-# Copyright (c) 2010 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-from event import SUMMARY
-
-import _event_change
-
-def replaceSummary(event, i):
- return event.replace(SUMMARY, 'Replacement summary %d' % (i,))
-
-
-def measure(host, port, dtrace, attendeeCount, samples):
- return _event_change.measure(
- host, port, dtrace, attendeeCount, samples, "change-summary",
- replaceSummary)
Deleted: CalendarServer/trunk/contrib/performance/event_delete.py
===================================================================
--- CalendarServer/trunk/contrib/performance/event_delete.py 2011-02-15 19:50:17 UTC (rev 6930)
+++ CalendarServer/trunk/contrib/performance/event_delete.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -1,77 +0,0 @@
-##
-# Copyright (c) 2010 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-"""
-Benchmark a server's handling of event deletion.
-"""
-
-from itertools import count
-from urllib2 import HTTPDigestAuthHandler
-
-from twisted.internet import reactor
-from twisted.internet.defer import inlineCallbacks, returnValue
-from twisted.web.client import Agent
-from twisted.web.http_headers import Headers
-from twisted.web.http import NO_CONTENT
-
-from httpauth import AuthHandlerAgent
-from httpclient import StringProducer
-
-from benchlib import initialize, sample
-from event import makeEvent
-
- at inlineCallbacks
-def measure(host, port, dtrace, attendeeCount, samples):
- organizerSequence = 1
- user = password = "user%02d" % (organizerSequence,)
- root = "/"
- principal = "/"
- calendar = "event-deletion-benchmark"
-
- authinfo = HTTPDigestAuthHandler()
- authinfo.add_password(
- realm="Test Realm",
- uri="http://%s:%d/" % (host, port),
- user=user,
- passwd=password)
- agent = AuthHandlerAgent(Agent(reactor), authinfo)
-
- # Set up the calendar first
- yield initialize(agent, host, port, user, password, root, principal, calendar)
-
- # An infinite stream of VEVENTs to PUT to the server.
- events = ((i, makeEvent(i, organizerSequence, attendeeCount))
- for i in count(2))
-
- # Create enough events to delete
- uri = 'http://%s:%d/calendars/__uids__/%s/%s/foo-%%d.ics' % (
- host, port, user, calendar)
- headers = Headers({"content-type": ["text/calendar"]})
- urls = []
- for i, body in events:
- urls.append(uri % (i,))
- yield agent.request(
- 'PUT', urls[-1], headers, StringProducer(body))
- if len(urls) == samples:
- break
-
- # Now delete them all
- samples = yield sample(
- dtrace, samples,
- agent, (('DELETE', url) for url in urls).next,
- NO_CONTENT)
- returnValue(samples)
-
Deleted: CalendarServer/trunk/contrib/performance/event_delete_attendee.py
===================================================================
--- CalendarServer/trunk/contrib/performance/event_delete_attendee.py 2011-02-15 19:50:17 UTC (rev 6930)
+++ CalendarServer/trunk/contrib/performance/event_delete_attendee.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -1,35 +0,0 @@
-##
-# Copyright (c) 2010 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-import _event_change
-
-def measure(host, port, dtrace, attendeeCount, samples):
- def deleteAttendees(event, i):
- """
- Add C{i} new attendees to the given event.
- """
- for n in range(attendeeCount):
- # Find the beginning of an ATTENDEE line
- attendee = event.find('ATTENDEE')
- # And the end of it
- eol = event.find('\n', attendee)
- # And remove it
- event = event[:attendee] + event[eol:]
- return event
-
- return _event_change.measure(
- host, port, dtrace, attendeeCount, samples, "delete-attendee",
- deleteAttendees, eventPerSample=True)
Deleted: CalendarServer/trunk/contrib/performance/event_move.py
===================================================================
--- CalendarServer/trunk/contrib/performance/event_move.py 2011-02-15 19:50:17 UTC (rev 6930)
+++ CalendarServer/trunk/contrib/performance/event_move.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -1,77 +0,0 @@
-##
-# Copyright (c) 2010 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-from itertools import count, cycle
-from urllib2 import HTTPDigestAuthHandler
-
-from twisted.internet import reactor
-from twisted.internet.defer import inlineCallbacks, returnValue
-from twisted.web.client import Agent
-from twisted.web.http_headers import Headers
-from twisted.web.http import CREATED
-
-from httpauth import AuthHandlerAgent
-from httpclient import StringProducer
-
-from benchlib import initialize, sample
-from event import makeEvent
-
- at inlineCallbacks
-def measure(host, port, dtrace, attendeeCount, samples):
- organizerSequence = 1
- user = password = "user%02d" % (organizerSequence,)
- root = "/"
- principal = "/"
-
- # Two calendars between which to move the event.
- fooCalendar = "event-move-foo-benchmark"
- barCalendar = "event-move-bar-benchmark"
-
- authinfo = HTTPDigestAuthHandler()
- authinfo.add_password(
- realm="Test Realm",
- uri="http://%s:%d/" % (host, port),
- user=user,
- passwd=password)
- agent = AuthHandlerAgent(Agent(reactor), authinfo)
-
- # Set up the calendars first
- for calendar in [fooCalendar, barCalendar]:
- yield initialize(
- agent, host, port, user, password, root, principal, calendar)
-
- fooURI = 'http://%s:%d/calendars/__uids__/%s/%s/some-event.ics' % (
- host, port, user, fooCalendar)
- barURI = 'http://%s:%d/calendars/__uids__/%s/%s/some-event.ics' % (
- host, port, user, barCalendar)
-
- # Create the event that will move around
- headers = Headers({"content-type": ["text/calendar"]})
- yield agent.request(
- 'PUT', fooURI, headers,
- StringProducer(makeEvent(1, organizerSequence, attendeeCount)))
-
- # Move it around sooo much
- source = cycle([fooURI, barURI])
- dest = cycle([barURI, fooURI])
-
- params = (
- ('MOVE', source.next(),
- Headers({"destination": [dest.next()], "overwrite": ["F"]}))
- for i in count(1))
-
- samples = yield sample(dtrace, samples, agent, params.next, CREATED)
- returnValue(samples)
Deleted: CalendarServer/trunk/contrib/performance/find_calendars.py
===================================================================
--- CalendarServer/trunk/contrib/performance/find_calendars.py 2011-02-15 19:50:17 UTC (rev 6930)
+++ CalendarServer/trunk/contrib/performance/find_calendars.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -1,104 +0,0 @@
-##
-# Copyright (c) 2010 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-from itertools import count
-from urllib2 import HTTPDigestAuthHandler
-
-from twisted.internet import reactor
-from twisted.internet.defer import inlineCallbacks, returnValue
-from twisted.web.client import Agent
-from twisted.web.http_headers import Headers
-from twisted.web.http import MULTI_STATUS
-
-from httpauth import AuthHandlerAgent
-from httpclient import StringProducer
-
-from benchlib import CalDAVAccount, sample
-
-PROPFIND = """\
-<?xml version="1.0" encoding="utf-8"?>
-<x0:propfind xmlns:x0="DAV:" xmlns:x3="http://apple.com/ns/ical/" xmlns:x1="http://calendarserver.org/ns/" xmlns:x2="urn:ietf:params:xml:ns:caldav">
- <x0:prop>
- <x1:xmpp-server/>
- <x1:xmpp-uri/>
- <x1:getctag/>
- <x0:displayname/>
- <x2:calendar-description/>
- <x3:calendar-color/>
- <x3:calendar-order/>
- <x2:supported-calendar-component-set/>
- <x0:resourcetype/>
- <x0:owner/>
- <x2:calendar-free-busy-set/>
- <x2:schedule-calendar-transp/>
- <x2:schedule-default-calendar-URL/>
- <x0:quota-available-bytes/>
- <x0:quota-used-bytes/>
- <x2:calendar-timezone/>
- <x0:current-user-privilege-set/>
- <x1:source/>
- <x1:subscribed-strip-alarms/>
- <x1:subscribed-strip-attachments/>
- <x1:subscribed-strip-todos/>
- <x3:refreshrate/>
- <x1:push-transports/>
- <x1:pushkey/>
- <x1:publish-url/>
- </x0:prop>
-</x0:propfind>
-"""
-
- at inlineCallbacks
-def measure(host, port, dtrace, numCalendars, samples):
- # There's already the "calendar" calendar
- numCalendars -= 1
-
- user = password = "user10"
- root = "/"
- principal = "/"
-
- authinfo = HTTPDigestAuthHandler()
- authinfo.add_password(
- realm="Test Realm",
- uri="http://%s:%d/" % (host, port),
- user=user,
- passwd=password)
- agent = AuthHandlerAgent(Agent(reactor), authinfo)
-
- # Create the number of calendars necessary
- account = CalDAVAccount(
- agent,
- "%s:%d" % (host, port),
- user=user, password=password,
- root=root, principal=principal)
- cal = "/calendars/users/%s/propfind-%%d/" % (user,)
- for i in range(numCalendars):
- yield account.makeCalendar(cal % (i,))
-
- body = StringProducer(PROPFIND)
- params = (
- ('PROPFIND', 'http://%s:%d/calendars/__uids__/%s/' % (host, port, user),
- Headers({"depth": ["1"], "content-type": ["text/xml"]}), body)
- for i in count(1))
-
- samples = yield sample(dtrace, samples, agent, params.next, MULTI_STATUS)
-
- # Delete the calendars we created to leave the server in roughly
- # the same state as we found it.
- for i in range(numCalendars):
- yield account.deleteResource(cal % (i,))
-
- returnValue(samples)
Deleted: CalendarServer/trunk/contrib/performance/find_events.py
===================================================================
--- CalendarServer/trunk/contrib/performance/find_events.py 2011-02-15 19:50:17 UTC (rev 6930)
+++ CalendarServer/trunk/contrib/performance/find_events.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -1,98 +0,0 @@
-##
-# Copyright (c) 2010 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-from itertools import count
-from urllib2 import HTTPDigestAuthHandler
-
-from twisted.internet import reactor
-from twisted.internet.defer import inlineCallbacks, returnValue, gatherResults
-from twisted.internet.task import cooperate
-from twisted.web.client import Agent
-from twisted.web.http_headers import Headers
-from twisted.web.http import MULTI_STATUS
-
-from httpauth import AuthHandlerAgent
-from httpclient import StringProducer
-
-from benchlib import CalDAVAccount, sample
-from event import makeEvent
-
-PROPFIND = """\
-<?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>
-"""
-
-def uploadEvents(numEvents, agent, uri, cal):
- def worker():
- for i in range(numEvents):
- event = makeEvent(i, 1, 0)
- yield agent.request(
- 'PUT',
- '%s%s%d.ics' % (uri, cal, i),
- Headers({"content-type": ["text/calendar"]}),
- StringProducer(event))
- worker = worker()
- return gatherResults([
- cooperate(worker).whenDone() for i in range(3)])
-
-
- at inlineCallbacks
-def measure(host, port, dtrace, numEvents, samples):
- user = password = "user11"
- root = "/"
- principal = "/"
-
- uri = "http://%s:%d/" % (host, port)
- authinfo = HTTPDigestAuthHandler()
- authinfo.add_password(
- realm="Test Realm",
- uri=uri,
- user=user,
- passwd=password)
- agent = AuthHandlerAgent(Agent(reactor), authinfo)
-
- # Create the number of calendars necessary
- account = CalDAVAccount(
- agent,
- "%s:%d" % (host, port),
- user=user, password=password,
- root=root, principal=principal)
- cal = "calendars/users/%s/find-events/" % (user,)
- yield account.makeCalendar("/" + cal)
-
- # Create the indicated number of events on the calendar
- yield uploadEvents(numEvents, agent, uri, cal)
-
- body = StringProducer(PROPFIND)
- params = (
- ('PROPFIND',
- '%scalendars/__uids__/%s/find-events/' % (uri, user),
- Headers({"depth": ["1"], "content-type": ["text/xml"]}), body)
- for i in count(1))
-
- samples = yield sample(dtrace, samples, agent, params.next, MULTI_STATUS)
-
- # Delete the calendar we created to leave the server in roughly
- # the same state as we found it.
- yield account.deleteResource("/" + cal)
-
- returnValue(samples)
Deleted: CalendarServer/trunk/contrib/performance/vfreebusy.py
===================================================================
--- CalendarServer/trunk/contrib/performance/vfreebusy.py 2011-02-15 19:50:17 UTC (rev 6930)
+++ CalendarServer/trunk/contrib/performance/vfreebusy.py 2011-02-15 20:54:05 UTC (rev 6931)
@@ -1,147 +0,0 @@
-##
-# Copyright (c) 2010 Apple Inc. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##
-
-"""
-Benchmark a server's handling of VFREEBUSY requests.
-"""
-
-from urllib2 import HTTPDigestAuthHandler
-from uuid import uuid4
-from datetime import datetime, timedelta
-
-from twisted.internet.defer import inlineCallbacks, returnValue
-from twisted.internet import reactor
-from twisted.web.client import Agent
-from twisted.web.http_headers import Headers
-from twisted.web.http import OK
-
-from httpauth import AuthHandlerAgent
-from httpclient import StringProducer
-from benchlib import initialize, sample
-
-# XXX Represent these as vobjects? Would make it easier to add more vevents.
-event = """\
-BEGIN:VCALENDAR
-VERSION:2.0
-CALSCALE:GREGORIAN
-PRODID:-//Apple Inc.//iCal 4.0.3//EN
-BEGIN:VTIMEZONE
-TZID:America/New_York
-BEGIN:STANDARD
-DTSTART:20071104T020000
-RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU
-TZNAME:EST
-TZOFFSETFROM:-0400
-TZOFFSETTO:-0500
-END:STANDARD
-BEGIN:DAYLIGHT
-DTSTART:20070311T020000
-RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU
-TZNAME:EDT
-TZOFFSETFROM:-0500
-TZOFFSETTO:-0400
-END:DAYLIGHT
-END:VTIMEZONE
-%(VEVENTS)s\
-END:VCALENDAR
-"""
-
-vfreebusy = """\
-BEGIN:VCALENDAR
-CALSCALE:GREGORIAN
-VERSION:2.0
-METHOD:REQUEST
-PRODID:-//Apple Inc.//iCal 4.0.3//EN
-BEGIN:VFREEBUSY
-UID:81F582C8-4E7F-491C-85F4-E541864BE0FA
-DTEND:20100730T150000Z
-ATTENDEE:urn:uuid:user02
-DTSTART:20100730T140000Z
-X-CALENDARSERVER-MASK-UID:EC75A61B-08A3-44FD-BFBB-2457BBD0D490
-DTSTAMP:20100729T174751Z
-ORGANIZER:mailto:user01 at example.com
-SUMMARY:Availability for urn:uuid:user02
-END:VFREEBUSY
-END:VCALENDAR
-"""
-
-def formatDate(d):
- return ''.join(filter(str.isalnum, d.isoformat()))
-
-def makeEvent(i):
- s = """\
-BEGIN:VEVENT
-UID:%(UID)s
-DTSTART;TZID=America/New_York:%(START)s
-DTEND;TZID=America/New_York:%(END)s
-CREATED:20100729T193912Z
-DTSTAMP:20100729T195557Z
-SEQUENCE:%(SEQUENCE)s
-SUMMARY:STUFF IS THINGS
-TRANSP:OPAQUE
-END:VEVENT
-"""
- base = datetime(2010, 7, 30, 11, 15, 00)
- interval = timedelta(hours=2)
- duration = timedelta(hours=1)
- return event % {
- 'VEVENTS': s % {
- 'UID': uuid4(),
- 'START': formatDate(base + i * interval),
- 'END': formatDate(base + i * interval + duration),
- 'SEQUENCE': i,
- },
- }
-
-
-def makeEvents(n):
- return [makeEvent(i) for i in range(n)]
-
-
- at inlineCallbacks
-def measure(host, port, dtrace, events, samples):
- user = password = "user01"
- root = "/"
- principal = "/"
- calendar = "vfreebusy-benchmark"
-
- authinfo = HTTPDigestAuthHandler()
- authinfo.add_password(
- realm="Test Realm",
- uri="http://%s:%d/" % (host, port),
- user=user,
- passwd=password)
- agent = AuthHandlerAgent(Agent(reactor), authinfo)
-
- # First set things up
- account = yield initialize(
- agent, host, port, user, password, root, principal, calendar)
-
- base = "/calendars/users/%s/%s/foo-%%d.ics" % (user, calendar)
- for i, cal in enumerate(makeEvents(events)):
- yield account.writeData(base % (i,), cal, "text/calendar")
-
- method = 'POST'
- uri = 'http://%s:%d/calendars/__uids__/%s/outbox/' % (host, port, user)
- headers = Headers({"content-type": ["text/calendar"]})
- body = StringProducer(vfreebusy)
-
- samples = yield sample(
- dtrace, samples,
- agent, lambda: (method, uri, headers, body),
- OK)
- returnValue(samples)
-
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110215/bd594349/attachment-0001.html>
More information about the calendarserver-changes
mailing list