[CalendarServer-changes] [15351] CalendarServer/trunk/contrib/performance

source_changes at macosforge.org source_changes at macosforge.org
Tue Dec 1 13:38:14 PST 2015


Revision: 15351
          http://trac.calendarserver.org//changeset/15351
Author:   cdaboo at apple.com
Date:     2015-12-01 13:38:14 -0800 (Tue, 01 Dec 2015)
Log Message:
-----------
Fix old sim configs. Add a tool to run the sim against a range of server revisions.

Modified Paths:
--------------
    CalendarServer/trunk/contrib/performance/loadtest/clients-old.plist
    CalendarServer/trunk/contrib/performance/loadtest/config-old.plist

Added Paths:
-----------
    CalendarServer/trunk/contrib/performance/simanalysis/
    CalendarServer/trunk/contrib/performance/simanalysis/__init__.py
    CalendarServer/trunk/contrib/performance/simanalysis/sim_regress.py

Modified: CalendarServer/trunk/contrib/performance/loadtest/clients-old.plist
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/clients-old.plist	2015-12-01 16:53:48 UTC (rev 15350)
+++ CalendarServer/trunk/contrib/performance/loadtest/clients-old.plist	2015-12-01 21:38:14 UTC (rev 15351)
@@ -55,8 +55,10 @@
 
 					<key>supportAmpPush</key>
 					<true/>
-					<key>ampPushHost</key>
-					<string>localhost</string>
+					<key>ampPushHosts</key>
+					<array>
+						<string>localhost</string>
+				    </array>
 					<key>ampPushPort</key>
 					<integer>62311</integer>
 				</dict>

Modified: CalendarServer/trunk/contrib/performance/loadtest/config-old.plist
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/config-old.plist	2015-12-01 16:53:48 UTC (rev 15350)
+++ CalendarServer/trunk/contrib/performance/loadtest/config-old.plist	2015-12-01 21:38:14 UTC (rev 15351)
@@ -20,9 +20,47 @@
 <plist version="1.0">
 	<dict>
 		<!-- Identify the server to be load tested. -->
-		<key>server</key>
-		<string>https://localhost:8443</string>
+		<key>servers</key>
+		<dict>
+			<key>PodA</key>
+			<dict>
+				<key>enabled</key>
+				<true/>
 
+				<!-- Identify the server to be load tested. -->
+				<key>uri</key>
+				<string>https://localhost:8443</string>
+
+				<!--  Define whether server supports stats socket. -->
+				<key>stats</key>
+				<dict>
+					<key>enabled</key>
+					<true/>
+					<key>Port</key>
+					<integer>8100</integer>
+				</dict>
+			</dict>
+			<key>PodB</key>
+			<dict>
+				<key>enabled</key>
+				<false/>
+
+				<!-- Identify the server to be load tested. -->
+				<key>uri</key>
+				<string>https://localhost:8543</string>
+
+				<!--  Define whether server supports stats socket. -->
+				<key>stats</key>
+				<dict>
+					<key>enabled</key>
+					<true/>
+					<key>Port</key>
+					<integer>8101</integer>
+				</dict>
+			</dict>
+		</dict>
+
+
 		<!-- The template URI for doing initial principal lookup on. -->
 		<key>principalPathTemplate</key>
 		<string>/principals/users/%s/</string>
@@ -37,15 +75,6 @@
 			<integer>8080</integer>
 		</dict>
 
-		<!--  Define whether server supports stats socket. -->
-		<key>serverStats</key>
-		<dict>
-			<key>enabled</key>
-			<true/>
-			<key>Port</key>
-			<integer>8100</integer>
-		</dict>
-
 		<!--  Define whether client data should be re-used. It will always be saved to the specified path.-->
 		<key>clientDataSerialization</key>
 		<dict>
@@ -75,6 +104,11 @@
 					a relative path. This isn't a great solution. -->
 				<key>path</key>
 				<string>contrib/performance/loadtest/accounts.csv</string>
+
+				<!-- When there are accounts for multiple pods, interleave the accounts for each
+					pod so that the arrival mechanism will cycle clients between each pod. -->
+				<key>interleavePods</key>
+				<true/>
 			</dict>
 		</dict>
 

Added: CalendarServer/trunk/contrib/performance/simanalysis/__init__.py
===================================================================
--- CalendarServer/trunk/contrib/performance/simanalysis/__init__.py	                        (rev 0)
+++ CalendarServer/trunk/contrib/performance/simanalysis/__init__.py	2015-12-01 21:38:14 UTC (rev 15351)
@@ -0,0 +1,19 @@
+##
+# Copyright (c) 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.
+##
+
+"""
+Tools to manage sim runs and associated data.
+"""

Added: CalendarServer/trunk/contrib/performance/simanalysis/sim_regress.py
===================================================================
--- CalendarServer/trunk/contrib/performance/simanalysis/sim_regress.py	                        (rev 0)
+++ CalendarServer/trunk/contrib/performance/simanalysis/sim_regress.py	2015-12-01 21:38:14 UTC (rev 15351)
@@ -0,0 +1,179 @@
+##
+# Copyright (c) 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.
+##
+
+import argparse
+import os
+import plistlib
+import shutil
+import subprocess
+import sys
+import time
+
+
+class SimRegress(object):
+    """
+    Class that manages running the sim against a range of SVN revisions.
+    """
+
+    TMP_DIR = "/tmp/CalendarServer-SimRegress"
+
+    def __init__(self, startRev, stopRev, stepRev):
+        self.startRev = startRev
+        self.currentRev = startRev
+        self.stopRev = stopRev
+        self.stepRev = stepRev
+        self.cwd = os.getcwd()
+        self.results = []
+
+
+    def run(self):
+
+        # Get the actual SVN revisions we want to use
+        svn_revs = self.getRevisions()
+        print("SVN Revisions to analyze: {}".format(svn_revs))
+
+        # Create the tmp dir and do initial checkout
+        for revision in svn_revs:
+            self.currentRev = revision
+            logfile = os.path.join(self.cwd, "Log-rev-{}.txt".format(self.currentRev))
+            with open(logfile, "w") as f:
+                self.log = f
+                self.checkRevision()
+                self.buildServer()
+                self.runServer()
+                qos = self.runSim()
+                self.stopServer()
+            with open(logfile) as f:
+                qos = filter(lambda line: line.strip().startswith("Qos : "), f.read().splitlines())
+                qos = float(qos[0].strip()[len("Qos : "):]) if qos else None
+                print("Revision: {}  Qos: {}".format(self.currentRev, qos))
+                self.results.append((self.currentRev, qos))
+
+        print("All revisions complete")
+
+        print("\n*** Results:")
+        print("Rev\tQos")
+        for result in self.results:
+            print("{}\t{:.4f}".format(*result))
+
+
+    def getRevisions(self):
+
+        if self.stopRev is None:
+            print("Determining HEAD revision")
+            out = subprocess.check_output("svn info -r HEAD".split())
+            rev = filter(lambda line: line.startswith("Revision: "), out.splitlines())
+            if rev:
+                self.stopRev = int(rev[0][len("Revision: "):])
+                print("Using HEAD revision: {}".format(self.stopRev))
+
+        return range(self.startRev, self.stopRev, self.stepRev) + [self.stopRev]
+
+
+    def checkRevision(self):
+        # Create the tmp dir and do initial checkout
+        if not os.path.exists(SimRegress.TMP_DIR):
+            os.makedirs(SimRegress.TMP_DIR)
+            os.chdir(SimRegress.TMP_DIR)
+            self.checkoutInitialRevision()
+        else:
+            os.chdir(SimRegress.TMP_DIR)
+            actualRevision = self.currentRevision()
+            if actualRevision > self.currentRev:
+                # If actualRevision code is newer than what we want, always wipe it
+                # and start from scratch
+                shutil.rmtree(SimRegress.TMP_DIR)
+                self.checkRevision()
+            elif actualRevision < self.currentRev:
+                # Upgrade from older revision to what we want
+                self.updateRevision()
+
+
+    def checkoutInitialRevision(self):
+        print("Checking out revision: {}".format(self.startRev))
+        subprocess.call(
+            "svn checkout http://svn.calendarserver.org/repository/calendarserver/CalendarServer/trunk -r {start} .".format(start=self.startRev).split(),
+            stdout=self.log, stderr=self.log,
+        )
+
+
+    def currentRevision(self):
+        print("Checking current revision")
+        out = subprocess.check_output("svn info".split())
+        rev = filter(lambda line: line.startswith("Revision: "), out.splitlines())
+        return int(rev[0][len("Revision: "):]) if rev else None
+
+
+    def updateRevision(self):
+        print("Updating to revision: {}".format(self.currentRev))
+        subprocess.call("svn up -r {rev} .".format(rev=self.currentRev).split())
+
+
+    def patchConfig(self, configPath):
+        """
+        Patch the plist config file to use settings that make sense for the sim.
+
+        @param configPath: path to plist file to patch
+        @type configPath: L{str}
+        """
+
+        f = plistlib.readPlist(configPath)
+        f['Authentication']['Kerberos']['Enabled'] = False
+        plistlib.writePlist(f, configPath)
+
+
+    def buildServer(self):
+        print("Building revision: {}".format(self.currentRev))
+        subprocess.call("./bin/develop".split(), stdout=self.log, stderr=self.log)
+
+
+    def runServer(self):
+        print("Running revision: {}".format(self.currentRev))
+        shutil.copyfile("conf/caldavd-test.plist", "conf/caldavd-dev.plist")
+        self.patchConfig("conf/caldavd-dev.plist")
+        if os.path.exists("data"):
+            shutil.rmtree("data")
+        subprocess.call("./bin/run -nd".split(), stdout=self.log, stderr=self.log)
+        time.sleep(10)
+
+
+    def stopServer(self):
+        print("Stopping revision: {}".format(self.currentRev))
+        subprocess.call("./bin/run -k".split(), stdout=self.log, stderr=self.log)
+
+
+    def runSim(self):
+        print("Running sim")
+        if os.path.exists("/tmp/sim"):
+            shutil.rmtree("/tmp/sim")
+        subprocess.call("{exe} {sim} --config {config} --clients {clients} --runtime 300".format(
+            exe=sys.executable,
+            sim=os.path.join(self.cwd, "contrib/performance/loadtest/sim.py"),
+            config=os.path.join(self.cwd, "contrib/performance/loadtest/config-old.plist"),
+            clients=os.path.join(self.cwd, "contrib/performance/loadtest/clients-old.plist"),
+        ).split(), stdout=self.log, stderr=self.log)
+
+
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser(description="Run the sim tool against a specific range of server revisions.")
+    parser.add_argument("--start", type=int, required=True, help="Revision number to start at")
+    parser.add_argument("--stop", type=int, help="Revision number to stop at")
+    parser.add_argument("--step", default=100, type=int, help="Revision number steps")
+
+    args = parser.parse_args()
+
+    SimRegress(args.start, args.stop, args.step).run()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20151201/02441b23/attachment-0001.html>


More information about the calendarserver-changes mailing list