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

source_changes at macosforge.org source_changes at macosforge.org
Tue May 31 10:36:37 PDT 2016


Revision: 15645
          http://trac.calendarserver.org//changeset/15645
Author:   sagen at apple.com
Date:     2016-05-31 10:36:37 -0700 (Tue, 31 May 2016)
Log Message:
-----------
Add client sim profiles for deep refreshes and time range queries

Modified Paths:
--------------
    CalendarServer/trunk/contrib/performance/loadtest/clients.plist
    CalendarServer/trunk/contrib/performance/loadtest/config.plist
    CalendarServer/trunk/contrib/performance/loadtest/ical.py
    CalendarServer/trunk/contrib/performance/loadtest/profiles.py

Modified: CalendarServer/trunk/contrib/performance/loadtest/clients.plist
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/clients.plist	2016-05-31 17:34:48 UTC (rev 15644)
+++ CalendarServer/trunk/contrib/performance/loadtest/clients.plist	2016-05-31 17:36:37 UTC (rev 15645)
@@ -731,6 +731,45 @@
 					</dict>
 
 
+					<!-- A profile which periodically does calendar-query reports
+						on a random calendar. -->
+					<dict>
+						<key>class</key>
+						<string>contrib.performance.loadtest.profiles.TimeRanger</string>
+
+						<key>params</key>
+						<dict>
+							<key>enabled</key>
+							<false/>
+
+							<!-- Define the interval (in seconds) at which this profile will use
+								its client to run a report. -->
+							<key>interval</key>
+							<integer>10</integer>
+
+						</dict>
+					</dict>
+
+
+					<!-- A profile which periodically does a "deep refresh" of PROPFINDs
+					    on each calendar. -->
+					<dict>
+						<key>class</key>
+						<string>contrib.performance.loadtest.profiles.DeepRefresher</string>
+
+						<key>params</key>
+						<dict>
+							<key>enabled</key>
+							<true/>
+
+							<!-- Define the interval (in seconds) at which this profile will use
+								its client to refresh. -->
+							<key>interval</key>
+							<integer>600</integer>
+
+						</dict>
+					</dict>
+
 					<!-- A profile which will periodically reset itself, as if a user removed
 						and re-added their account. -->
 					<dict>
@@ -806,8 +845,9 @@
 				<!-- Determine the frequency at which this client configuration will
 					appear in the clients which are created by the load tester. -->
 				<key>weight</key>
-				<integer>1</integer>
+				<integer>2</integer>
 			</dict>
+
 		</array>
 	</dict>
 </plist>

Modified: CalendarServer/trunk/contrib/performance/loadtest/config.plist
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/config.plist	2016-05-31 17:34:48 UTC (rev 15644)
+++ CalendarServer/trunk/contrib/performance/loadtest/config.plist	2016-05-31 17:36:37 UTC (rev 15645)
@@ -143,21 +143,21 @@
 			<dict>
 				<!-- groups gives the total number of groups of clients to introduce. -->
 				<key>groups</key>
-				<integer>10</integer>
+				<integer>15</integer>
 
 				<!-- groupSize is the number of clients in each group of clients. It's
 					really only a "smooth" ramp up if this is pretty small. -->
 				<key>groupSize</key>
-				<integer>3</integer>
+				<integer>1</integer>
 
 				<!-- Number of seconds between the introduction of each group. -->
 				<key>interval</key>
-				<integer>3</integer>
+				<integer>15</integer>
 
 				<!-- Number of clients each user is assigned to. -->
 				<!-- Set weight of clients to 1 if this is > 1. Number of clients must match this value if > 1. -->
 				<key>clientsPerUser</key>
-				<integer>2</integer>
+				<integer>3</integer>
 			</dict>
 
 		</dict>

Modified: CalendarServer/trunk/contrib/performance/loadtest/ical.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/ical.py	2016-05-31 17:34:48 UTC (rev 15644)
+++ CalendarServer/trunk/contrib/performance/loadtest/ical.py	2016-05-31 17:36:37 UTC (rev 15645)
@@ -849,7 +849,59 @@
         returnValue((calendars, notificationCollection, result,))
 
 
+
+    def timeRangeQuery(self, url, start, end):
+
+        requestBody = """<?xml version="1.0" encoding="utf-8" ?>
+        <C:calendar-query xmlns:D="DAV:" xmlns:C="urn:ietf:params:xml:ns:caldav">
+            <D:prop>
+                <D:getetag/>
+                <C:calendar-data>
+                    <C:expand start="{start}" end="{end}"/>
+                    <C:comp name="VCALENDAR">
+                        <C:prop name="VERSION"/>
+                        <C:comp name="VEVENT">
+                            <C:prop name="SUMMARY"/>
+                            <C:prop name="DTSTART"/>
+                            <C:prop name="DTEND"/>
+                            <C:prop name="LOCATION"/>
+                            <C:prop name="UID"/>
+                            <C:prop name="RECURRENCE-ID"/>
+                        </C:comp>
+                    </C:comp>
+                </C:calendar-data>
+            </D:prop>
+            <C:filter>
+                <C:comp-filter name="VCALENDAR">
+                    <C:comp-filter name="VEVENT">
+                        <C:time-range start="{start}" end="{end}"/>
+                    </C:comp-filter>
+                </C:comp-filter>
+            </C:filter>
+        </C:calendar-query>""".format(start=start, end=end)
+
+        return self._report(
+            url,
+            requestBody,
+            allowedStatus=(MULTI_STATUS,),
+            method_label="REPORT{calendar-query}"
+        )
+
+
     @inlineCallbacks
+    def deepRefresh(self):
+        calendars, notificationCollection, results = yield self._calendarHomePropfind(self.calendarHomeHref)
+        for calendar in calendars:
+            yield self._propfind(
+                calendar.url,
+                self._POLL_CALENDAR_PROPFIND_D1,
+                depth='1',
+                method_label="PROPFIND{calendar}"
+            )
+
+
+
+    @inlineCallbacks
     def _extractPrincipalDetails(self):
         # Using the actual principal URL, retrieve principal information
         principal = yield self._principalPropfind()
@@ -2269,7 +2321,7 @@
 
     _client_type = "OS X 10.11"
 
-    USER_AGENT = "Mac+OS+X/10.11 (15A283) CalendarAgent/361"
+    USER_AGENT = "Mac+OS+X/10.11 (15A283) CalendarAgent/361 Simulator"
 
     # The default interval, used if none is specified in external
     # configuration.  This is also the actual value used by El

Modified: CalendarServer/trunk/contrib/performance/loadtest/profiles.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/profiles.py	2016-05-31 17:34:48 UTC (rev 15644)
+++ CalendarServer/trunk/contrib/performance/loadtest/profiles.py	2016-05-31 17:36:37 UTC (rev 15645)
@@ -46,7 +46,8 @@
 from pycalendar.datetime import DateTime
 from pycalendar.duration import Duration
 
-from datetime import datetime
+from datetime import datetime, timedelta
+import dateutil
 
 class ProfileBase(object):
     """
@@ -1064,7 +1065,69 @@
             return self._newOperation("create", d)
 
 
+class TimeRanger(ProfileBase):
+    """
+    A profile which does time queries
+    """
 
+    def setParameters(
+        self,
+        enabled=True,
+        interval=25,
+    ):
+        self.enabled = enabled
+        self._interval = interval
+
+
+    def run(self):
+        self._call = LoopingCall(self._runQuery)
+        self._call.clock = self._reactor
+        return self._call.start(self._interval)
+
+
+    def _runQuery(self):
+        # Don't perform any operations until the client is up and running
+        if not self._client.started:
+            return succeed(None)
+
+        now = datetime.now(dateutil.tz.tzutc())
+        start = now.strftime("%Y%m%dT%H%M%SZ")
+        end = (now + timedelta(seconds=24 * 60 * 60)).strftime("%Y%m%dT%H%M%SZ")
+
+        calendar = self._getRandomCalendarOfType('VEVENT')
+        return self._client.timeRangeQuery(calendar.url, start, end)
+
+
+
+class DeepRefresher(ProfileBase):
+    """
+    A profile which PROPFINDs all collection in a home
+    """
+
+    def setParameters(
+        self,
+        enabled=True,
+        interval=25,
+    ):
+        self.enabled = enabled
+        self._interval = interval
+
+
+    def run(self):
+        self._call = LoopingCall(self._deepRefresh)
+        self._call.clock = self._reactor
+        return self._call.start(self._interval)
+
+
+    def _deepRefresh(self):
+        # Don't perform any operations until the client is up and running
+        if not self._client.started:
+            return succeed(None)
+
+        return self._client.deepRefresh()
+
+
+
 class Resetter(ProfileBase):
     """
     A Calendar user who resets their account and re-downloads everything.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20160531/6fb89c6a/attachment-0001.html>


More information about the calendarserver-changes mailing list