[CalendarServer-changes] [15051] CalendarServer/branches/users/sredmond/clientsim/contrib/ performance/loadtest
source_changes at macosforge.org
source_changes at macosforge.org
Tue Aug 18 11:04:26 PDT 2015
Revision: 15051
http://trac.calendarserver.org//changeset/15051
Author: sredmond at apple.com
Date: 2015-08-18 11:04:26 -0700 (Tue, 18 Aug 2015)
Log Message:
-----------
More unit tests
Modified Paths:
--------------
CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/distributions.py
CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/ical.py
CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/profiles.py
CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/push.py
CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/requester.py
CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/templates.py
CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_distributions.py
Added Paths:
-----------
CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/pubsub.py
CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_pubsub.py
CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_push.py
CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_requester.py
CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_resources.py
CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_templates.py
Removed Paths:
-------------
CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/subscribe.py
Modified: CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/distributions.py
===================================================================
--- CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/distributions.py 2015-08-17 21:24:30 UTC (rev 15050)
+++ CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/distributions.py 2015-08-18 18:04:26 UTC (rev 15051)
@@ -20,12 +20,12 @@
Base statistical functions
mean / median / stddev / mad / residuals
-IPopulation interface exposes:
+IDistribution interface exposes:
sample()
Sampling from this distribution must *not* change the underlying behavior of a distribution
-Distributions (all of which implement IPopulation):
+Distributions (all of which implement IDistribution):
UniformDiscreteDistribution
LogNormalDistribution
FixedDistribution
@@ -49,17 +49,19 @@
from twisted.python.util import FancyEqMixin
-class IPopulation(Interface):
+class IDistribution(Interface):
"""Interface for a class that provides a single function, `sample`, which returns a float"""
def sample(): #@NoSelf
pass
+class Bounded
+
class UniformDiscreteDistribution(object, FancyEqMixin):
"""
"""
- implements(IPopulation)
+ implements(IDistribution)
compareAttributes = ['_values']
@@ -85,7 +87,7 @@
class LogNormalDistribution(object, FancyEqMixin):
"""
"""
- implements(IPopulation)
+ implements(IDistribution)
compareAttributes = ['_mu', '_sigma', '_maximum']
@@ -134,7 +136,7 @@
class FixedDistribution(object, FancyEqMixin):
"""
"""
- implements(IPopulation)
+ implements(IDistribution)
compareAttributes = ['_value']
@@ -395,30 +397,16 @@
return None
-class HappyFaceStartDistribution(object, FancyEqMixin):
- compareAttributes = []
- def __init__(self, scale):
- self._scale = scale
-
- def sample(self):
- return nprandom.exponential(self._scale)
-
-class HappyFaceDurationDistribution(object, FancyEqMixin):
- compareAttributes = []
- def __init__(self):
- self._distribution = UniformDiscreteDistribution(60 * 15, 60 * 30)
-
- def sample(self):
- return self._distribution.sample()
-
-
if __name__ == '__main__':
from collections import defaultdict
- mu = 1.5
- sigma = 1.22
+ mu = 15
+ sigma = 12
+ print("Testing LogNormalDistribution with mu={mu}, sigma={sigma}".format(
+ mu=mu, sigma=sigma
+ ))
distribution = LogNormalDistribution(mu, sigma, 100)
result = defaultdict(int)
- for i in range(100000):
+ for _ignore_i in xrange(100000):
s = int(distribution.sample())
if s > 300:
continue
Modified: CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/ical.py
===================================================================
--- CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/ical.py 2015-08-17 21:24:30 UTC (rev 15050)
+++ CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/ical.py 2015-08-18 18:04:26 UTC (rev 15051)
@@ -22,7 +22,7 @@
from caldavclientlibrary.protocol.url import URL
from contrib.performance.httpclient import readBody
-from contrib.performance.loadtest.subscribe import Periodical
+from contrib.performance.loadtest.pubsub import Publisher
from contrib.performance.loadtest.resources import Event, Calendar
from contrib.performance.loadtest.requester import Requester, IncorrectResponseCode
from contrib.performance.loadtest.push import PushMonitor
@@ -293,7 +293,7 @@
# Allow events to go out into the world.
self.catalog = {
- "eventChanged": Periodical(),
+ "eventChanged": Publisher(),
}
self._checking = set()
Modified: CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/profiles.py
===================================================================
--- CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/profiles.py 2015-08-17 21:24:30 UTC (rev 15050)
+++ CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/profiles.py 2015-08-18 18:04:26 UTC (rev 15051)
@@ -864,10 +864,7 @@
PRIORITY_LOW = 9
def _setPriority(self, priority, vtodo):
- if priority == self.PRIORITY_NONE:
- vtodo.removeProperty("PRIORITY")
- else:
- vtodo.replaceProperty(Property("PRIORITY", priority))
+ vtodo.replaceProperty(Property("PRIORITY", priority))
class Completer(TaskBase):
def _markTaskComplete(vtodo):
Added: CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/pubsub.py
===================================================================
--- CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/pubsub.py (rev 0)
+++ CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/pubsub.py 2015-08-18 18:04:26 UTC (rev 15051)
@@ -0,0 +1,48 @@
+##
+# Copyright (c) 2011-2015 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.
+#
+##
+"""
+Publisher-Subscription model
+"""
+class _Subscription(object):
+ def __init__(self, publisher, subscriber):
+ self.publisher = publisher
+ self.subscriber = subscriber
+
+
+ def cancel(self):
+ self.publisher.subscriptions.remove(self)
+
+
+ def issue(self, issue):
+ self.subscriber(issue)
+
+
+
+class Publisher(object):
+ def __init__(self):
+ self.subscriptions = []
+
+
+ def subscribe(self, who):
+ subscription = _Subscription(self, who)
+ self.subscriptions.append(subscription)
+ return subscription
+
+
+ def issue(self, issue):
+ for subscr in self.subscriptions:
+ subscr.issue(issue)
Modified: CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/push.py
===================================================================
--- CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/push.py 2015-08-17 21:24:30 UTC (rev 15050)
+++ CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/push.py 2015-08-18 18:04:26 UTC (rev 15051)
@@ -3,8 +3,7 @@
class PushMonitor(object):
"""
- Representation of a watchguard that monitors
- push notifications (AMP Push)
+ Watchguard that monitors push notifications (AMP Push)
"""
def __init__(
@@ -15,11 +14,16 @@
callback
):
"""
- reactor: Twisted reactor
- ampPushHost: localhost
- ampPushPort: 62311
- callback: a one-argument function that is fired with a calendar href
- upon receipt of a push notification for that resource
+ @param reactor: Twisted reactor
+ @type reactor: twisted.web.reactor
+ @param ampPushHost: AMP host to connect to (e.g. 'localhost')
+ @type ampPushHost: string
+ @param ampPushPort: AMP port to connect to (e.g. 62311)
+ @type ampPushPort: integer
+ @param callback: a one-argument function that is fired
+ with a calendar hrefupon receipt of a push notification
+ for that resource
+ @type callback: one-argument callable
"""
self.reactor = reactor
self.ampPushHost = ampPushHost
Modified: CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/requester.py
===================================================================
--- CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/requester.py 2015-08-17 21:24:30 UTC (rev 15050)
+++ CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/requester.py 2015-08-18 18:04:26 UTC (rev 15051)
@@ -293,7 +293,10 @@
self.expected = expected
self.response = response
+ def __repr__(self):
+ return "%s "
+
class WebClientContextFactory(ClientContextFactory):
"""
A web context factory which ignores the hostname and port and does no
Deleted: CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/subscribe.py
===================================================================
--- CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/subscribe.py 2015-08-17 21:24:30 UTC (rev 15050)
+++ CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/subscribe.py 2015-08-18 18:04:26 UTC (rev 15051)
@@ -1,30 +0,0 @@
-
-class Subscription(object):
- def __init__(self, periodical, subscriber):
- self.periodical = periodical
- self.subscriber = subscriber
-
-
- def cancel(self):
- self.periodical.subscriptions.remove(self)
-
-
- def issue(self, issue):
- self.subscriber(issue)
-
-
-
-class Periodical(object):
- def __init__(self):
- self.subscriptions = []
-
-
- def subscribe(self, who):
- subscription = Subscription(self, who)
- self.subscriptions.append(subscription)
- return subscription
-
-
- def issue(self, issue):
- for subscr in self.subscriptions:
- subscr.issue(issue)
Modified: CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/templates.py
===================================================================
--- CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/templates.py 2015-08-17 21:24:30 UTC (rev 15050)
+++ CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/templates.py 2015-08-18 18:04:26 UTC (rev 15051)
@@ -21,16 +21,15 @@
from twistedcaldav.ical import Component
-# Default event
-# Todo - decide on default timezone, also should we have X-ATAB?
-eventTemplate = Component.fromString("""\
+_baseTemplate = Component.newCalendar()
+
+_veventTemplate = Component.fromString("""\
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Apple Inc.//Mac OS X 10.11//EN
CALSCALE:GREGORIAN
BEGIN:VEVENT
TRANSP:OPAQUE
-X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:AUTOMATIC
SUMMARY:Sample Event
UID:00000000-0000-0000-0000-000000000000
CREATED:00000000T000000Z
@@ -42,6 +41,30 @@
END:VCALENDAR
""".replace("\n", "\r\n"))
+_valarmTemplate = Component.fromString("""\
+BEGIN:VALARM
+X-WR-ALARMUID:00000000-0000-0000-0000-000000000000
+UID:00000000-0000-0000-0000-000000000000
+DESCRIPTION:Sample Alarm
+TRIGGER:-PT5M
+ACTION:DISPLAY
+END:VALARM
+""".replace("\n", "\r\n"))
+
+_vtodoTemplate = Component.fromString("""\
+BEGIN:VTODO
+SUMMARY:Sample Task
+UID:00000000-0000-0000-0000-000000000000
+CREATED:00000000T000000Z
+DTSTAMP:00000000T000000Z
+SEQUENCE:0
+END:VTODO
+""".replace("\n", "\r\n"))
+
+# Default Event
+eventTemplate = _baseTemplate.duplicate()
+
+# Default Alarm
alarmTemplate = Component.fromString("""\
BEGIN:VCALENDAR
VERSION:2.0
@@ -55,8 +78,9 @@
ACTION:DISPLAY
END:VALARM
END:VCALENDAR
-""".replace("\n", "\r\n"))
+""")
+# Default task
taskTemplate = Component.fromString("""\
BEGIN:VCALENDAR
VERSION:2.0
Modified: CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_distributions.py
===================================================================
--- CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_distributions.py 2015-08-17 21:24:30 UTC (rev 15050)
+++ CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_distributions.py 2015-08-18 18:04:26 UTC (rev 15051)
@@ -8,7 +8,18 @@
from pycalendar.datetime import DateTime
from pycalendar.timezone import Timezone
+class DistributionTestBase(TestCase):
+ def getSamples(self, n):
+ samples = []
+ for _ignore_i in xrange(n):
+ samples.append()
+
+ def close(self, n):
+ pass
+
class DistributionTests(TestCase):
+
+
def test_lognormal(self):
dist = LogNormalDistribution(mu=1, sigma=1)
for _ignore_i in range(100):
Added: CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_pubsub.py
===================================================================
--- CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_pubsub.py (rev 0)
+++ CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_pubsub.py 2015-08-18 18:04:26 UTC (rev 15051)
@@ -0,0 +1,86 @@
+##
+# Copyright (c) 2011-2015 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.
+#
+##
+"""
+Tests for loadtest.pubsub
+"""
+from collections import defaultdict
+
+from twisted.trial.unittest import TestCase
+
+from contrib.performance.loadtest.pubsub import Publisher
+
+
+class PubSubTests(TestCase):
+ """Tests for Publisher"""
+ def setUp(self):
+ self.publisher = Publisher()
+ # Maps IDs of subscribers to values issued
+ self.values = defaultdict(list)
+
+
+ def recordValueWithID(self, id):
+ """
+ Return a one-argument callable for use as a subscriber
+ that appends its argument to the list of values associated with id
+ """
+ def recordValue(value):
+ self.values[id].append(value)
+ return recordValue
+
+
+ def test_noSubscribers(self):
+ """When no subscriptions are present, no value is published"""
+ value = 'foobar'
+ self.publisher.issue(value)
+ self.assertEqual(self.values['sub1'], [])
+
+
+ def test_subscribe(self):
+ """Published values propagate to their subscribers"""
+ value = 'foobar'
+ self.publisher.subscribe(self.recordValueWithID('sub1'))
+ self.publisher.issue(value)
+ self.assertEqual(self.values['sub1'], [value])
+
+
+ def test_cancel(self):
+ """Cancelled subscriptions do not receive new publications"""
+ value = 'foobar'
+ subscr = self.publisher.subscribe(self.recordValueWithID('sub1'))
+ subscr.cancel()
+ self.publisher.issue(value)
+ self.assertEqual(self.values['sub1'], [])
+
+
+ def test_multiple_subscriptions(self):
+ """Publisher supports adding and removing multiple subscriptions"""
+ value = 'foobar'
+ subscr1 = self.publisher.subscribe(self.recordValueWithID('sub1'))
+ subscr2 = self.publisher.subscribe(self.recordValueWithID('sub2'))
+ self.publisher.issue(value)
+ self.assertEqual(self.values['sub1'], [value])
+ self.assertEqual(self.values['sub2'], [value])
+
+ subscr2.cancel()
+ self.publisher.issue(value)
+ self.assertEqual(self.values['sub1'], [value, value])
+ self.assertEqual(self.values['sub2'], [value])
+
+ subscr1.cancel()
+ self.publisher.issue(value)
+ self.assertEqual(self.values['sub1'], [value, value])
+ self.assertEqual(self.values['sub2'], [value])
Added: CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_push.py
===================================================================
--- CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_push.py (rev 0)
+++ CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_push.py 2015-08-18 18:04:26 UTC (rev 15051)
@@ -0,0 +1,28 @@
+from twisted.trial.unittest import TestCase
+
+from calendarserver.push.amppush import AMPPushMaster
+
+from contrib.performance.loadtest.push import PushMonitor
+
+class PushMonitorTests(TestCase):
+ def receivedPush(self, href):
+ print href
+
+ def setUp(self):
+ self.pushMaster = AMPPushMaster()
+
+ self.monitor = PushMonitor(
+ None,
+ 'localhost',
+ 62311,
+ self.receivedPush
+ )
+
+ def sendNotification(self, href, pushkey):
+ self.pushMaster.notify(href, pushkey, None, None)
+
+ def test_addPushkey(self):
+ pass
+
+ def test_removePushkey(self):
+ pass
Added: CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_requester.py
===================================================================
--- CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_requester.py (rev 0)
+++ CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_requester.py 2015-08-18 18:04:26 UTC (rev 15051)
@@ -0,0 +1,48 @@
+from twisted.trial.unittest import TestCase
+
+from contrib.performance.loadtest.requester import (
+ Requester, IncorrectResponseCode, WebClientContextFactory
+)
+
+class _FakeAgent(object):
+ def __init__(self):
+ self.requests = []
+ self.next = None
+
+ def request(self, method, uri, headers=None, bodyProducer=None):
+ self.requests.append((method, uri, headers, bodyProducer))
+
+ def setNextResponse(response):
+
+
+ # {'reactor': <contrib.performance.loadtest.trafficlogger.(Logged Reactor) object at 0x10d1860d0>, 'title': '10.11 Intern', 'self': <contrib.performance.loadtest.requester.Requester object at 0x10d184a10>, 'auth': {'digest': <urllib2.HTTPDigestAuthHandler instance at 0x10d192128>, 'basic': <urllib2.HTTPBasicAuthHandler instance at 0x10d180fc8>}, 'headers': {'Connection': ['keep-alive'], 'Accept-Language': ['en-us'], 'Accept-Encoding': ['gzip,deflate'], 'Accept': ['*/*'], 'User-Agent': ['Mac+OS+X/10.11 (15A216g) CalendarAgent/353']}, 'client_id': 'a11bce96-f787-4096-91a3-44f7dbf38a06', 'root': 'https://127.0.0.1:8443', 'uid': u'user01'}
+
+
+class RequesterTests(TestCase):
+ def setUp(self):
+ self.root = '/foo/bar/'
+ self.headers = Headers({
+ 'Connection': ['keep-alive'],
+ 'Accept-Language': ['en-us'],
+ 'Accept-Encoding': ['gzip,deflate'],
+ 'Accept': ['*/*'],
+ 'User-Agent': ['Mac+OS+X/10.11 (15A216g) CalendarAgent/353'
+ }
+ self.title = 'Requester '
+
+ self,
+ root,
+ headers,
+ title,
+ uid,
+ client_id,
+ auth,
+ reactor
+
+
+
+class IncorrectResponseCodeTests(TestCase):
+ pass
+
+class WebClientContextFactoryTests(TestCase):
+ pass
\ No newline at end of file
Added: CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_resources.py
===================================================================
Added: CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_templates.py
===================================================================
--- CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_templates.py (rev 0)
+++ CalendarServer/branches/users/sredmond/clientsim/contrib/performance/loadtest/tests/test_templates.py 2015-08-18 18:04:26 UTC (rev 15051)
@@ -0,0 +1,46 @@
+# -*- test-case-name: contrib.performance.loadtest.test_templates -*-
+##
+# Copyright (c) 2010-2015 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.
+#
+##
+"""
+Tests for loadtest.templates
+"""
+
+from twisted.trial.unittest import TestCase
+
+from contrib.performance.loadtest.templates import eventTemplate, alarmTemplate, taskTemplate
+
+"""
+ensure they're all comps
+and that they are all vcalendars
+with the right prodid and calscale and version
+and that they have the corresponding component
+and that each comp has its required properties
+and that they are all v***
+
+"""
+
+class TemplateTests(TestCase):
+
+
+ def assertTemplateIs(self, component, ):
+ pass
+
+ def test_components(self):
+
+
+ def test_eventTemplate(self):
+ runTests(eventTemplate, component_name="VEVENT", required="")
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20150818/ddad57a1/attachment-0001.html>
More information about the calendarserver-changes
mailing list