[CalendarServer-changes] [7548] CalendarServer/trunk/contrib/performance
source_changes at macosforge.org
source_changes at macosforge.org
Thu Jun 2 14:07:45 PDT 2011
Revision: 7548
http://trac.macosforge.org/projects/calendarserver/changeset/7548
Author: exarkun at twistedmatrix.com
Date: 2011-06-02 14:07:44 -0700 (Thu, 02 Jun 2011)
Log Message:
-----------
Implement a workday-centric normal distribution and use it for event creation. incremental step towards more realistic event distribution.
Modified Paths:
--------------
CalendarServer/trunk/contrib/performance/loadtest/config.plist
CalendarServer/trunk/contrib/performance/loadtest/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-02 15:51:45 UTC (rev 7547)
+++ CalendarServer/trunk/contrib/performance/loadtest/config.plist 2011-06-02 21:07:44 UTC (rev 7548)
@@ -72,7 +72,27 @@
<key>params</key>
<dict>
<key>interval</key>
- <integer>25</integer>
+ <integer>60</integer>
+ <key>eventStartDistribution</key>
+ <dict>
+ <key>type</key>
+ <string>stats.WorkDistribution</string>
+ <key>params</key>
+ <dict>
+ <key>daysOfWeek</key>
+ <array>
+ <string>mon</string>
+ <string>tue</string>
+ <string>wed</string>
+ <string>thu</string>
+ <string>fri</string>
+ </array>
+ <key>beginHour</key>
+ <integer>8</integer>
+ <key>endHour</key>
+ <integer>17</integer>
+ </dict>
+ </dict>
</dict>
</dict>
Modified: CalendarServer/trunk/contrib/performance/loadtest/profiles.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/profiles.py 2011-06-02 15:51:45 UTC (rev 7547)
+++ CalendarServer/trunk/contrib/performance/loadtest/profiles.py 2011-06-02 21:07:44 UTC (rev 7548)
@@ -379,8 +379,6 @@
vevent.contents[u'dtend'][0].value = dtend
vevent.contents[u'uid'][0].value = unicode(uuid4())
- print 'Creating event from', dtstart, 'to', dtend
-
href = '%s%s.ics' % (
calendar.url, vevent.contents[u'uid'][0].value)
d = self._client.addEvent(href, vcalendar)
Modified: CalendarServer/trunk/contrib/performance/stats.py
===================================================================
--- CalendarServer/trunk/contrib/performance/stats.py 2011-06-02 15:51:45 UTC (rev 7547)
+++ CalendarServer/trunk/contrib/performance/stats.py 2011-06-02 21:07:44 UTC (rev 7548)
@@ -14,7 +14,7 @@
# limitations under the License.
##
-import random, time
+import random, time, datetime
from zope.interface import Interface, implements
@@ -287,3 +287,61 @@
def sample(self):
return random.normalvariate(self._mu, self._sigma)
+
+
+NUM_WEEKDAYS = 7
+
+class WorkDistribution(object, FancyEqMixin):
+ compareAttributes = ["_daysOfWeek", "_beginHour", "_endHour"]
+
+ _weekdayNames = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]
+
+ now = staticmethod(datetime.datetime.now)
+
+ def __init__(self, daysOfWeek=["mon", "tue", "wed", "thu", "fri"], beginHour=8, endHour=17):
+ self._daysOfWeek = [self._weekdayNames.index(day) for day in daysOfWeek]
+ self._beginHour = beginHour
+ self._endHour = endHour
+ self._helperDistribution = NormalDistribution(
+ # Mean 6 workdays in the future
+ 60 * 60 * 8 * 6,
+ # Standard deviation of 4 workdays
+ 60 * 60 * 8 * 4)
+
+ def astimestamp(self, dt):
+ return time.mktime(dt.timetuple())
+
+
+ def _findWorkAfter(self, when):
+ """
+ Return a two-tuple of the start and end of work hours following
+ C{when}. If C{when} falls within work hours, then the start time will
+ be equal to when.
+ """
+ # Find a workday that follows the timestamp
+ weekday = when.weekday()
+ for i in range(NUM_WEEKDAYS):
+ day = when + datetime.timedelta(days=i)
+ if (weekday + i) % NUM_WEEKDAYS in self._daysOfWeek:
+ # Joy, a day on which work might occur. Find the first hour on
+ # this day when work may start.
+ begin = day.replace(
+ hour=self._beginHour, minute=0, second=0, microsecond=0)
+ end = begin.replace(hour=self._endHour)
+ if end > when:
+ return begin, end
+
+
+ def sample(self):
+ offset = datetime.timedelta(seconds=self._helperDistribution.sample())
+ beginning = self.now()
+ while offset:
+ start, end = self._findWorkAfter(beginning)
+ if end - start > offset:
+ result = start + offset
+ return self.astimestamp(
+ result.replace(
+ minute=result.minute // 15 * 15,
+ second=0, microsecond=0))
+ offset -= (end - start)
+ beginning = end
Modified: CalendarServer/trunk/contrib/performance/test_stats.py
===================================================================
--- CalendarServer/trunk/contrib/performance/test_stats.py 2011-06-02 15:51:45 UTC (rev 7547)
+++ CalendarServer/trunk/contrib/performance/test_stats.py 2011-06-02 21:07:44 UTC (rev 7548)
@@ -14,9 +14,11 @@
# limitations under the License.
##
+from datetime import datetime
+
from twisted.trial.unittest import TestCase
-from stats import SQLDuration, LogNormalDistribution, UniformDiscreteDistribution, quantize
+from stats import SQLDuration, LogNormalDistribution, UniformDiscreteDistribution, WorkDistribution, quantize
class SQLDurationTests(TestCase):
def setUp(self):
@@ -61,7 +63,20 @@
self.assertEqual(dict.fromkeys(population, 10), counts)
+ def test_workdistribution(self):
+ dist = WorkDistribution(["mon", "wed", "thu", "sat"], 10, 20)
+ dist._helperDistribution = UniformDiscreteDistribution([35 * 60 * 60 + 30 * 60])
+ dist.now = lambda: datetime(2011, 5, 29, 18, 5, 36)
+ value = dist.sample()
+ self.assertEqual(
+ # Move past three workdays - monday, wednesday, thursday - using 30
+ # of the hours, and then five and a half hours into the fourth
+ # workday, saturday. Workday starts at 10am, so the sample value
+ # is 3:30pm, ie 1530 hours.
+ datetime(2011, 6, 4, 15, 30, 0), datetime.fromtimestamp(value))
+
+
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/20110602/3e34d66c/attachment.html>
More information about the calendarserver-changes
mailing list