[CalendarServer-changes] [7531] CalendarServer/trunk/contrib/performance
source_changes at macosforge.org
source_changes at macosforge.org
Thu May 26 13:13:40 PDT 2011
Revision: 7531
http://trac.macosforge.org/projects/calendarserver/changeset/7531
Author: exarkun at twistedmatrix.com
Date: 2011-05-26 13:13:40 -0700 (Thu, 26 May 2011)
Log Message:
-----------
Add ability to pass parameters to profile objects; move hard-coded timing/etc constants out of profile implementations and into config plist
Modified Paths:
--------------
CalendarServer/trunk/contrib/performance/loadtest/config.plist
CalendarServer/trunk/contrib/performance/loadtest/population.py
CalendarServer/trunk/contrib/performance/loadtest/profiles.py
CalendarServer/trunk/contrib/performance/loadtest/sim.py
CalendarServer/trunk/contrib/performance/loadtest/test_sim.py
CalendarServer/trunk/contrib/performance/run.sh
CalendarServer/trunk/contrib/performance/stats.py
CalendarServer/trunk/contrib/performance/test_stats.py
CalendarServer/trunk/contrib/performance/todo
Modified: CalendarServer/trunk/contrib/performance/loadtest/config.plist
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/config.plist 2011-05-26 20:08:42 UTC (rev 7530)
+++ CalendarServer/trunk/contrib/performance/loadtest/config.plist 2011-05-26 20:13:40 UTC (rev 7531)
@@ -64,9 +64,46 @@
<key>profiles</key>
<array>
- <string>loadtest.profiles.Eventer</string>
- <string>loadtest.profiles.Inviter</string>
- <string>loadtest.profiles.Accepter</string>
+
+ <dict>
+ <key>class</key>
+ <string>loadtest.profiles.Eventer</string>
+
+ <key>params</key>
+ <dict>
+ <key>interval</key>
+ <integer>25</integer>
+ </dict>
+ </dict>
+
+ <dict>
+ <key>class</key>
+ <string>loadtest.profiles.Inviter</string>
+
+ <key>params</key>
+ <dict>
+ <key>interval</key>
+ <integer>20</integer>
+
+ <key>spread</key>
+ <integer>3</integer>
+ </dict>
+ </dict>
+
+ <dict>
+ <key>class</key>
+ <string>loadtest.profiles.Accepter</string>
+
+ <key>params</key>
+ <dict>
+ <key>delay</key>
+ <integer>10</integer>
+
+ <key>spread</key>
+ <integer>2</integer>
+ </dict>
+ </dict>
+
</array>
<key>weight</key>
Modified: CalendarServer/trunk/contrib/performance/loadtest/population.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/population.py 2011-05-26 20:08:42 UTC (rev 7530)
+++ CalendarServer/trunk/contrib/performance/loadtest/population.py 2011-05-26 20:13:40 UTC (rev 7531)
@@ -33,10 +33,31 @@
from loadtest.ical import SnowLeopard, RequestLogger
from loadtest.profiles import Eventer, Inviter, Accepter
+
+class ProfileType(object, FancyEqMixin):
+ """
+ @ivar profileType: A L{ProfileBase} subclass, or an L{ICalendarUserProfile}
+ implementation.
+
+ @ivar params: A C{dict} which will be passed to C{profileType} as keyword
+ arguments to create a new profile instance.
+ """
+ compareAttributes = ("profileType", "params")
+
+ def __init__(self, profileType, params):
+ self.profileType = profileType
+ self.params = params
+
+
+ def __call__(self, reactor, client, number):
+ return self.profileType(reactor, client, number, **self.params)
+
+
+
class ClientType(object, FancyEqMixin):
"""
@ivar clientType: An L{ICalendarClient} implementation
- @ivar profileTypes: A list of L{ICalendarUserProfile} implementations
+ @ivar profileTypes: A list of L{ProfileType} instances
"""
compareAttributes = ("clientType", "profileTypes")
Modified: CalendarServer/trunk/contrib/performance/loadtest/profiles.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/profiles.py 2011-05-26 20:08:42 UTC (rev 7530)
+++ CalendarServer/trunk/contrib/performance/loadtest/profiles.py 2011-05-26 20:13:40 UTC (rev 7531)
@@ -49,12 +49,17 @@
"""
random = random
- def __init__(self, reactor, client, userNumber):
+ def __init__(self, reactor, client, userNumber, **params):
self._reactor = reactor
self._client = client
self._number = userNumber
+ self.setParameters(**params)
+ def setParameters(self):
+ pass
+
+
def _calendarsOfType(self, calendarType):
return [
cal
@@ -109,11 +114,15 @@
"""
A Calendar user who invites and de-invites other users to events.
"""
+ def setParameters(self, interval=20, spread=3):
+ self._interval = interval
+ self._spread = spread
+
+
def run(self):
self._call = LoopingCall(self._invite)
self._call.clock = self._reactor
- # XXX Base this on something real
- return self._call.start(20)
+ return self._call.start(self._interval)
def _addAttendee(self, event, attendees):
@@ -126,7 +135,7 @@
invitees.add(att.value)
for i in range(10):
- invitee = max(1, int(self.random.gauss(self._number, 3)))
+ invitee = max(1, int(self.random.gauss(self._number, self._spread)))
uuid = u'urn:uuid:user%02d' % (invitee,)
if uuid not in invitees:
break
@@ -207,10 +216,10 @@
"""
A Calendar user who accepts invitations to events.
"""
-
- def __init__(self, reactor, client, userNumber):
- ProfileBase.__init__(self, reactor, client, userNumber)
+ def setParameters(self, delay=10, spread=2):
self._accepting = set()
+ self._delay = delay
+ self._spread = spread
def run(self):
@@ -238,8 +247,7 @@
for attendee in attendees:
if self._isSelfAttendee(attendee):
if attendee.params[u'PARTSTAT'][0] == 'NEEDS-ACTION':
- # XXX Base this on something real
- delay = self.random.gauss(10, 2)
+ delay = self.random.gauss(self._delay, self._spread)
self._accepting.add(href)
self._reactor.callLater(
delay, self._acceptInvitation, href, attendee)
@@ -332,12 +340,14 @@
END:VEVENT
END:VCALENDAR
"""))[0]
+ def setParameters(self, interval=25):
+ self._interval = interval
+
def run(self):
self._call = LoopingCall(self._addEvent)
self._call.clock = self._reactor
- # XXX Base this on something real
- return self._call.start(25)
+ return self._call.start(self._interval)
def _addEvent(self):
Modified: CalendarServer/trunk/contrib/performance/loadtest/sim.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/sim.py 2011-05-26 20:08:42 UTC (rev 7530)
+++ CalendarServer/trunk/contrib/performance/loadtest/sim.py 2011-05-26 20:13:40 UTC (rev 7531)
@@ -30,7 +30,7 @@
from loadtest.ical import SnowLeopard
from loadtest.profiles import Eventer, Inviter, Accepter
from loadtest.population import (
- Populator, ClientType, PopulationParameters, SmoothRampUp,
+ Populator, ProfileType, ClientType, PopulationParameters, SmoothRampUp,
CalendarClientSimulator)
@@ -193,7 +193,9 @@
clientConfig["weight"],
ClientType(
namedAny(clientConfig["software"]),
- [namedAny(profile)
+ [ProfileType(
+ namedAny(profile["class"]),
+ profile["params"])
for profile in clientConfig["profiles"]]))
if not parameters.clients:
parameters.addClient(
Modified: CalendarServer/trunk/contrib/performance/loadtest/test_sim.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/test_sim.py 2011-05-26 20:08:42 UTC (rev 7530)
+++ CalendarServer/trunk/contrib/performance/loadtest/test_sim.py 2011-05-26 20:13:40 UTC (rev 7531)
@@ -34,7 +34,7 @@
from loadtest.profiles import Eventer, Inviter, Accepter
from loadtest.population import (
SmoothRampUp, ClientType, PopulationParameters, Populator, CalendarClientSimulator,
- SimpleStatistics)
+ ProfileType, SimpleStatistics)
from loadtest.sim import (
Server, Arrival, SimOptions, LoadSimulator, LagTrackingReactor, main)
@@ -302,12 +302,13 @@
config.setContent(writePlistToString({
"clients": [{
"software": "loadtest.ical.SnowLeopard",
- "profiles": ["loadtest.profiles.Eventer"],
+ "profiles": [{"class": "loadtest.profiles.Eventer", "params": {"interval": 25}}],
"weight": 3,
}]}))
sim = LoadSimulator.fromCommandLine(['--config', config.path])
expectedParameters = PopulationParameters()
- expectedParameters.addClient(3, ClientType(SnowLeopard, [Eventer]))
+ expectedParameters.addClient(
+ 3, ClientType(SnowLeopard, [ProfileType(Eventer, {"interval": 25})]))
self.assertEquals(sim.parameters, expectedParameters)
Modified: CalendarServer/trunk/contrib/performance/run.sh
===================================================================
--- CalendarServer/trunk/contrib/performance/run.sh 2011-05-26 20:08:42 UTC (rev 7530)
+++ CalendarServer/trunk/contrib/performance/run.sh 2011-05-26 20:13:40 UTC (rev 7531)
@@ -20,6 +20,6 @@
source support/shell.sh
popd
-export PYTHONPATH=$PYTHONPATH:~/Projects/CalDAVClientLibrary/trunk/src
+export PYTHONPATH=$PYTHONPATH:~/Projects/CalendarServer/CalDAVClientLibrary/src
exec "$@"
Modified: CalendarServer/trunk/contrib/performance/stats.py
===================================================================
--- CalendarServer/trunk/contrib/performance/stats.py 2011-05-26 20:08:42 UTC (rev 7530)
+++ CalendarServer/trunk/contrib/performance/stats.py 2011-05-26 20:13:40 UTC (rev 7531)
@@ -200,3 +200,13 @@
def summarize(self, samples):
return _Statistic.summarize(self, self.squash(samples))
+
+
+def quantize(data):
+ """
+ Given some continuous data, quantize it into appropriately sized
+ discrete buckets (eg, as would be suitable for constructing a
+ histogram of the values).
+ """
+ buckets = {}
+ return []
Modified: CalendarServer/trunk/contrib/performance/test_stats.py
===================================================================
--- CalendarServer/trunk/contrib/performance/test_stats.py 2011-05-26 20:08:42 UTC (rev 7530)
+++ CalendarServer/trunk/contrib/performance/test_stats.py 2011-05-26 20:13:40 UTC (rev 7531)
@@ -16,7 +16,7 @@
from unittest import TestCase
-from stats import SQLDuration
+from stats import SQLDuration, quantize
class SQLDurationTests(TestCase):
def setUp(self):
@@ -40,3 +40,40 @@
self.stat.normalize('SELECT foo FROM bar WHERE True'),
'SELECT foo FROM bar WHERE ?')
+
+class QuantizationTests(TestCase):
+ """
+ Tests for L{quantize} which constructs discrete datasets of
+ dynamic quantization from continuous datasets.
+ """
+ def test_one(self):
+ """
+ A single data point is put into a bucket equal to its value and returned.
+ """
+ dataset = [5.0]
+ expected = [(5.0, [5.0])]
+ self.assertEqual(quantize(dataset), expected)
+
+
+ def test_two(self):
+ """
+ Each of two values are put into buckets the size of the
+ standard deviation of the sample.
+ """
+ dataset = [2.0, 5.0]
+ expected = [(1.5, [2.0]), (4.5, [5.0])]
+ self.assertEqual(quantize(dataset), expected)
+
+
+ def xtest_three(self):
+ """
+ If two out of three values fall within one bucket defined by
+ the standard deviation of the sample, that bucket is split in
+ half so each bucket has one value.
+ """
+
+
+ def xtest_alpha(self):
+ """
+ This exercises one simple case of L{quantize} with a small amount of data.
+ """
Modified: CalendarServer/trunk/contrib/performance/todo
===================================================================
--- CalendarServer/trunk/contrib/performance/todo 2011-05-26 20:08:42 UTC (rev 7530)
+++ CalendarServer/trunk/contrib/performance/todo 2011-05-26 20:13:40 UTC (rev 7531)
@@ -1,4 +1,34 @@
-description of each benchmark on the website
-investigate the performance regression near r6270 to see if it is real
-benchmarks for larger calendars (more events)
-extend report to know about linear scaling, quadratic scaling, etc perhaps
+Client profiles
+ - SnowLeopard iCal profile
+ - XMPP/push
+ - Delete from inbox
+ - Resync?
+ - Separate init behavior from normal operational behavior
+
+ - iPhone iCal profile
+ - Everything
+
+ - Lion iCal profile
+ - Everything
+
+Behavior models
+ - Allow configuration of
+ - Event creation
+ - Invitations
+ - Accept invitation
+
+Measurements/Reporting
+ - Collect aggregate task stats
+ - periodic poll
+ - event
+ - invite
+ - startup
+ - day zero? resync? pollb? eventb? startupb? resyncb?
+ - still need to figure out what these are/mean
+ - QoS reports
+ - configurable pass/fail levels
+
+Server initialization
+ - Accounts
+ - DirectoryService? LDAP?
+ -
\ No newline at end of file
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110526/b874e8c0/attachment-0001.html>
More information about the calendarserver-changes
mailing list