[CalendarServer-changes] [7553] CalendarServer/trunk/contrib/performance
source_changes at macosforge.org
source_changes at macosforge.org
Fri Jun 3 12:57:35 PDT 2011
Revision: 7553
http://trac.macosforge.org/projects/calendarserver/changeset/7553
Author: exarkun at twistedmatrix.com
Date: 2011-06-03 12:57:35 -0700 (Fri, 03 Jun 2011)
Log Message:
-----------
Accept distribution objects in the other profiles as well.
Modified Paths:
--------------
CalendarServer/trunk/contrib/performance/loadtest/config.plist
CalendarServer/trunk/contrib/performance/loadtest/profiles.py
CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py
CalendarServer/trunk/contrib/performance/stats.py
CalendarServer/trunk/contrib/performance/test_stats.py
Modified: CalendarServer/trunk/contrib/performance/loadtest/config.plist
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/config.plist 2011-06-03 00:31:41 UTC (rev 7552)
+++ CalendarServer/trunk/contrib/performance/loadtest/config.plist 2011-06-03 19:57:35 UTC (rev 7553)
@@ -73,6 +73,7 @@
<dict>
<key>interval</key>
<integer>60</integer>
+
<key>eventStartDistribution</key>
<dict>
<key>type</key>
@@ -97,17 +98,39 @@
</dict>
<dict>
+
<key>class</key>
<string>loadtest.profiles.Inviter</string>
-
+
<key>params</key>
<dict>
- <key>interval</key>
- <integer>20</integer>
+ <key>sendInvitationDistribution</key>
+ <dict>
+ <key>type</key>
+ <string>stats.NormalDistribution</string>
+ <key>params</key>
+ <dict>
+ <key>mu</key>
+ <integer>60</integer>
+ <key>sigma</key>
+ <integer>5</integer>
+ </dict>
+ </dict>
- <key>spread</key>
- <integer>3</integer>
+ <key>inviteeDistanceDistribution</key>
+ <dict>
+ <key>type</key>
+ <string>stats.UniformIntegerDistribution</string>
+ <key>params</key>
+ <dict>
+ <key>min</key>
+ <integer>-100</integer>
+ <key>max</key>
+ <integer>101</integer>
+ </dict>
+ </dict>
</dict>
+
</dict>
<dict>
@@ -116,14 +139,21 @@
<key>params</key>
<dict>
- <key>delay</key>
- <integer>10</integer>
-
- <key>spread</key>
- <integer>2</integer>
+ <key>acceptDelayDistribution</key>
+ <dict>
+ <key>type</key>
+ <string>stats.NormalDistribution</string>
+ <key>params</key>
+ <dict>
+ <key>mu</key>
+ <integer>360</integer>
+ <key>sigma</key>
+ <integer>60</integer>
+ </dict>
+ </dict>
</dict>
+
</dict>
-
</array>
<key>weight</key>
Modified: CalendarServer/trunk/contrib/performance/loadtest/profiles.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/profiles.py 2011-06-03 00:31:41 UTC (rev 7552)
+++ CalendarServer/trunk/contrib/performance/loadtest/profiles.py 2011-06-03 19:57:35 UTC (rev 7553)
@@ -31,13 +31,13 @@
from protocol.caldav.definitions import caldavxml
from twisted.python import context
-from twisted.python.log import msg
+from twisted.python.log import msg, err
from twisted.python.failure import Failure
from twisted.internet.defer import Deferred, succeed, fail
from twisted.internet.task import LoopingCall
from twisted.web.http import PRECONDITION_FAILED
-from stats import NearFutureDistribution, UniformDiscreteDistribution, mean, median
+from stats import NearFutureDistribution, NormalDistribution, UniformDiscreteDistribution, mean, median
from loadtest.logger import SummarizingMixin
from loadtest.ical import IncorrectResponseCode
@@ -110,20 +110,35 @@
"""
+def loopWithDistribution(reactor, distribution, function):
+ result = Deferred()
+ def repeat(ignored):
+ reactor.callLater(distribution.sample(), iterate)
+
+ def iterate():
+ d = function()
+ d.addCallbacks(repeat, result.errback)
+
+ repeat(None)
+ return result
+
+
+
class Inviter(ProfileBase):
"""
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 setParameters(self,
+ sendInvitationDistribution=NormalDistribution(600, 60),
+ inviteeDistanceDistribution=UniformDiscreteDistribution(range(-10, 11))):
+ self._sendInvitationDistribution = sendInvitationDistribution
+ self._inviteeDistanceDistribution = inviteeDistanceDistribution
def run(self):
- self._call = LoopingCall(self._invite)
- self._call.clock = self._reactor
- return self._call.start(self._interval)
+ return loopWithDistribution(
+ self._reactor, self._sendInvitationDistribution, self._invite)
def _addAttendee(self, event, attendees):
@@ -137,7 +152,8 @@
invitees.add(att.value)
for i in range(10):
- invitee = max(1, int(self.random.gauss(self._number, self._spread)))
+ invitee = max(
+ 1, self._number + self._inviteeDistanceDistribution.sample())
record = self._sim.getUserRecord(invitee)
uuid = u'urn:uuid:%s' % (record.uid,)
if uuid not in invitees:
@@ -210,16 +226,18 @@
lambda reason: reason.trap(CannotAddAttendee))
return self._newOperation("invite", d)
+ # Oops, no events to play with.
+ return succeed(None)
+
class Accepter(ProfileBase):
"""
A Calendar user who accepts invitations to events.
"""
- def setParameters(self, delay=10, spread=2):
+ def setParameters(self, acceptDelayDistribution=NormalDistribution(1200, 60)):
self._accepting = set()
- self._delay = delay
- self._spread = spread
+ self._acceptDelayDistribution = acceptDelayDistribution
def run(self):
@@ -247,7 +265,7 @@
for attendee in attendees:
if self._isSelfAttendee(attendee):
if attendee.params[u'PARTSTAT'][0] == 'NEEDS-ACTION':
- delay = self.random.gauss(self._delay, self._spread)
+ delay = self._acceptDelayDistribution.sample()
self._accepting.add(href)
self._reactor.callLater(
delay, self._acceptInvitation, href, attendee)
Modified: CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py 2011-06-03 00:31:41 UTC (rev 7552)
+++ CalendarServer/trunk/contrib/performance/loadtest/test_profiles.py 2011-06-03 19:57:35 UTC (rev 7553)
@@ -165,6 +165,10 @@
class Deterministic(object):
+ def __init__(self, value=None):
+ self.value = value
+
+
def gauss(self, mean, stddev):
"""
Pretend to return a value from a gaussian distribution with mu
@@ -178,7 +182,11 @@
return sequence[0]
+ def sample(self):
+ return self.value
+
+
class StubClient(BaseClient):
"""
Stand in for an iCalendar client.
@@ -232,6 +240,16 @@
+class SequentialDistribution(object):
+ def __init__(self, values):
+ self.values = values
+
+
+ def sample(self):
+ return self.values.pop(0)
+
+
+
class InviterTests(TestCase):
"""
Tests for loadtest.profiles.Inviter.
@@ -306,7 +324,7 @@
vevent, event, calendar, client = self._simpleAccount(
userNumber, SIMPLE_EVENT)
inviter = Inviter(Clock(), self.sim, client, userNumber)
- inviter.random = Deterministic()
+ inviter.setParameters(inviteeDistanceDistribution=Deterministic(1))
inviter._invite()
attendees = vevent.contents[u'vevent'][0].contents[u'attendee']
self.assertEquals(len(attendees), 1)
@@ -330,11 +348,10 @@
selfNumber, SIMPLE_EVENT)
otherNumber = 20
- values = [selfNumber, otherNumber]
+ values = [selfNumber - selfNumber, otherNumber - selfNumber]
inviter = Inviter(Clock(), self.sim, client, selfNumber)
- inviter.random = Deterministic()
- inviter.random.gauss = lambda mu, sigma: values.pop(0)
+ inviter.setParameters(inviteeDistanceDistribution=SequentialDistribution(values))
inviter._invite()
attendees = vevent.contents[u'vevent'][0].contents[u'attendee']
self.assertEquals(len(attendees), 1)
@@ -360,11 +377,10 @@
invitee = vevent.contents[u'vevent'][0].contents[u'attendee'][0]
inviteeNumber = int(invitee.params[u'CN'][0].split()[1])
anotherNumber = inviteeNumber + 5
- values = [inviteeNumber, anotherNumber]
+ values = [inviteeNumber - selfNumber, anotherNumber - selfNumber]
inviter = Inviter(Clock(), self.sim, client, selfNumber)
- inviter.random = Deterministic()
- inviter.random.gauss = lambda mu, sigma: values.pop(0)
+ inviter.setParameters(inviteeDistanceDistribution=SequentialDistribution(values))
inviter._invite()
attendees = vevent.contents[u'vevent'][0].contents[u'attendee']
self.assertEquals(len(attendees), 3)
@@ -387,9 +403,8 @@
vevent, event, calendar, client = self._simpleAccount(
selfNumber, INVITED_EVENT)
inviter = Inviter(Clock(), self.sim, client, selfNumber)
- inviter.random = Deterministic()
# Always return a user number which has already been invited.
- inviter.random.gauss = lambda mu, sigma: 2
+ inviter.setParameters(inviteeDistanceDistribution=Deterministic(2 - selfNumber))
inviter._invite()
attendees = vevent.contents[u'vevent'][0].contents[u'attendee']
self.assertEquals(len(attendees), 2)
@@ -527,8 +542,7 @@
client._setEvent(inboxEvent.url, inboxEvent)
accepter = Accepter(clock, self.sim, client, userNumber)
- accepter.random = Deterministic()
- accepter.random.gauss = lambda mu, sigma: randomDelay
+ accepter.setParameters(Deterministic(randomDelay))
accepter.eventChanged(event.url)
clock.advance(randomDelay)
@@ -564,8 +578,7 @@
event = Event(calendarURL + u'1234.ics', None, vevent)
client._events[event.url] = event
accepter = Accepter(clock, self.sim, client, userNumber)
- accepter.random = Deterministic()
- accepter.random.gauss = lambda mu, sigma: randomDelay
+ accepter.setParameters(Deterministic(randomDelay))
accepter.eventChanged(event.url)
clock.advance(randomDelay)
@@ -608,8 +621,7 @@
client._setEvent(event.url, event)
accepter = Accepter(clock, self.sim, client, userNumber)
- accepter.random = Deterministic()
- accepter.random.gauss = lambda mu, sigma: randomDelay
+ accepter.setParameters(Deterministic(randomDelay))
client.rescheduled.add(event.url)
Modified: CalendarServer/trunk/contrib/performance/stats.py
===================================================================
--- CalendarServer/trunk/contrib/performance/stats.py 2011-06-03 00:31:41 UTC (rev 7552)
+++ CalendarServer/trunk/contrib/performance/stats.py 2011-06-03 19:57:35 UTC (rev 7553)
@@ -289,6 +289,19 @@
return random.normalvariate(self._mu, self._sigma)
+
+class UniformIntegerDistribution(object, FancyEqMixin):
+ compareAttributes = ['_min', '_max']
+
+ def __init__(self, min, max):
+ self._min = min
+ self._max = max
+
+
+ def sample(self):
+ return int(random.uniform(self._min, self._max))
+
+
NUM_WEEKDAYS = 7
class WorkDistribution(object, FancyEqMixin):
Modified: CalendarServer/trunk/contrib/performance/test_stats.py
===================================================================
--- CalendarServer/trunk/contrib/performance/test_stats.py 2011-06-03 00:31:41 UTC (rev 7552)
+++ CalendarServer/trunk/contrib/performance/test_stats.py 2011-06-03 19:57:35 UTC (rev 7553)
@@ -18,7 +18,9 @@
from twisted.trial.unittest import TestCase
-from stats import SQLDuration, LogNormalDistribution, UniformDiscreteDistribution, WorkDistribution, quantize
+from stats import (
+ SQLDuration, LogNormalDistribution, UniformDiscreteDistribution,
+ UniformIntegerDistribution, WorkDistribution, quantize)
class SQLDurationTests(TestCase):
def setUp(self):
@@ -76,7 +78,15 @@
datetime(2011, 6, 4, 15, 30, 0), datetime.fromtimestamp(value))
+ def test_uniform(self):
+ dist = UniformIntegerDistribution(-5, 10)
+ for i in range(100):
+ value = dist.sample()
+ self.assertTrue(-5 <= value < 10)
+ self.assertIsInstance(value, int)
+
+
class QuantizationTests(TestCase):
"""
Tests for L{quantize} which constructs discrete datasets of
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110603/d97c3175/attachment-0001.html>
More information about the calendarserver-changes
mailing list