[CalendarServer-changes] [1324] CalDAVTester/trunk

source_changes at macosforge.org source_changes at macosforge.org
Tue Mar 6 09:25:56 PST 2007


Revision: 1324
          http://trac.macosforge.org/projects/calendarserver/changeset/1324
Author:   cdaboo at apple.com
Date:     2007-03-06 09:25:55 -0800 (Tue, 06 Mar 2007)

Log Message:
-----------
Allow a proeprty value to be "grabbed" from a response and stored in a special subtitution variable that can be later used
in a verifier for comparison with a subsequent proeprty value. Add an option to the propfindItems verify so that it can
check for the existence of a property whose value does not match a specified value.

Together these changes allow us to verify that a specific property value changes as the result of some operation,
i.e. we can verify that getetag changes when a resource is changed.

Modified Paths:
--------------
    CalDAVTester/trunk/src/__init__.py
    CalDAVTester/trunk/src/account.py
    CalDAVTester/trunk/src/caldavtest.py
    CalDAVTester/trunk/src/populate.py
    CalDAVTester/trunk/src/request.py
    CalDAVTester/trunk/src/serverinfo.py
    CalDAVTester/trunk/src/xmlDefs.py
    CalDAVTester/trunk/utilities/__init__.py
    CalDAVTester/trunk/verifiers/__init__.py
    CalDAVTester/trunk/verifiers/aclItems.py
    CalDAVTester/trunk/verifiers/multistatusItems.py
    CalDAVTester/trunk/verifiers/propfindItems.py

Added Paths:
-----------
    CalDAVTester/trunk/utilities/
    CalDAVTester/trunk/utilities/xmlutils.py

Removed Paths:
-------------
    CalDAVTester/trunk/utils/

Modified: CalDAVTester/trunk/src/__init__.py
===================================================================
--- CalDAVTester/trunk/src/__init__.py	2007-03-06 01:37:34 UTC (rev 1323)
+++ CalDAVTester/trunk/src/__init__.py	2007-03-06 17:25:55 UTC (rev 1324)
@@ -15,3 +15,18 @@
 #
 # DRI: Cyrus Daboo, cdaboo at apple.com
 ##
+
+__all__ = [
+    "account",
+    "caldavtest",
+    "manager",
+    "monitorinfo",
+    "multithread",
+    "perfinfo",
+    "populate",
+    "request",
+    "serverinfo",
+    "test",
+    "testsuite",
+    "xmlDefs",
+]

Modified: CalDAVTester/trunk/src/account.py
===================================================================
--- CalDAVTester/trunk/src/account.py	2007-03-06 01:37:34 UTC (rev 1323)
+++ CalDAVTester/trunk/src/account.py	2007-03-06 17:25:55 UTC (rev 1324)
@@ -20,8 +20,7 @@
 Class that encapsulates the account information for populating a CalDAV server.
 """
 
-
-from utils import webdav
+from utilities import webdav
 import copy
 import md5
 import os

Modified: CalDAVTester/trunk/src/caldavtest.py
===================================================================
--- CalDAVTester/trunk/src/caldavtest.py	2007-03-06 01:37:34 UTC (rev 1323)
+++ CalDAVTester/trunk/src/caldavtest.py	2007-03-06 17:25:55 UTC (rev 1324)
@@ -25,8 +25,12 @@
 from src.request import request
 from src.request import stats
 from src.testsuite import testsuite
+from utilities.xmlutils import ElementsByName
+
 from xml.dom.minicompat import NodeList
+from xml.dom.minidom import Element
 from xml.dom.minidom import Node
+
 import httplib
 import os
 import rfc822
@@ -453,6 +457,16 @@
             if hdrs:
                 self.grabbedlocation = hdrs[0]
 
+        if req.grabproperty:
+            if response.status == 207:
+                # grab the property here
+                propvalue = self.extractProperty(req.grabproperty[0], respdata)
+                if propvalue == None:
+                    result = False
+                    resulttxt += "\nProperty %s was not extracted from multistatus response\n" % (req.grabproperty[0],)
+                else:
+                    self.manager.server_info.addextrasubs({req.grabproperty[1]: propvalue})
+
         return result, resulttxt, response, respdata
 
     def verifyrequest( self, req, uri, response, respdata ):
@@ -498,3 +512,50 @@
             elif child._get_localName() == src.xmlDefs.ELEMENT_END:
                 self.end_requests = request.parseList( self.manager, child )
     
+    def extractProperty(self, propertyname, respdata):
+
+        try:
+            doc = xml.dom.minidom.parseString( respdata )
+        except:
+            return None
+                
+        for response in doc.getElementsByTagNameNS( "DAV:", "response" ):
+            # Get all property status
+            propstatus = ElementsByName(response, "DAV:", "propstat")
+            for props in propstatus:
+                # Determine status for this propstat
+                status = ElementsByName(props, "DAV:", "status")
+                if len(status) == 1:
+                    statustxt = status[0].firstChild.data
+                    status = False
+                    if statustxt.startswith("HTTP/1.1 ") and (len(statustxt) >= 10):
+                        status = (statustxt[9] == "2")
+                else:
+                    status = False
+                
+                if not status:
+                    continue
+
+                # Get properties for this propstat
+                prop = ElementsByName(props, "DAV:", "prop")
+                if len(prop) != 1:
+                    return False, "           Wrong number of DAV:prop elements\n"
+
+                for child in prop[0]._get_childNodes():
+                    if isinstance(child, Element):
+                        qname = (child.namespaceURI, child.localName)
+                        fqname = qname[0] + qname[1]
+                        if child.firstChild is not None:
+                            # Copy sub-element data as text into one long string and strip leading/trailing space
+                            value = ""
+                            for p in child._get_childNodes():
+                                temp = p.toprettyxml("", "")
+                                temp = temp.strip()
+                                value += temp
+                        else:
+                            value = ""
+                        
+                        if fqname == propertyname:
+                            return value
+
+        return None
\ No newline at end of file

Modified: CalDAVTester/trunk/src/populate.py
===================================================================
--- CalDAVTester/trunk/src/populate.py	2007-03-06 01:37:34 UTC (rev 1323)
+++ CalDAVTester/trunk/src/populate.py	2007-03-06 17:25:55 UTC (rev 1324)
@@ -21,7 +21,7 @@
 """
 
 from src.account import account
-from utils import webdav
+from utilities import webdav
 import src.xmlDefs
 
 class populate( object ):

Modified: CalDAVTester/trunk/src/request.py
===================================================================
--- CalDAVTester/trunk/src/request.py	2007-03-06 01:37:34 UTC (rev 1323)
+++ CalDAVTester/trunk/src/request.py	2007-03-06 17:25:55 UTC (rev 1324)
@@ -30,7 +30,8 @@
     be used to determine a satisfactory output or not.
     """
     __slots__  = ['manager', 'auth', 'user', 'pswd', 'end_delete', 'print_response',
-                  'method', 'headers', 'ruri', 'data', 'datasubs', 'verifiers', 'grablocation']
+                  'method', 'headers', 'ruri', 'data', 'datasubs', 'verifiers',
+                  'grablocation', 'grabproperty']
     
     def __init__( self, manager ):
         self.manager = manager
@@ -46,6 +47,7 @@
         self.datasubs = True
         self.verifiers = []
         self.grablocation = False
+        self.grabproperty = None
     
     def __str__(self):
         return "Method: %s; uri: %s" % (self.method, self.ruri)
@@ -125,6 +127,8 @@
                 self.verifiers[-1].parseXML( child )
             elif child._get_localName() == src.xmlDefs.ELEMENT_GRABLOCATION:
                 self.grablocation = True
+            elif child._get_localName() == src.xmlDefs.ELEMENT_GRABPROPERTY:
+                self.parseGrabProperty(child)
 
     def parseHeader(self, node):
         
@@ -150,6 +154,19 @@
                 
     parseList = staticmethod( parseList )
 
+    def parseGrabProperty(self, node):
+        
+        property = None
+        variable = None
+        for child in node._get_childNodes():
+           if child._get_localName() == src.xmlDefs.ELEMENT_PROPERTY:
+                property = child.firstChild.data
+           elif child._get_localName() == src.xmlDefs.ELEMENT_VARIABLE:
+                variable = self.manager.server_info.subs(child.firstChild.data)
+        
+        if (property is not None) and (variable is not None):
+            self.grabproperty = (property, variable)
+            
 class data( object ):
     """
     Represents the data/body portion of an HTTP request.
@@ -188,6 +205,13 @@
         self.args = {}
     
     def doVerify(self, uri, response, respdata):
+        
+        # Re-do substitutions from values generated during the current test run
+        if self.manager.server_info.hasextrasubs():
+            for name, values in self.args.iteritems():
+                newvalues = [self.manager.server_info.extrasubs(value) for value in values]
+                self.args[name] = newvalues
+                
         verifierClass = self._importName("verifiers." + self.callback, "Verifier")
         verifier = verifierClass()
         return verifier.verify(self.manager, uri, response, respdata, self.args)

Modified: CalDAVTester/trunk/src/serverinfo.py
===================================================================
--- CalDAVTester/trunk/src/serverinfo.py	2007-03-06 01:37:34 UTC (rev 1323)
+++ CalDAVTester/trunk/src/serverinfo.py	2007-03-06 17:25:55 UTC (rev 1324)
@@ -26,7 +26,7 @@
     """
     Maintains information about the server beiung targetted.
     """
-    __slots__  = ['host', 'port', 'ssl', 'calendarpath', 'user', 'pswd', 'serverfilepath', 'subsdict']
+    __slots__  = ['host', 'port', 'ssl', 'calendarpath', 'user', 'pswd', 'serverfilepath', 'subsdict', 'extrasubsdict',]
 
 
     def __init__( self ):
@@ -38,17 +38,32 @@
         self.pswd = ""
         self.serverfilepath = ""
         self.subsdict = {}
+        self.extrasubsdict = {}
 
-    def subs(self, str):
-        for key, value in self.subsdict.iteritems():
+    def subs(self, str, db=None):
+        if db is None:
+            db = self.subsdict
+        for key, value in db.iteritems():
             str = str.replace(key, value)
         return str
 
-    def addsubs(self, items):
+    def addsubs(self, items, db=None):
+        if db is None:
+            db = self.subsdict
         for key, value in items.iteritems():
-            self.subsdict[key] = value
+            db[key] = value
    
-        self.updateParams()
+        if db is None:
+            self.updateParams()
+    
+    def hasextrasubs(self):
+        return len(self.extrasubsdict) > 0
+
+    def extrasubs(self, str):
+        return self.subs(str, self.extrasubsdict)
+
+    def addextrasubs(self, items):
+        self.addsubs(items, self.extrasubsdict)
         
     def parseXML( self, node ):
         for child in node._get_childNodes():

Modified: CalDAVTester/trunk/src/xmlDefs.py
===================================================================
--- CalDAVTester/trunk/src/xmlDefs.py	2007-03-06 01:37:34 UTC (rev 1323)
+++ CalDAVTester/trunk/src/xmlDefs.py	2007-03-06 17:25:55 UTC (rev 1324)
@@ -31,6 +31,7 @@
 ELEMENT_END = "end"
 ELEMENT_FILEPATH = "filepath"
 ELEMENT_GRABLOCATION = "grablocation"
+ELEMENT_GRABPROPERTY = "grabproperty"
 ELEMENT_HEADER = "header"
 ELEMENT_HOST = "host"
 ELEMENT_KEY = "key"
@@ -43,6 +44,7 @@
 ELEMENT_PERIOD = "period"
 ELEMENT_POPULATE = "populate"
 ELEMENT_PORT = "port"
+ELEMENT_PROPERTY = "property"
 ELEMENT_REQUEST = "request"
 ELEMENT_RUNS = "runs"
 ELEMENT_RURI = "ruri"
@@ -59,6 +61,7 @@
 ELEMENT_TESTSUITE = "test-suite"
 ELEMENT_THREADS = "threads"
 ELEMENT_VALUE = "value"
+ELEMENT_VARIABLE = "variable"
 ELEMENT_VERIFY = "verify"
 ELEMENT_WARNINGTIME = "warningtime"
 

Copied: CalDAVTester/trunk/utilities (from rev 1308, CalDAVTester/trunk/utils)

Modified: CalDAVTester/trunk/utilities/__init__.py
===================================================================
--- CalDAVTester/trunk/utils/__init__.py	2007-03-05 19:03:19 UTC (rev 1308)
+++ CalDAVTester/trunk/utilities/__init__.py	2007-03-06 17:25:55 UTC (rev 1324)
@@ -15,3 +15,8 @@
 #
 # DRI: Cyrus Daboo, cdaboo at apple.com
 ##
+
+__all__ = [
+    "xmlutils",
+    "webdav",
+]

Added: CalDAVTester/trunk/utilities/xmlutils.py
===================================================================
--- CalDAVTester/trunk/utilities/xmlutils.py	                        (rev 0)
+++ CalDAVTester/trunk/utilities/xmlutils.py	2007-03-06 17:25:55 UTC (rev 1324)
@@ -0,0 +1,30 @@
+#
+# Copyright (c) 2006-2007 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.
+#
+# DRI: Cyrus Daboo, cdaboo at apple.com
+##
+
+from xml.dom.minicompat import NodeList
+from xml.dom.minidom import Node
+
+def ElementsByName(parent, nsURI, localName):
+    rc = NodeList()
+    for node in parent.childNodes:
+        if node.nodeType == Node.ELEMENT_NODE:
+            if ((localName == "*" or node.localName == localName) and
+                (nsURI == "*" or node.namespaceURI == nsURI)):
+                rc.append(node)
+    return rc
+

Modified: CalDAVTester/trunk/verifiers/__init__.py
===================================================================
--- CalDAVTester/trunk/verifiers/__init__.py	2007-03-06 01:37:34 UTC (rev 1323)
+++ CalDAVTester/trunk/verifiers/__init__.py	2007-03-06 17:25:55 UTC (rev 1324)
@@ -15,3 +15,15 @@
 #
 # DRI: Cyrus Daboo, cdaboo at apple.com
 ##
+
+__all__ = [
+    "aclItems",
+    "dataMatch",
+    "dataString",
+    "freeBusy",
+    "header",
+    "multistatusItems",
+    "prepostcondition",
+    "propfindItems",
+    "statusCode",
+]

Modified: CalDAVTester/trunk/verifiers/aclItems.py
===================================================================
--- CalDAVTester/trunk/verifiers/aclItems.py	2007-03-06 01:37:34 UTC (rev 1323)
+++ CalDAVTester/trunk/verifiers/aclItems.py	2007-03-06 17:25:55 UTC (rev 1324)
@@ -21,24 +21,15 @@
 are available for the currently authenticated user.
 """
 
-from xml.dom.minicompat import NodeList
 from xml.dom.minidom import Element
-from xml.dom.minidom import Node
 import xml.dom.minidom
 
+from utilities.xmlutils import ElementsByName
+
 class Verifier(object):
     
     def verify(self, manager, uri, response, respdata, args): #@UnusedVariable
 
-        def ElementsByName(parent, nsURI, localName):
-            rc = NodeList()
-            for node in parent.childNodes:
-                if node.nodeType == Node.ELEMENT_NODE:
-                    if ((localName == "*" or node.localName == localName) and
-                        (nsURI == "*" or node.namespaceURI == nsURI)):
-                        rc.append(node)
-            return rc
-
         granted = args.get("granted", [])
         denied = args.get("denied", [])
         

Modified: CalDAVTester/trunk/verifiers/multistatusItems.py
===================================================================
--- CalDAVTester/trunk/verifiers/multistatusItems.py	2007-03-06 01:37:34 UTC (rev 1323)
+++ CalDAVTester/trunk/verifiers/multistatusItems.py	2007-03-06 17:25:55 UTC (rev 1324)
@@ -21,23 +21,14 @@
 are returned with appropriate status codes.
 """
 
-from xml.dom.minicompat import NodeList
-from xml.dom.minidom import Node
 import xml.dom.minidom
 
+from utilities.xmlutils import ElementsByName
+
 class Verifier(object):
     
     def verify(self, manager, uri, response, respdata, args):
 
-        def ElementsByName(parent, nsURI, localName):
-            rc = NodeList()
-            for node in parent.childNodes:
-                if node.nodeType == Node.ELEMENT_NODE:
-                    if ((localName == "*" or node.localName == localName) and
-                        (nsURI == "*" or node.namespaceURI == nsURI)):
-                        rc.append(node)
-            return rc
-
         # If no hrefs requested, then assume none should come back
         okhrefs = args.get("okhrefs", [])
         badhrefs = args.get("badhrefs", [])

Modified: CalDAVTester/trunk/verifiers/propfindItems.py
===================================================================
--- CalDAVTester/trunk/verifiers/propfindItems.py	2007-03-06 01:37:34 UTC (rev 1323)
+++ CalDAVTester/trunk/verifiers/propfindItems.py	2007-03-06 17:25:55 UTC (rev 1324)
@@ -21,46 +21,45 @@
 are returned with appropriate status codes.
 """
 
-from xml.dom.minicompat import NodeList
 from xml.dom.minidom import Element
-from xml.dom.minidom import Node
 import xml.dom.minidom
 
+from utilities.xmlutils import ElementsByName
+
 class Verifier(object):
     
     def verify(self, manager, uri, response, respdata, args): #@UnusedVariable
-        def ElementsByName(parent, nsURI, localName):
-            rc = NodeList()
-            for node in parent.childNodes:
-                if node.nodeType == Node.ELEMENT_NODE:
-                    if ((localName == "*" or node.localName == localName) and
-                        (nsURI == "*" or node.namespaceURI == nsURI)):
-                        rc.append(node)
-            return rc
 
         # If no status veriffication requested, then assume all 2xx codes are OK
         ignores = args.get("ignore", [])
 
         # Get property arguments and split on $ delimited for name, value tuples
         okprops = args.get("okprops", [])
+        ok_props_match = []
+        okprops_nomatch = {}
         for i in range(len(okprops)):
             p = okprops[i]
             if (p.find("$") != -1):
                 if  p.find("$") != len(p) - 1:
-                    okprops[i] = (p.split("$")[0], p.split("$")[1],)
+                    ok_props_match.append((p.split("$")[0], p.split("$")[1]))
                 else:
-                    okprops[i] = (p.split("$")[0], None,)
+                    ok_props_match.append((p.split("$")[0], None))
+            elif (p.find("!") != -1):
+                if  p.find("!") != len(p) - 1:
+                    okprops_nomatch[p.split("!")[0]] = p.split("!")[1]
+                else:
+                    okprops_nomatch[p.split("!")[0]] = None
             else:
-                okprops[i] = (p, None,)
+                ok_props_match.append((p, None))
         badprops = args.get("badprops", [])
         for i in range(len(badprops)):
             p = badprops[i]
             if p.find("$") != -1:
-                badprops[i] = (p.split("$")[0], p.split("$")[1],)
+                badprops[i] = (p.split("$")[0], p.split("$")[1])
             else:
-                badprops[i] = (p, None,)
+                badprops[i] = (p, None)
 
-        ok_test_set = set( okprops )
+        ok_test_set = set( ok_props_match )
         bad_test_set = set( badprops )
         
         # Process the multistatus response, extracting all hrefs
@@ -145,6 +144,11 @@
             bad_missing = bad_test_set.difference( bad_result_set )
             bad_extras = bad_result_set.difference( bad_test_set )
             
+            # Now remove extras that are in the no-match set
+            for name, value in [p for p in ok_extras]:
+                if okprops_nomatch.has_key(name) and okprops_nomatch[name] != value:
+                    ok_extras.remove((name, value))
+                    
             if len( ok_missing ) + len( ok_extras ) + len( bad_missing ) + len( bad_extras )!= 0:
                 if len( ok_missing ) != 0:
                     l = list( ok_missing )

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20070306/c00ee8bd/attachment.html


More information about the calendarserver-changes mailing list