[CalendarServer-changes] [6722] CalendarServer/trunk/contrib/performance/loadtest
source_changes at macosforge.org
source_changes at macosforge.org
Mon Jan 10 11:46:13 PST 2011
Revision: 6722
http://trac.macosforge.org/projects/calendarserver/changeset/6722
Author: exarkun at twistedmatrix.com
Date: 2011-01-10 11:46:05 -0800 (Mon, 10 Jan 2011)
Log Message:
-----------
Collect success/failure results and start to summarize collected statistics like the existing ccs report does
Modified Paths:
--------------
CalendarServer/trunk/contrib/performance/loadtest/ical.py
CalendarServer/trunk/contrib/performance/loadtest/population.py
Modified: CalendarServer/trunk/contrib/performance/loadtest/ical.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/ical.py 2011-01-10 18:30:40 UTC (rev 6721)
+++ CalendarServer/trunk/contrib/performance/loadtest/ical.py 2011-01-10 19:46:05 UTC (rev 6722)
@@ -26,6 +26,7 @@
from twisted.internet.defer import Deferred, inlineCallbacks, returnValue
from twisted.internet.task import LoopingCall
from twisted.web.http_headers import Headers
+from twisted.web.http import OK, MULTI_STATUS
from twisted.web.client import Agent
from protocol.webdav.propfindparser import PropFindParser
@@ -94,18 +95,20 @@
self._events = {}
- def _request(self, method, url, headers, body):
- # XXX Do return code checking here.
+ def _request(self, expectedResponseCode, method, url, headers, body):
headers.setRawHeaders('User-Agent', [self.USER_AGENT])
d = self.agent.request(method, url, headers, body)
before = self.reactor.seconds()
- def report(passthrough):
+ def report(response):
+ success = response.code == expectedResponseCode
after = self.reactor.seconds()
# XXX This is time to receive response headers, not time
# to receive full response. Should measure the latter, if
# not both.
- msg(type="request", duration=(after - before), url=url)
- return passthrough
+ msg(
+ type="request", success=success, method=method,
+ duration=(after - before), url=url)
+ return response
d.addCallback(report)
return d
@@ -162,6 +165,7 @@
"""
principalURL = '/principals/__uids__/' + user + '/'
d = self._request(
+ MULTI_STATUS,
'PROPFIND',
self.root + principalURL[1:],
Headers({
@@ -178,6 +182,7 @@
if principalCollectionSet.startswith('/'):
principalCollectionSet = principalCollectionSet[1:]
d = self._request(
+ OK,
'REPORT',
self.root + principalCollectionSet,
Headers({
@@ -194,6 +199,7 @@
if not calendarHomeSet.endswith('/'):
calendarHomeSet = calendarHomeSet + '/'
d = self._request(
+ MULTI_STATUS,
'PROPFIND',
self.root + calendarHomeSet,
Headers({
@@ -214,6 +220,7 @@
# First do a PROPFIND on the calendar to learn about events it
# might have.
response = yield self._request(
+ MULTI_STATUS,
'PROPFIND',
self.root + url,
Headers({'content-type': ['text/xml'], 'depth': ['1']}),
@@ -244,6 +251,7 @@
# Next do a REPORT on each event that might have information
# we don't know about.
return self._request(
+ MULTI_STATUS,
'REPORT',
self.root + calendar,
Headers({'content-type': ['text/xml']}),
@@ -265,6 +273,7 @@
if notificationURL.startswith('/'):
notificationURL = notificationURL[1:]
d = self._request(
+ MULTI_STATUS,
'PROPFIND',
self.root + notificationURL,
Headers({
@@ -280,6 +289,7 @@
if principalURL.startswith('/'):
principalURL = principalURL[1:]
d = self._request(
+ OK,
'REPORT',
self.root + principalURL,
Headers({
Modified: CalendarServer/trunk/contrib/performance/loadtest/population.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/population.py 2011-01-10 18:30:40 UTC (rev 6721)
+++ CalendarServer/trunk/contrib/performance/loadtest/population.py 2011-01-10 19:46:05 UTC (rev 6722)
@@ -105,20 +105,82 @@
-class Statistics(object):
+class StatisticsBase(object):
+ def observe(self, event):
+ if event.get('type') == 'request':
+ self.eventReceived(event)
+
+
+
+class SimpleStatistics(StatisticsBase):
def __init__(self):
self._times = []
- def observe(self, event):
- if event.get('type') == 'request':
- self._times.append(event['duration'])
- if len(self._times) == 200:
- print 'mean:', mean(self._times)
- print 'median:', median(self._times)
- print 'stddev:', stddev(self._times)
- print 'mad:', mad(self._times)
- del self._times[:100]
+ def eventReceived(self, event):
+ self._times.append(event['duration'])
+ if len(self._times) == 200:
+ print 'mean:', mean(self._times)
+ print 'median:', median(self._times)
+ print 'stddev:', stddev(self._times)
+ print 'mad:', mad(self._times)
+ del self._times[:100]
+
+
+
+class ReportStatistics(StatisticsBase):
+ _fields = [
+ ('operation', 10, '%10s'),
+ ('count', 8, '%8s'),
+ ('failed', 8, '%8s'),
+ ('>3sec', 8, '%8s'),
+ ('mean', 8, '%8.4f'),
+ ('median', 8, '%8.4f'),
+ ]
+
+ def __init__(self):
+ self._perMethodTimes = {}
+
+
+ def eventReceived(self, event):
+ dataset = self._perMethodTimes.setdefault(event['method'], [])
+ dataset.append((event['success'], event['duration']))
+
+
+ def _printHeader(self):
+ format = []
+ labels = []
+ for (label, width, fmt) in self._fields:
+ format.append('%%%ds' % (width,))
+ labels.append(label)
+ print ''.join(format) % tuple(labels)
+
+
+ def _summarizeData(self, method, data):
+ failed = 0
+ threesec = 0
+ durations = []
+ for (success, duration) in data:
+ if not success:
+ failed += 1
+ if duration > 3:
+ threesec += 1
+ durations.append(duration)
+
+ return method, len(data), failed, threesec, mean(durations), median(durations)
+
+
+ def _printData(self, *values):
+ format = ''.join(fmt for (label, width, fmt) in self._fields)
+ print format % values
+
+
+ def summarize(self):
+ print
+ self._printHeader()
+ for method, data in self._perMethodTimes.iteritems():
+ self._printData(*self._summarizeData(method, data))
+
def main():
import random
@@ -127,7 +189,9 @@
from twisted.internet.task import LoopingCall
from twisted.python.log import addObserver
- addObserver(Statistics().observe)
+ report = ReportStatistics()
+ addObserver(SimpleStatistics().observe)
+ addObserver(report.observe)
r = random.Random()
r.seed(100)
@@ -142,6 +206,7 @@
reactor.callLater(3 * 90, call.stop)
reactor.run()
+ report.summarize()
if __name__ == '__main__':
main()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110110/d1e63c3d/attachment-0001.html>
More information about the calendarserver-changes
mailing list