[CalendarServer-changes] [9917] CalDAVTester/trunk
source_changes at macosforge.org
source_changes at macosforge.org
Wed Oct 10 08:51:13 PDT 2012
Revision: 9917
http://trac.calendarserver.org//changeset/9917
Author: cdaboo at apple.com
Date: 2012-10-10 08:51:13 -0700 (Wed, 10 Oct 2012)
Log Message:
-----------
Expand XML xpath-style tests to target sub-tree's within a document (useful for checking properties of specific
resources in Depth:1 responses). Add a sharing test for Depth:1.
Modified Paths:
--------------
CalDAVTester/trunk/README.txt
CalDAVTester/trunk/scripts/server/serverinfo-partitioning.xml
CalDAVTester/trunk/scripts/server/serverinfo-template.xml
CalDAVTester/trunk/scripts/server/serverinfo.xml
CalDAVTester/trunk/scripts/tests/CalDAV/sharing-calendars.xml
CalDAVTester/trunk/verifiers/xmlElementMatch.py
Modified: CalDAVTester/trunk/README.txt
===================================================================
--- CalDAVTester/trunk/README.txt 2012-10-09 23:54:56 UTC (rev 9916)
+++ CalDAVTester/trunk/README.txt 2012-10-10 15:51:13 UTC (rev 9917)
@@ -616,9 +616,22 @@
Compares the response with an XML data file and returns TRUE if there
is a match, otherwise False.
The path is the absolute xpath from the root element down. Attribute, attribute-value
- and text contents tests of the matched element can be done using [@attr], [@attr="value"],
- and [="text"] suffixes on the path.
+ and text contents tests of the matched element can be done using:
+ [@attr] - "attr" is present as an attribute
+ [@attr=value] - "attr" is present as an attribute with the value "value"
+ [=text] - node text is "text".
+ [!text] - node text is not "text".
+ [*text] - node text contains "text".
+ [+text] - node text starts with "text".
+ [^tag] - node has child element "tag".
+ [^tag=text] - node has child element "tag" with text "text".
+
+ Argument: 'parent'
+ ElementTree style path for an XML element to use as the root for any
+ subsequent "exists" or "notexists" tests. This is useful for targeting
+ a specific resource in a Depth:1 multistatus response.
+
Argument: 'exists'
ElementTree style path for an XML element to check the presence of
in the response.
Modified: CalDAVTester/trunk/scripts/server/serverinfo-partitioning.xml
===================================================================
--- CalDAVTester/trunk/scripts/server/serverinfo-partitioning.xml 2012-10-09 23:54:56 UTC (rev 9916)
+++ CalDAVTester/trunk/scripts/server/serverinfo-partitioning.xml 2012-10-10 15:51:13 UTC (rev 9917)
@@ -92,7 +92,7 @@
<!-- CardDAV specific extension -->
<feature>carddav</feature> <!-- Basic CardDAV feature enabler -->
<feature>default-addressbook</feature> <!-- Default address book behavior -->
- <!-- <feature>global-addressbook</feature> --> <!-- Global address book for each user -->
+ <!-- <feature>global-addressbook</feature> --> <!-- Global address book for each user -->
<feature>shared-addressbooks</feature> <!-- Shared address books extension -->
<!-- <feature>directory-gateway</feature> --> <!-- Directory gateway extension -->
@@ -101,10 +101,18 @@
<substitutions>
<!-- Useful xpath shortcuts for verifiers -->
<substitution>
+ <key>$multistatus-response-prefix:</key>
+ <value>/{DAV:}multistatus/{DAV:}response</value>
+ </substitution>
+ <substitution>
<key>$multistatus-href-prefix:</key>
<value>/{DAV:}multistatus/{DAV:}response/{DAV:}href</value>
</substitution>
<substitution>
+ <key>$verify-response-prefix:</key>
+ <value>{DAV:}response/{DAV:}propstat/{DAV:}prop</value>
+ </substitution>
+ <substitution>
<key>$verify-property-prefix:</key>
<value>/{DAV:}multistatus/{DAV:}response/{DAV:}propstat/{DAV:}prop</value>
</substitution>
Modified: CalDAVTester/trunk/scripts/server/serverinfo-template.xml
===================================================================
--- CalDAVTester/trunk/scripts/server/serverinfo-template.xml 2012-10-09 23:54:56 UTC (rev 9916)
+++ CalDAVTester/trunk/scripts/server/serverinfo-template.xml 2012-10-10 15:51:13 UTC (rev 9917)
@@ -101,10 +101,18 @@
<substitutions>
<!-- Useful xpath shortcuts for verifiers -->
<substitution>
+ <key>$multistatus-response-prefix:</key>
+ <value>/{DAV:}multistatus/{DAV:}response</value>
+ </substitution>
+ <substitution>
<key>$multistatus-href-prefix:</key>
<value>/{DAV:}multistatus/{DAV:}response/{DAV:}href</value>
</substitution>
<substitution>
+ <key>$verify-response-prefix:</key>
+ <value>{DAV:}response/{DAV:}propstat/{DAV:}prop</value>
+ </substitution>
+ <substitution>
<key>$verify-property-prefix:</key>
<value>/{DAV:}multistatus/{DAV:}response/{DAV:}propstat/{DAV:}prop</value>
</substitution>
Modified: CalDAVTester/trunk/scripts/server/serverinfo.xml
===================================================================
--- CalDAVTester/trunk/scripts/server/serverinfo.xml 2012-10-09 23:54:56 UTC (rev 9916)
+++ CalDAVTester/trunk/scripts/server/serverinfo.xml 2012-10-10 15:51:13 UTC (rev 9917)
@@ -101,10 +101,18 @@
<substitutions>
<!-- Useful xpath shortcuts for verifiers -->
<substitution>
+ <key>$multistatus-response-prefix:</key>
+ <value>/{DAV:}multistatus/{DAV:}response</value>
+ </substitution>
+ <substitution>
<key>$multistatus-href-prefix:</key>
<value>/{DAV:}multistatus/{DAV:}response/{DAV:}href</value>
</substitution>
<substitution>
+ <key>$verify-response-prefix:</key>
+ <value>{DAV:}response/{DAV:}propstat/{DAV:}prop</value>
+ </substitution>
+ <substitution>
<key>$verify-property-prefix:</key>
<value>/{DAV:}multistatus/{DAV:}response/{DAV:}propstat/{DAV:}prop</value>
</substitution>
Modified: CalDAVTester/trunk/scripts/tests/CalDAV/sharing-calendars.xml
===================================================================
--- CalDAVTester/trunk/scripts/tests/CalDAV/sharing-calendars.xml 2012-10-09 23:54:56 UTC (rev 9916)
+++ CalDAVTester/trunk/scripts/tests/CalDAV/sharing-calendars.xml 2012-10-10 15:51:13 UTC (rev 9917)
@@ -130,6 +130,8 @@
<arg>
<name>exists</name>
<value>$verify-property-prefix:/{DAV:}owner/{DAV:}href[=$principaluri1:]</value>
+ <value>$verify-property-prefix:/{DAV:}resourcetype/{DAV:}collection</value>
+ <value>$verify-property-prefix:/{DAV:}resourcetype/{urn:ietf:params:xml:ns:caldav}calendar</value>
<value>$verify-property-prefix:/{DAV:}resourcetype/{http://calendarserver.org/ns/}shared</value>
<value>$verify-property-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}read</value>
<value>$verify-property-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}write</value>
@@ -146,6 +148,45 @@
</request>
</test>
<test name='4a'>
+ <description>Shared calendar exists Depth:1</description>
+ <request user="$userid2:" pswd="$pswd2:" print-response='no'>
+ <method>PROPFIND</method>
+ <ruri>$calendarhome2:/</ruri>
+ <header>
+ <name>Depth</name>
+ <value>1</value>
+ </header>
+ <data>
+ <content-type>text/xml; charset=utf-8</content-type>
+ <filepath>Resource/CalDAV/sharing/calendars/read-write/4.xml</filepath>
+ </data>
+ <verify>
+ <callback>xmlElementMatch</callback>
+ <arg>
+ <name>parent</name>
+ <value>$multistatus-response-prefix:[^{DAV:}href=$sharedcalendar:/]</value>
+ </arg>
+ <arg>
+ <name>exists</name>
+ <value>$verify-response-prefix:/{DAV:}owner/{DAV:}href[=$principaluri1:]</value>
+ <value>$verify-response-prefix:/{DAV:}resourcetype/{DAV:}collection</value>
+ <value>$verify-response-prefix:/{DAV:}resourcetype/{urn:ietf:params:xml:ns:caldav}calendar</value>
+ <value>$verify-response-prefix:/{DAV:}resourcetype/{http://calendarserver.org/ns/}shared</value>
+ <value>$verify-response-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}read</value>
+ <value>$verify-response-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}write</value>
+ <value>$verify-response-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}bind</value>
+ <value>$verify-response-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}unbind</value>
+ <value>$verify-response-prefix:/{urn:ietf:params:xml:ns:caldav}schedule-calendar-transp/{urn:ietf:params:xml:ns:caldav}transparent</value>
+ </arg>
+ <arg>
+ <name>notexists</name>
+ <value>$verify-response-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}admin</value>
+ <value>$verify-response-prefix:/{DAV:}current-user-privilege-set/{DAV:}privilege/{DAV:}all</value>
+ </arg>
+ </verify>
+ </request>
+ </test>
+ <test name='4b'>
<description>Shared calendar has invite property</description>
<request user="$userid2:" pswd="$pswd2:" print-response='no'>
<method>PROPFIND</method>
Modified: CalDAVTester/trunk/verifiers/xmlElementMatch.py
===================================================================
--- CalDAVTester/trunk/verifiers/xmlElementMatch.py 2012-10-09 23:54:56 UTC (rev 9916)
+++ CalDAVTester/trunk/verifiers/xmlElementMatch.py 2012-10-10 15:51:13 UTC (rev 9917)
@@ -26,6 +26,7 @@
def verify(self, manager, uri, response, respdata, args): #@UnusedVariable
# Get arguments
+ parent = args.get("parent", [])
exists = args.get("exists", [])
notexists = args.get("notexists", [])
@@ -49,16 +50,26 @@
else:
return path, None
+ if parent:
+ nodes = self.nodeForPath(tree.getroot(), parent[0])
+ if len(nodes) == 0:
+ return False, " Response data is missing parent node: %s" % (parent[0],)
+ elif len(nodes) > 1:
+ return False, " Response data has too many parent nodes: %s" % (parent[0],)
+ root = nodes[0]
+ else:
+ root = tree.getroot()
+
result = True
resulttxt = ""
for path in exists:
- matched, txt = self.matchPath(tree, path)
+ matched, txt = self.matchPath(root, path)
result &= matched
resulttxt += txt
for path in notexists:
- matched, _ignore_txt = self.matchPath(tree, path)
+ matched, _ignore_txt = self.matchPath(root, path)
if matched:
resulttxt += " Items returned in XML for %s\n" % (path,)
result = False
@@ -66,8 +77,73 @@
return result, resulttxt
- def matchPath(self, tree, path):
+ def nodeForPath(self, root, path):
+ if '[' in path:
+ actual_path, tests = path.split('[', 1)
+ else:
+ actual_path = path
+ tests = None
+ # Handle absolute root element
+ if actual_path[0] == '/':
+ actual_path = actual_path[1:]
+ if '/' in actual_path:
+ root_path, child_path = actual_path.split('/', 1)
+ if root.tag != root_path:
+ return None
+ nodes = root.findall(child_path)
+ else:
+ root_path = actual_path
+ child_path = None
+ nodes = (root,)
+
+ if len(nodes) == 0:
+ return None
+
+ results = []
+
+ if tests:
+ tests = [item[:-1] for item in tests.split('[')]
+ for test in tests:
+ for node in nodes:
+ if test[0] == '@':
+ if '=' in test:
+ attr, value = test[1:].split('=')
+ value = value[1:-1]
+ else:
+ attr = test[1:]
+ value = None
+ if attr in node.keys() and (value is None or node.get(attr) == value):
+ results.append(node)
+ elif test[0] == '=':
+ if node.text == test[1:]:
+ results.append(node)
+ elif test[0] == '!':
+ if node.text != test[1:]:
+ results.append(node)
+ elif test[0] == '*':
+ if node.text is not None and node.text.find(test[1:]) != -1:
+ results.append(node)
+ elif test[0] == '+':
+ if node.text is not None and node.text.startswith(test[1:]):
+ results.append(node)
+ elif test[0] == '^':
+ if "=" in test:
+ element, value = test[1:].split("=", 1)
+ else:
+ element = test[1:]
+ value = None
+ for child in node.getchildren():
+ if child.tag == element and (value is None or child.text == value):
+ results.append(node)
+ else:
+ results = nodes
+
+ return results
+
+
+ def matchPath(self, root, path):
+
result = True
resulttxt = ""
@@ -82,13 +158,11 @@
actual_path = actual_path[1:]
if '/' in actual_path:
root_path, child_path = actual_path.split('/', 1)
- if tree.getroot().tag != root_path:
+ if root.tag != root_path:
resulttxt += " Items not returned in XML for %s\n" % (path,)
- nodes = tree.findall(child_path)
+ nodes = root.findall(child_path)
else:
- root_path = actual_path
- child_path = None
- nodes = (tree.getroot(),)
+ nodes = (root,)
if len(nodes) == 0:
resulttxt += " Items not returned in XML for %s\n" % (path,)
@@ -125,6 +199,17 @@
elif test[0] == '+':
if node.text is None or not node.text.startswith(test[1:]):
result = " Incorrect value returned in XML for %s\n" % (path,)
+ elif test[0] == '^':
+ if "=" in test:
+ element, value = test[1:].split("=", 1)
+ else:
+ element = test[1:]
+ value = None
+ for child in node.getchildren():
+ if child.tag == element and (value is None or child.text == value):
+ break
+ else:
+ result = " Missing child returned in XML for %s\n" % (path,)
return result
testresult = _doTest()
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20121010/84f46d73/attachment-0001.html>
More information about the calendarserver-changes
mailing list