[CalendarServer-changes] [6647] CalDAVTester/trunk

source_changes at macosforge.org source_changes at macosforge.org
Wed Nov 17 12:45:14 PST 2010


Revision: 6647
          http://trac.macosforge.org/projects/calendarserver/changeset/6647
Author:   cdaboo at apple.com
Date:     2010-11-17 12:45:11 -0800 (Wed, 17 Nov 2010)
Log Message:
-----------
Add ability to generate (fuzz) an iCalendar object being written to the server to allow populating a server
with a bunch of events. Removed use of __slots__ in source.

Modified Paths:
--------------
    CalDAVTester/trunk/README.txt
    CalDAVTester/trunk/scripts/tests/CalDAV/caldavtest.dtd
    CalDAVTester/trunk/src/caldavtest.py
    CalDAVTester/trunk/src/monitorinfo.py
    CalDAVTester/trunk/src/perfinfo.py
    CalDAVTester/trunk/src/request.py
    CalDAVTester/trunk/src/test.py
    CalDAVTester/trunk/src/xmlDefs.py
    CalDAVTester/trunk/utilities/webdav.py

Modified: CalDAVTester/trunk/README.txt
===================================================================
--- CalDAVTester/trunk/README.txt	2010-11-17 19:25:39 UTC (rev 6646)
+++ CalDAVTester/trunk/README.txt	2010-11-17 20:45:11 UTC (rev 6647)
@@ -22,7 +22,7 @@
 	data. Server data population only occurs when this option is
 	present.
 
-	-d : in conjuntion with -p, if present specifies that the populated
+	-d : in conjunction with -p, if present specifies that the populated
 	data be removed after all tests have completed.
 
 	--all : execute all tests found in the working directory. Each .xml
@@ -181,10 +181,13 @@
 			2) DELAY - pause for the number of seconds specified by the <ruri> element.
 			3) GETNEW - get the data from the newest resource in the collection specified by the <ruri> element and put its URI
 					    into the $ variable for later use in an <ruri> element.
-			3) WAITCOUNT - wait until at least a certain numner of resources appear in a collection.
+			3) WAITCOUNT - wait until at least a certain number of resources appear in a collection.
 
 	ELEMENT <ruri>
 		the URI of the request. Multiple <ruri>'s are allowed with DELETEALL only.
+		The characters "**" may be used to cause a random uuid to be inserted where
+		those two characters appear. The characters "##" may be used to insert the
+		current test count iteration where those two characters occur.
 
 	ELEMENT <header>
 		can be used to specify additional headers in the request.
@@ -204,6 +207,10 @@
 			substitutions will be performed on the data before it is sent
 			in the request.
 
+		ATTRIBUTE generate
+			if set to 'yes' then a basic calendar data "fuzzing" is done to
+			the source data to make it unique and up to date.
+
 		ELEMENT <content-type>
 			the MIME content type for the request body.
 

Modified: CalDAVTester/trunk/scripts/tests/CalDAV/caldavtest.dtd
===================================================================
--- CalDAVTester/trunk/scripts/tests/CalDAV/caldavtest.dtd	2010-11-17 19:25:39 UTC (rev 6646)
+++ CalDAVTester/trunk/scripts/tests/CalDAV/caldavtest.dtd	2010-11-17 20:45:11 UTC (rev 6647)
@@ -40,7 +40,8 @@
 			<!ELEMENT name (#PCDATA)>
 			<!ELEMENT value (#PCDATA)>
 		<!ELEMENT data (content-type, filepath)>
-			<!ATTLIST data substitutions (yes|no) "yes">
+			<!ATTLIST data substitutions (yes|no) "yes"
+			               generate      (yes|no) "no">
 			<!ELEMENT content-type (#PCDATA)>
 			<!ELEMENT filepath (#PCDATA)>
 

Modified: CalDAVTester/trunk/src/caldavtest.py
===================================================================
--- CalDAVTester/trunk/src/caldavtest.py	2010-11-17 19:25:39 UTC (rev 6646)
+++ CalDAVTester/trunk/src/caldavtest.py	2010-11-17 20:45:11 UTC (rev 6647)
@@ -149,7 +149,7 @@
                 reqstats = None
             for ctr in range(test.count): #@UnusedVariable
                 for req in test.requests:
-                    result, resulttxt, _ignore_response, _ignore_respdata = self.dorequest( req, test.details, True, False, reqstats, etags = etags, label=label )
+                    result, resulttxt, _ignore_response, _ignore_respdata = self.dorequest( req, test.details, True, False, reqstats, etags = etags, label=label, count=ctr+1 )
                     if not result:
                         break
             loglevel = [manager.LOG_ERROR, manager.LOG_HIGH][result]
@@ -162,14 +162,14 @@
             self.postgresResult(postgresCount, indent=8)
             return ["f", "t"][result]
     
-    def dorequests( self, description, list, doverify = True, forceverify = False, label = "" ):
+    def dorequests( self, description, list, doverify = True, forceverify = False, label = "", count = 1 ):
         if len(list) == 0:
             return True
         description += " " * max(1, STATUSTXT_WIDTH - len(description))
         self.manager.log(manager.LOG_HIGH, description, before=1, after=0)
         ctr = 1
         for req in list:
-            result, resulttxt, _ignore_response, _ignore_respdata = self.dorequest( req, False, doverify, forceverify, label=label )
+            result, resulttxt, _ignore_response, _ignore_respdata = self.dorequest( req, False, doverify, forceverify, label=label, count=count )
             if not result:
                 resulttxt += "\nFailure during multiple requests #%d out of %d, request=%s" % (ctr, len(list), str(req))
                 break
@@ -387,8 +387,10 @@
             self.dorequest( req, False, False, label=label )
         self.manager.log(manager.LOG_HIGH, "[DONE]")
     
-    def dorequest( self, req, details=False, doverify = True, forceverify = False, stats = None, etags = None, label = "" ):
+    def dorequest( self, req, details=False, doverify = True, forceverify = False, stats = None, etags = None, label = "", count = 1 ):
         
+        req.count = count
+
         if isinstance(req, pause):
             # Useful for pausing at a particular point
             print "Paused"

Modified: CalDAVTester/trunk/src/monitorinfo.py
===================================================================
--- CalDAVTester/trunk/src/monitorinfo.py	2010-11-17 19:25:39 UTC (rev 6646)
+++ CalDAVTester/trunk/src/monitorinfo.py	2010-11-17 20:45:11 UTC (rev 6647)
@@ -28,25 +28,6 @@
     """
     Maintains information about the monitoring test scenario.
     """
-    __slots__  = [
-        'name',
-        'logging',
-        'period',
-        'timeout',
-        'serverinfo',
-        'startscript',
-        'testinfo',
-        'endscript',
-        'warningtime',
-        'notify',
-        'notify_from',
-        'notify_time_exceeded',
-        'notify_request_failed',
-        'notify_interval',
-        'notify_subject',
-        'notify_body',
-    ]
-
     def __init__( self ):
         self.name = ""
         self.logging = False

Modified: CalDAVTester/trunk/src/perfinfo.py
===================================================================
--- CalDAVTester/trunk/src/perfinfo.py	2010-11-17 19:25:39 UTC (rev 6646)
+++ CalDAVTester/trunk/src/perfinfo.py	2010-11-17 20:45:11 UTC (rev 6647)
@@ -33,8 +33,6 @@
     """
     Maintains information about the performance test scenario.
     """
-    __slots__  = ['clients', 'threads', 'logging', 'tests', 'serverinfo', 'startscript', 'testinfo', 'endscript', 'subsdict']
-
     def __init__( self ):
         self.clients = 20
         self.threads = True

Modified: CalDAVTester/trunk/src/request.py
===================================================================
--- CalDAVTester/trunk/src/request.py	2010-11-17 19:25:39 UTC (rev 6646)
+++ CalDAVTester/trunk/src/request.py	2010-11-17 20:45:11 UTC (rev 6647)
@@ -21,9 +21,12 @@
 from hashlib import md5, sha1
 from src.xmlUtils import getYesNoAttributeValue
 import base64
+import datetime
 import httplib
+import re
 import src.xmlDefs
 import time
+import uuid
 
 algorithms = {
     'md5': md5,
@@ -129,9 +132,6 @@
     Represents the HTTP request to be executed, and verifcation information to
     be used to determine a satisfactory output or not.
     """
-    __slots__  = ['manager', 'auth', 'user', 'pswd', 'end_delete', 'print_response',
-                  'method', 'headers', 'ruris', 'ruri', 'data', 'datasubs', 'verifiers',
-                  'grabheader', 'grabproperty', 'grabelement', 'require_features']
     
     def __init__( self, manager ):
         self.manager = manager
@@ -146,7 +146,7 @@
         self.ruris = []
         self.ruri = ""
         self.data = None
-        self.datasubs = True
+        self.count = 1
         self.verifiers = []
         self.grabheader = []
         self.grabproperty = []
@@ -159,7 +159,12 @@
         return self.require_features - self.manager.server_info.features
 
     def getURI( self, si ):
-        return si.extrasubs(self.ruri)
+        uri = si.extrasubs(self.ruri)
+        if "**" in uri:
+            uri = uri.replace("**", str(uuid.uuid4()))
+        elif "##" in uri:
+            uri = uri.replace("##", str(self.count))
+        return uri
         
     def getHeaders( self, si ):
         hdrs = self.headers
@@ -266,11 +271,31 @@
                     data = fd.read()
                 finally:
                     fd.close()
-            if self.datasubs:
+            if self.data.substitute:
                 data = str(self.manager.server_info.subs(data))
                 data = self.manager.server_info.extrasubs(data)
+            if self.data.generate:
+                if self.data.content_type.startswith("text/calendar"):
+                    data = self.generateCalendarData(data)
         return data
     
+    def generateCalendarData( self, data ):
+        """
+        FIXME: does not work for events with recurrence overrides.
+        """
+        
+        # Change the following iCalendar data values:
+        # DTSTART, DTEND, RECURRENCE-ID, UID
+        
+        data = re.sub("UID:.*", "UID:%s" % (uuid.uuid4(),), data)
+        data = re.sub("SUMMARY:(.*)", "SUMMARY:\\1 #%s" % (self.count,), data)
+        
+        now = datetime.date.today()
+        data = re.sub("(DTSTART;[^:]*):[0-9]{8,8}", "\\1:%04d%02d%02d" % (now.year, now.month, now.day,), data)
+        data = re.sub("(DTEND;[^:]*):[0-9]{8,8}", "\\1:%04d%02d%02d" % (now.year, now.month, now.day,), data)
+
+        return data
+
     def parseXML( self, node ):
         self.auth = node.get(src.xmlDefs.ATTR_AUTH, src.xmlDefs.ATTR_VALUE_YES) == src.xmlDefs.ATTR_VALUE_YES
         self.user = self.manager.server_info.subs(node.get(src.xmlDefs.ATTR_USER, "").encode("utf-8"))
@@ -291,7 +316,7 @@
                     self.ruri = self.ruris[0]
             elif child.tag == src.xmlDefs.ELEMENT_DATA:
                 self.data = data()
-                self.datasubs = self.data.parseXML( child )
+                self.data.parseXML( child )
             elif child.tag == src.xmlDefs.ELEMENT_VERIFY:
                 self.verifiers.append(verify(self.manager))
                 self.verifiers[-1].parseXML( child )
@@ -350,16 +375,18 @@
     """
     Represents the data/body portion of an HTTP request.
     """
-    __slots__  = ['content_type', 'filepath', 'value']
-    
+
     def __init__( self ):
         self.content_type = ""
         self.filepath = ""
         self.value = ""
+        self.substitute = False
+        self.generate = False
     
     def parseXML( self, node ):
 
-        subs = node.get(src.xmlDefs.ATTR_SUBSTITUTIONS, src.xmlDefs.ATTR_VALUE_YES) == src.xmlDefs.ATTR_VALUE_YES
+        self.substitute = node.get(src.xmlDefs.ATTR_SUBSTITUTIONS, src.xmlDefs.ATTR_VALUE_YES) == src.xmlDefs.ATTR_VALUE_YES
+        self.generate = node.get(src.xmlDefs.ATTR_GENERATE, src.xmlDefs.ATTR_VALUE_NO) == src.xmlDefs.ATTR_VALUE_YES
 
         for child in node.getchildren():
             if child.tag == src.xmlDefs.ELEMENT_CONTENTTYPE:
@@ -367,8 +394,6 @@
             elif child.tag == src.xmlDefs.ELEMENT_FILEPATH:
                 self.filepath = child.text.encode("utf-8")
 
-        return subs
-
 class verify( object ):
     """
     Defines how the result of a request should be verified. This is done
@@ -376,7 +401,6 @@
     specified in the test XML config file. The callback name is in the XML config
     file also and is dynamically loaded to do the verification.
     """
-    __slots__  = ['manager', 'callback', 'args']
     
     def __init__( self, manager ):
         self.manager = manager
@@ -428,7 +452,6 @@
     """
     Maintains stats about the current test.
     """
-    __slots__ = ['count', 'totaltime', 'currenttime']
     
     def __init__(self):
         self.count = 0

Modified: CalDAVTester/trunk/src/test.py
===================================================================
--- CalDAVTester/trunk/src/test.py	2010-11-17 19:25:39 UTC (rev 6646)
+++ CalDAVTester/trunk/src/test.py	2010-11-17 20:45:11 UTC (rev 6647)
@@ -28,7 +28,6 @@
     be run more than once, and timing information gathered and averaged across
     all runs.
     """
-    __slots__  = ['manager', 'name', 'details', 'count', 'stats', 'ignore', 'require_features', 'description', 'requests']
     
     def __init__( self, manager ):
         self.manager = manager

Modified: CalDAVTester/trunk/src/xmlDefs.py
===================================================================
--- CalDAVTester/trunk/src/xmlDefs.py	2010-11-17 19:25:39 UTC (rev 6646)
+++ CalDAVTester/trunk/src/xmlDefs.py	2010-11-17 20:45:11 UTC (rev 6647)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006-2009 Apple Inc. All rights reserved.
+# Copyright (c) 2006-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.
@@ -75,6 +75,7 @@
 ATTR_DETAILS = "details"
 ATTR_ENABLE = "enable"
 ATTR_END_DELETE = "end-delete"
+ATTR_GENERATE = "generate"
 ATTR_IGNORE = "ignore"
 ATTR_IGNORE_ALL = "ignore-all"
 ATTR_INTERVAL = "interval"

Modified: CalDAVTester/trunk/utilities/webdav.py
===================================================================
--- CalDAVTester/trunk/utilities/webdav.py	2010-11-17 19:25:39 UTC (rev 6646)
+++ CalDAVTester/trunk/utilities/webdav.py	2010-11-17 20:45:11 UTC (rev 6647)
@@ -1,5 +1,5 @@
 ##
-# Copyright (c) 2006-2007 Apple Inc. All rights reserved.
+# Copyright (c) 2006-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.
@@ -28,8 +28,6 @@
     Class that encapsulates the details of a request.
     """
 
-    __slots__ = ['host', 'port', 'method', 'uri', 'user', 'pswd', 'headers', 'body']
-    
     def __init__(self, **kwargs):
         self.host = kwargs.get("host", "")
         self.port = kwargs.get("port", 80)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20101117/c5ce4e14/attachment-0001.html>


More information about the calendarserver-changes mailing list