[CalendarServer-changes] [9708] CalendarServer/trunk/contrib/performance/sqlusage

source_changes at macosforge.org source_changes at macosforge.org
Tue Aug 14 15:17:59 PDT 2012


Revision: 9708
          http://trac.macosforge.org/projects/calendarserver/changeset/9708
Author:   cdaboo at apple.com
Date:     2012-08-14 15:17:59 -0700 (Tue, 14 Aug 2012)
Log Message:
-----------
Add put and invite tests. Add some more command line options. Make it easier to handle multiple users.

Modified Paths:
--------------
    CalendarServer/trunk/contrib/performance/sqlusage/requests/httpTests.py
    CalendarServer/trunk/contrib/performance/sqlusage/requests/multiget.py
    CalendarServer/trunk/contrib/performance/sqlusage/requests/propfind.py
    CalendarServer/trunk/contrib/performance/sqlusage/requests/query.py
    CalendarServer/trunk/contrib/performance/sqlusage/requests/sync.py
    CalendarServer/trunk/contrib/performance/sqlusage/sqlusage.py

Added Paths:
-----------
    CalendarServer/trunk/contrib/performance/sqlusage/requests/invite.py
    CalendarServer/trunk/contrib/performance/sqlusage/requests/put.py

Modified: CalendarServer/trunk/contrib/performance/sqlusage/requests/httpTests.py
===================================================================
--- CalendarServer/trunk/contrib/performance/sqlusage/requests/httpTests.py	2012-08-14 21:42:08 UTC (rev 9707)
+++ CalendarServer/trunk/contrib/performance/sqlusage/requests/httpTests.py	2012-08-14 22:17:59 UTC (rev 9708)
@@ -30,14 +30,13 @@
             self.rows = rows
             self.timing = timing
         
-    def __init__(self, label, session, href, logFilePath):
+    def __init__(self, label, sessions, logFilePath):
         """
         @param label: label used to identify the test
         @type label: C{str}
         """
         self.label = label
-        self.session = session
-        self.baseHref = href
+        self.sessions = sessions
         self.logFilePath = logFilePath
         self.result = None
 

Added: CalendarServer/trunk/contrib/performance/sqlusage/requests/invite.py
===================================================================
--- CalendarServer/trunk/contrib/performance/sqlusage/requests/invite.py	                        (rev 0)
+++ CalendarServer/trunk/contrib/performance/sqlusage/requests/invite.py	2012-08-14 22:17:59 UTC (rev 9708)
@@ -0,0 +1,92 @@
+##
+# Copyright (c) 2012 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.
+##
+
+from caldavclientlibrary.protocol.url import URL
+from contrib.performance.sqlusage.requests.httpTests import HTTPTestBase
+from pycalendar.datetime import PyCalendarDateTime
+from twext.web2.dav.util import joinURL
+from caldavclientlibrary.protocol.webdav.definitions import davxml
+
+ICAL = """BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:%d0101T100000
+DURATION:PT1H
+SUMMARY:event 1
+UID:invite-ics
+ORGANIZER:mailto:user02 at example.com
+ATTENDEE:mailto:user02 at example.com
+ATTENDEE:mailto:user01 at example.com
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n")
+
+class InviteTest(HTTPTestBase):
+    """
+    A PUT operation (invite)
+    """
+
+    def doRequest(self):
+        """
+        Execute the actual HTTP request.
+        """
+
+        # Invite as user02
+        now = PyCalendarDateTime.getNowUTC()
+        href = joinURL(self.sessions[1].calendarHref, "organizer.ics")
+        self.sessions[1].writeData(URL(path=href), ICAL % (now.getYear() + 1,), "text/calendar")
+
+    def cleanup(self):
+        """
+        Do some cleanup after the real request.
+        """
+        # Remove created resources
+        href = joinURL(self.sessions[1].calendarHref, "organizer.ics")
+        self.sessions[1].deleteResource(URL(path=href))
+
+        # Remove the attendee event and inbox items
+        props = (davxml.resourcetype,)
+        results = self.sessions[0].getPropertiesOnHierarchy(URL(path=self.sessions[0].calendarHref), props)
+        for href in results.keys():
+            if len(href.split("/")[-1]) > 10:
+                self.sessions[0].deleteResource(URL(path=href))
+        results = self.sessions[0].getPropertiesOnHierarchy(URL(path=self.sessions[0].inboxHref), props)
+        for href in results.keys():
+            if href != self.sessions[0].inboxHref:
+                self.sessions[0].deleteResource(URL(path=href))
+        

Modified: CalendarServer/trunk/contrib/performance/sqlusage/requests/multiget.py
===================================================================
--- CalendarServer/trunk/contrib/performance/sqlusage/requests/multiget.py	2012-08-14 21:42:08 UTC (rev 9707)
+++ CalendarServer/trunk/contrib/performance/sqlusage/requests/multiget.py	2012-08-14 22:17:59 UTC (rev 9708)
@@ -26,15 +26,15 @@
     A multiget operation
     """
 
-    def __init__(self, label, session, href, logFilePath, count):
-        super(MultigetTest, self).__init__(label, session, href, logFilePath)
+    def __init__(self, label, sessions, logFilePath, count):
+        super(MultigetTest, self).__init__(label, sessions, logFilePath)
         self.count = count
     
     def doRequest(self):
         """
         Execute the actual HTTP request.
         """
-        hrefs = [joinURL(self.baseHref, "%d.ics" % (i+1,)) for i in range(self.count)]
+        hrefs = [joinURL(self.sessions[0].calendarHref, "%d.ics" % (i+1,)) for i in range(self.count)]
         props = (
             davxml.getetag,
             caldavxml.calendar_data,
@@ -42,12 +42,12 @@
         )
 
         # Create CalDAV multiget
-        request = Multiget(self.session, self.baseHref, hrefs, props)
+        request = Multiget(self.sessions[0], self.sessions[0].calendarHref, hrefs, props)
         result = ResponseDataString()
         request.setOutput(result)
     
         # Process it
-        self.session.runSession(request)
+        self.sessions[0].runSession(request)
     
         # If its a 207 we want to parse the XML
         if request.getStatusCode() == statuscodes.MultiStatus:

Modified: CalendarServer/trunk/contrib/performance/sqlusage/requests/propfind.py
===================================================================
--- CalendarServer/trunk/contrib/performance/sqlusage/requests/propfind.py	2012-08-14 21:42:08 UTC (rev 9707)
+++ CalendarServer/trunk/contrib/performance/sqlusage/requests/propfind.py	2012-08-14 22:17:59 UTC (rev 9708)
@@ -25,8 +25,8 @@
     A propfind operation
     """
 
-    def __init__(self, label, session, href, logFilePath, depth=1):
-        super(PropfindTest, self).__init__(label, session, href, logFilePath)
+    def __init__(self, label, sessions, logFilePath, depth=1):
+        super(PropfindTest, self).__init__(label, sessions, logFilePath)
         self.depth = headers.Depth1 if depth == 1 else headers.Depth0
     
     def doRequest(self):
@@ -39,12 +39,12 @@
         )
 
         # Create WebDAV propfind
-        request = PropFind(self.session, self.baseHref, self.depth, props)
+        request = PropFind(self.sessions[0], self.sessions[0].calendarHref, self.depth, props)
         result = ResponseDataString()
         request.setOutput(result)
     
         # Process it
-        self.session.runSession(request)
+        self.sessions[0].runSession(request)
     
         # If its a 207 we want to parse the XML
         if request.getStatusCode() == statuscodes.MultiStatus:

Added: CalendarServer/trunk/contrib/performance/sqlusage/requests/put.py
===================================================================
--- CalendarServer/trunk/contrib/performance/sqlusage/requests/put.py	                        (rev 0)
+++ CalendarServer/trunk/contrib/performance/sqlusage/requests/put.py	2012-08-14 22:17:59 UTC (rev 9708)
@@ -0,0 +1,75 @@
+##
+# Copyright (c) 2012 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.
+##
+
+from caldavclientlibrary.protocol.url import URL
+from contrib.performance.sqlusage.requests.httpTests import HTTPTestBase
+from pycalendar.datetime import PyCalendarDateTime
+from twext.web2.dav.util import joinURL
+
+ICAL = """BEGIN:VCALENDAR
+CALSCALE:GREGORIAN
+PRODID:-//Example Inc.//Example Calendar//EN
+VERSION:2.0
+BEGIN:VTIMEZONE
+LAST-MODIFIED:20040110T032845Z
+TZID:US/Eastern
+BEGIN:DAYLIGHT
+DTSTART:20000404T020000
+RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4
+TZNAME:EDT
+TZOFFSETFROM:-0500
+TZOFFSETTO:-0400
+END:DAYLIGHT
+BEGIN:STANDARD
+DTSTART:20001026T020000
+RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
+TZNAME:EST
+TZOFFSETFROM:-0400
+TZOFFSETTO:-0500
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+DTSTAMP:20051222T205953Z
+CREATED:20060101T150000Z
+DTSTART;TZID=US/Eastern:%d0101T100000
+DURATION:PT1H
+SUMMARY:event 1
+UID:put-ics
+END:VEVENT
+END:VCALENDAR
+""".replace("\n", "\r\n")
+
+class PutTest(HTTPTestBase):
+    """
+    A PUT operation (non-invite)
+    """
+
+    def doRequest(self):
+        """
+        Execute the actual HTTP request.
+        """
+
+        now = PyCalendarDateTime.getNowUTC()
+        href = joinURL(self.sessions[0].calendarHref, "put.ics")
+        self.sessions[0].writeData(URL(path=href), ICAL % (now.getYear() + 1,), "text/calendar")
+
+    def cleanup(self):
+        """
+        Do some cleanup after the real request.
+        """
+        # Remove created resources
+        href = joinURL(self.sessions[0].calendarHref, "put.ics")
+        self.sessions[0].deleteResource(URL(path=href))

Modified: CalendarServer/trunk/contrib/performance/sqlusage/requests/query.py
===================================================================
--- CalendarServer/trunk/contrib/performance/sqlusage/requests/query.py	2012-08-14 21:42:08 UTC (rev 9707)
+++ CalendarServer/trunk/contrib/performance/sqlusage/requests/query.py	2012-08-14 22:17:59 UTC (rev 9708)
@@ -60,8 +60,8 @@
     A sync operation
     """
 
-    def __init__(self, label, session, href, logFilePath, count):
-        super(QueryTest, self).__init__(label, session, href, logFilePath)
+    def __init__(self, label, sessions, logFilePath, count):
+        super(QueryTest, self).__init__(label, sessions, logFilePath)
         self.count = count
     
     def prepare(self):
@@ -74,8 +74,8 @@
         self.end = self.start.duplicate()
         self.end.offsetHours(1)
         for i in range(self.count):
-            href = joinURL(self.baseHref, "tr-query-%d.ics" % (i+1,))
-            self.session.writeData(URL(path=href), ICAL % (self.start.getText(), i+1,), "text/calendar")
+            href = joinURL(self.sessions[0].calendarHref, "tr-query-%d.ics" % (i+1,))
+            self.sessions[0].writeData(URL(path=href), ICAL % (self.start.getText(), i+1,), "text/calendar")
 
     def doRequest(self):
         """
@@ -87,12 +87,12 @@
         )
 
         # Create CalDAV query
-        request = QueryVEVENTTimeRange(self.session, self.baseHref, self.start.getText(), self.end.getText(), props)
+        request = QueryVEVENTTimeRange(self.sessions[0], self.sessions[0].calendarHref, self.start.getText(), self.end.getText(), props)
         result = ResponseDataString()
         request.setOutput(result)
     
         # Process it
-        self.session.runSession(request)
+        self.sessions[0].runSession(request)
     
         # If its a 207 we want to parse the XML
         if request.getStatusCode() == statuscodes.MultiStatus:
@@ -106,5 +106,5 @@
         """
         # Remove created resources
         for i in range(self.count):
-            href = joinURL(self.baseHref, "tr-query-%d.ics" % (i+1,))
-            self.session.deleteResource(URL(path=href))
+            href = joinURL(self.sessions[0].calendarHref, "tr-query-%d.ics" % (i+1,))
+            self.sessions[0].deleteResource(URL(path=href))

Modified: CalendarServer/trunk/contrib/performance/sqlusage/requests/sync.py
===================================================================
--- CalendarServer/trunk/contrib/performance/sqlusage/requests/sync.py	2012-08-14 21:42:08 UTC (rev 9707)
+++ CalendarServer/trunk/contrib/performance/sqlusage/requests/sync.py	2012-08-14 22:17:59 UTC (rev 9708)
@@ -58,8 +58,8 @@
     A sync operation
     """
 
-    def __init__(self, label, session, href, logFilePath, full, count):
-        super(SyncTest, self).__init__(label, session, href, logFilePath)
+    def __init__(self, label, sessions, logFilePath, full, count):
+        super(SyncTest, self).__init__(label, sessions, logFilePath)
         self.full = full
         self.count = count
         self.synctoken = ""
@@ -70,14 +70,14 @@
         """
         if not self.full:
             # Get current sync token
-            results, _ignore_bad = self.session.getProperties(URL(path=self.baseHref), (davxml.sync_token,))
+            results, _ignore_bad = self.sessions[0].getProperties(URL(path=self.sessions[0].calendarHref), (davxml.sync_token,))
             self.synctoken = results[davxml.sync_token]
             
             # Add resources to create required number of changes
             now = PyCalendarDateTime.getNowUTC()
             for i in range(self.count):
-                href = joinURL(self.baseHref, "sync-collection-%d.ics" % (i+1,))
-                self.session.writeData(URL(path=href), ICAL % (now.getYear() + 1, i+1,), "text/calendar")
+                href = joinURL(self.sessions[0].calendarHref, "sync-collection-%d.ics" % (i+1,))
+                self.sessions[0].writeData(URL(path=href), ICAL % (now.getYear() + 1, i+1,), "text/calendar")
 
     def doRequest(self):
         """
@@ -89,7 +89,7 @@
         )
 
         # Run sync collection
-        self.session.syncCollection(URL(path=self.baseHref), self.synctoken, props)
+        self.sessions[0].syncCollection(URL(path=self.sessions[0].calendarHref), self.synctoken, props)
 
     def cleanup(self):
         """
@@ -98,5 +98,5 @@
         if not self.full:
             # Remove created resources
             for i in range(self.count):
-                href = joinURL(self.baseHref, "sync-collection-%d.ics" % (i+1,))
-                self.session.deleteResource(URL(path=href))
+                href = joinURL(self.sessions[0].calendarHref, "sync-collection-%d.ics" % (i+1,))
+                self.sessions[0].deleteResource(URL(path=href))

Modified: CalendarServer/trunk/contrib/performance/sqlusage/sqlusage.py
===================================================================
--- CalendarServer/trunk/contrib/performance/sqlusage/sqlusage.py	2012-08-14 21:42:08 UTC (rev 9707)
+++ CalendarServer/trunk/contrib/performance/sqlusage/sqlusage.py	2012-08-14 22:17:59 UTC (rev 9708)
@@ -19,13 +19,16 @@
 from caldavclientlibrary.protocol.url import URL
 from caldavclientlibrary.protocol.webdav.definitions import davxml
 from calendarserver.tools import tables
+from contrib.performance.sqlusage.requests.invite import InviteTest
 from contrib.performance.sqlusage.requests.multiget import MultigetTest
 from contrib.performance.sqlusage.requests.propfind import PropfindTest
+from contrib.performance.sqlusage.requests.put import PutTest
 from contrib.performance.sqlusage.requests.query import QueryTest
 from contrib.performance.sqlusage.requests.sync import SyncTest
 from pycalendar.datetime import PyCalendarDateTime
 from twext.web2.dav.util import joinURL
 import getopt
+import itertools
 import sys
 
 """
@@ -37,7 +40,7 @@
 with calendar size can be plotted. 
 """
 
-EVENT_COUNTS = (0, 1, 5, 10, 25, 50, 75, 100, 200, 300, 400, 500, 1000, 2000, 3000, 4000, 5000)
+EVENT_COUNTS = (0, 1, 5, 10, 50, 100, 500, 1000, 5000)
 
 ICAL = """BEGIN:VCALENDAR
 CALSCALE:GREGORIAN
@@ -72,48 +75,63 @@
 END:VCALENDAR
 """.replace("\n", "\r\n")
 
+class SQLUsageSession(CalDAVSession):
+    
+    def __init__(self, server, port=None, ssl=False, user="", pswd="", principal=None, root=None, logging=False):
+
+        super(SQLUsageSession, self).__init__(server, port, ssl, user, pswd, principal, root, logging)
+        self.homeHref = "/calendars/users/%s/" % (self.user,)
+        self.calendarHref = "/calendars/users/%s/calendar/" % (self.user,)
+        self.inboxHref = "/calendars/users/%s/inbox/" % (self.user,)
+        
+
 class SQLUsage(object):
     
-    def __init__(self, server, port, user, pswd, logFilePath):
+    def __init__(self, server, port, users, pswds, logFilePath):
         self.server = server
         self.port = port
-        self.user = user
-        self.pswd = pswd
+        self.users = users
+        self.pswds = pswds
         self.logFilePath = logFilePath
         self.requestLabels = []
         self.results = {}
         self.currentCount = 0
-        
-        self.userhref = "/calendars/users/%s/" % (self.user,)
 
-    def runLoop(self):
+    def runLoop(self, counts):
         
-        # Make the session
-        session = CalDAVSession(self.server, self.port, user=self.user, pswd=self.pswd, root="/")
+        # Make the sessions
+        sessions = [
+            SQLUsageSession(self.server, self.port, user=user, pswd=pswd, root="/")
+            for user, pswd in itertools.izip(self.users, self.pswds)
+        ]
 
         # Set of requests to execute
         requests = [
-            MultigetTest("multiget-1", session, joinURL(self.userhref, "calendar/"), self.logFilePath, 1),
-            MultigetTest("multiget-50", session, joinURL(self.userhref, "calendar/"), self.logFilePath, 50),
-            PropfindTest("propfind-cal", session, joinURL(self.userhref, "calendar/"), self.logFilePath, 1),
-            SyncTest("sync-full", session, joinURL(self.userhref, "calendar/"), self.logFilePath, True, 0),
-            SyncTest("sync-1", session, joinURL(self.userhref, "calendar/"), self.logFilePath, False, 1),
-            QueryTest("query-1", session, joinURL(self.userhref, "calendar/"), self.logFilePath, 1),
-            QueryTest("query-10", session, joinURL(self.userhref, "calendar/"), self.logFilePath, 10),
+            MultigetTest("multiget-1", sessions, self.logFilePath, 1),
+            MultigetTest("multiget-50", sessions, self.logFilePath, 50),
+            PropfindTest("propfind-cal", sessions, self.logFilePath, 1),
+            SyncTest("sync-full", sessions, self.logFilePath, True, 0),
+            SyncTest("sync-1", sessions, self.logFilePath, False, 1),
+            QueryTest("query-1", sessions, self.logFilePath, 1),
+            QueryTest("query-10", sessions, self.logFilePath, 10),
+            PutTest("put", sessions, self.logFilePath),
+            InviteTest("invite", sessions, self.logFilePath),
         ]
         self.requestLabels = [request.label for request in requests]
 
         # Warm-up server by doing calendar home and calendar propfinds
         props = (davxml.resourcetype,)
-        session.getPropertiesOnHierarchy(URL(path=self.userhref), props)
-        session.getPropertiesOnHierarchy(URL(path=joinURL(self.userhref, "calendar/")), props)
+        for session in sessions:
+            session.getPropertiesOnHierarchy(URL(path=session.homeHref), props)
+            session.getPropertiesOnHierarchy(URL(path=session.calendarHref), props)
         
         # Now loop over sets of events
-        for count in EVENT_COUNTS:
+        for count in counts:
             print "Testing count = %d" % (count,)
-            self.ensureEvents(session, count)
+            self.ensureEvents(sessions[0], sessions[0].calendarHref, count)
             result = {}
             for request in requests:
+                print "  Test = %s" % (request.label,)
                 result[request.label] = request.execute()
             self.results[count] = result
     
@@ -121,26 +139,26 @@
         
         self._printReport("SQL Statement Count", "count", "%d")
         self._printReport("SQL Rows Returned", "rows", "%d")
-        self._printReport("SQL Time", "timing", "%.3f")
+        self._printReport("SQL Time", "timing", "%.1f")
             
     def _printReport(self, title, attr, colFormat):
         table = tables.Table()
         
         print title
-        headers = ["Events"] + sorted([label for label in self.requestLabels])
+        headers = ["Events"] + self.requestLabels
         table.addHeader(headers)
         formats = [tables.Table.ColumnFormat("%d", tables.Table.ColumnFormat.RIGHT_JUSTIFY)] + \
             [tables.Table.ColumnFormat(colFormat, tables.Table.ColumnFormat.RIGHT_JUSTIFY)] * len(self.requestLabels)
         table.setDefaultColumnFormats(formats)
         for k in sorted(self.results.keys()):
-            row = [k] + [getattr(self.results[k][item], attr) for item in sorted(self.results[k].keys())]
+            row = [k] + [getattr(self.results[k][item], attr) for item in self.requestLabels]
             table.addRow(row)
         os = StringIO()
         table.printTable(os=os)
         print os.getvalue()
         print
             
-    def ensureEvents(self, session, n):
+    def ensureEvents(self, session, calendarhref, n):
         """
         Make sure the required number of events are present in the calendar.
     
@@ -150,7 +168,7 @@
         now = PyCalendarDateTime.getNowUTC()
         for i in range(n - self.currentCount):
             index = self.currentCount + i + 1
-            href = joinURL(self.userhref, "calendar", "%d.ics" % (index,))
+            href = joinURL(calendarhref, "%d.ics" % (index,))
             session.writeData(URL(path=href), ICAL % (now.getYear() + 1, index,), "text/calendar")
             
         self.currentCount = n
@@ -166,6 +184,7 @@
     --port         Server port
     --user         User name
     --pswd         Password
+    --counts       Comma-separated list of event counts to test
 
 Arguments:
     FILE           File name for sqlstats.log to analyze.
@@ -183,11 +202,12 @@
     
     server = "localhost"
     port = 8008
-    user = "user01"
-    pswd = "user01"
+    users = ("user01", "user02",)
+    pswds = ("user01", "user02",)
     file = "sqlstats.logs"
+    counts = EVENT_COUNTS
 
-    options, args = getopt.getopt(sys.argv[1:], "h", ["server", "port", "user", "pswd",])
+    options, args = getopt.getopt(sys.argv[1:], "h", ["server=", "port=", "user=", "pswd=", "counts=",])
 
     for option, value in options:
         if option == "-h":
@@ -197,9 +217,11 @@
         elif option == "--port":
             port = int(value)
         elif option == "--user":
-            user = value
+            users = value.split(",")
         elif option == "--pswd":
-            pswd = value
+            pswds = value.split(",")
+        elif option == "--counts":
+            counts = [int(i) for i in value.split(",")]
         else:
             usage("Unrecognized option: %s" % (option,))
 
@@ -209,6 +231,6 @@
     elif len(args) != 0:
         usage("Must zero or one file arguments")
 
-    sql = SQLUsage(server, port, user, pswd, file)
-    sql.runLoop()
+    sql = SQLUsage(server, port, users, pswds, file)
+    sql.runLoop(counts)
     sql.report()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120814/4f48d331/attachment-0001.html>


More information about the calendarserver-changes mailing list