[CalendarServer-changes] [6691] CalendarServer/trunk/contrib/performance/loadtest

source_changes at macosforge.org source_changes at macosforge.org
Tue Dec 14 13:02:56 PST 2010


Revision: 6691
          http://trac.macosforge.org/projects/calendarserver/changeset/6691
Author:   exarkun at twistedmatrix.com
Date:     2010-12-14 13:02:51 -0800 (Tue, 14 Dec 2010)
Log Message:
-----------
Something that can run a few ical.SnowLeopard instances in parallel, perhaps eventually also offering the ability to configure them in various ways.

Modified Paths:
--------------
    CalendarServer/trunk/contrib/performance/loadtest/ical.py

Added Paths:
-----------
    CalendarServer/trunk/contrib/performance/loadtest/population.py

Modified: CalendarServer/trunk/contrib/performance/loadtest/ical.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/ical.py	2010-12-14 19:49:05 UTC (rev 6690)
+++ CalendarServer/trunk/contrib/performance/loadtest/ical.py	2010-12-14 21:02:51 UTC (rev 6691)
@@ -16,6 +16,7 @@
 ##
 
 from operator import getitem
+from pprint import pprint
 
 from xml.etree import ElementTree
 ElementTree.QName.__repr__ = lambda self: '<QName %r>' % (self.text,)
@@ -152,9 +153,10 @@
                     'depth': ['1']}),
             StringProducer(self._STARTUP_CALENDARHOME_PROPFIND))
         d.addCallback(readBody)
-        d.addCallback(self._parsePROPFINDResponse)
+        d.addCallback(self._extractCalendars)
         def report(result):
-            print result
+            # pprint(result)
+            pass
         d.addCallback(report)
         return d
 
@@ -196,19 +198,19 @@
 
         # Do another kind of thing I guess
         principalCollection = hrefs[davxml.principal_collection_set].toString()
-        print (yield self._principalsReport(principalCollection))
+        (yield self._principalsReport(principalCollection))
 
         # Whatever
         calendarHome = hrefs[caldavxml.calendar_home_set].toString()
-        print (yield self._calendarHomePropfind(calendarHome))
+        (yield self._calendarHomePropfind(calendarHome))
 
         # Learn stuff I guess
         notificationURL = hrefs[csxml.notification_URL].toString()
-        print (yield self._notificationPropfind(notificationURL))
+        (yield self._notificationPropfind(notificationURL))
 
         # More too
         principalURL = hrefs[davxml.principal_URL].toString()
-        print (yield self._principalReport(principalURL))
+        (yield self._principalReport(principalURL))
 
         returnValue(principal)
 

Added: CalendarServer/trunk/contrib/performance/loadtest/population.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/population.py	                        (rev 0)
+++ CalendarServer/trunk/contrib/performance/loadtest/population.py	2010-12-14 21:02:51 UTC (rev 6691)
@@ -0,0 +1,125 @@
+##
+# Copyright (c) 2010 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.
+#
+##
+
+"""
+Tools for generating a population of CalendarServer users based on
+certain usage parameters.
+"""
+
+from itertools import izip
+
+from loadtest.ical import SnowLeopard
+
+
+class PopulationParameters(object):
+    """
+    Descriptive statistics about a population of Calendar Server users.
+    """
+    def clientTypes(self):
+        """
+        Return a list of two-tuples giving the weights and types of
+        clients in the population.
+        """
+        return [(1, SnowLeopard)]
+
+
+
+class Populator(object):
+    """
+    @ivar userPattern: A C{str} giving a formatting pattern to use to
+        construct usernames.  The string will be interpolated with a
+        single integer, the incrementing counter of how many users
+        have thus far been "used".
+
+    @ivar passwordPattern: Similar to C{userPattern}, but for
+        passwords.
+    """
+    def __init__(self, random):
+        self._random = random
+
+
+    def _cycle(self, elements):
+        while True:
+            for (weight, value) in elements:
+                for i in range(weight):
+                    yield value
+
+
+    def populate(self, parameters):
+        """
+        Generate individuals such as might be randomly selected from a
+        population with the given parameters.
+        
+        @type parameters: L{PopulationParameters}
+        @rtype: generator of L{ICalendarClient} providers
+        """
+        for (clientType,) in izip(self._cycle(parameters.clientTypes())):
+            yield clientType
+
+
+class CalendarClientSimulator(object):
+    def __init__(self, populator, parameters, reactor, host, port):
+        self.populator = populator
+        self.reactor = reactor
+        self.host = host
+        self.port = port
+        self._pop = self.populator.populate(parameters)
+        self._user = 1
+
+
+    def _nextUser(self):
+        from urllib2 import HTTPDigestAuthHandler
+        user = "user%02d" % (self._user,)
+        self._user += 1
+        auth = HTTPDigestAuthHandler()
+        auth.add_password(
+            realm="Test Realm",
+            uri="http://127.0.0.1:8008/",
+            user=user,
+            passwd=user)
+        return user, auth
+
+
+    def add(self, numClients):
+        for n in range(numClients):
+            user, auth = self._nextUser()
+            client = self._pop.next()(self.reactor, self.host, self.port, user, auth)
+            client.run()
+        print 'Now running', self._user, 'clients.'
+
+
+    
+def main():
+    import random
+
+    from twisted.internet import reactor
+    from twisted.internet.task import LoopingCall
+
+    r = random.Random()
+    r.seed(100)
+    populator = Populator(r)
+    parameters = PopulationParameters()
+    simulator = CalendarClientSimulator(
+        populator, parameters, reactor, '127.0.0.1', 8008)
+
+    # Uh yea let's see
+    LoopingCall(simulator.add, 1).start(1)
+
+    reactor.run()
+
+if __name__ == '__main__':
+    main()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20101214/7cbe25f4/attachment.html>


More information about the calendarserver-changes mailing list