[Zope3-checkins] SVN: Zope3/branches/ctheune-xmlrpc-testing/ Added
xmlrpc ServerProxy for functional tests.
Christian Theune
ct at gocept.com
Tue Sep 19 04:09:58 EDT 2006
Log message for revision 70220:
Added xmlrpc ServerProxy for functional tests.
Changed:
U Zope3/branches/ctheune-xmlrpc-testing/doc/CHANGES.txt
U Zope3/branches/ctheune-xmlrpc-testing/src/zope/app/publisher/xmlrpc/README.txt
A Zope3/branches/ctheune-xmlrpc-testing/src/zope/app/testing/xmlrpc.py
-=-
Modified: Zope3/branches/ctheune-xmlrpc-testing/doc/CHANGES.txt
===================================================================
--- Zope3/branches/ctheune-xmlrpc-testing/doc/CHANGES.txt 2006-09-19 08:07:35 UTC (rev 70219)
+++ Zope3/branches/ctheune-xmlrpc-testing/doc/CHANGES.txt 2006-09-19 08:09:57 UTC (rev 70220)
@@ -10,6 +10,9 @@
New features
+ - Added xmlrpclib.ServerProxy variation in zope.app.testing.xmlrpc
+ that allows testing XML-RPC views in functional tests.
+
- Added attribute `permission` to the `browser:menuItems`-directive to
allow setting a default value for all menu items defined in this
directive.
Modified: Zope3/branches/ctheune-xmlrpc-testing/src/zope/app/publisher/xmlrpc/README.txt
===================================================================
--- Zope3/branches/ctheune-xmlrpc-testing/src/zope/app/publisher/xmlrpc/README.txt 2006-09-19 08:07:35 UTC (rev 70219)
+++ Zope3/branches/ctheune-xmlrpc-testing/src/zope/app/publisher/xmlrpc/README.txt 2006-09-19 08:09:57 UTC (rev 70220)
@@ -60,67 +60,20 @@
And call our xmlrpc method:
- >>> print http(r"""
- ... POST / HTTP/1.0
- ... Authorization: Basic bWdyOm1ncnB3
- ... Content-Length: 102
- ... Content-Type: text/xml
- ...
- ... <?xml version='1.0'?>
- ... <methodCall>
- ... <methodName>contents</methodName>
- ... <params>
- ... </params>
- ... </methodCall>
- ... """)
- HTTP/1.0 200 Ok
- Content-Length: 208
- Content-Type: text/xml;charset=utf-8
- <BLANKLINE>
- <?xml version='1.0'?>
- <methodResponse>
- <params>
- <param>
- <value><array><data>
- <value><string>f1</string></value>
- <value><string>f2</string></value>
- </data></array></value>
- </param>
- </params>
- </methodResponse>
- <BLANKLINE>
+ >>> from zope.app.testing.xmlrpc import ServerProxy
+ >>> proxy = ServerProxy("http://mgr:mgrpw@localhost/")
+ >>> proxy.contents()
+ ['f1', 'f2']
-
Note that we get an unauthorized error if we don't supply authentication
credentials:
- >>> print http(r"""
- ... POST / HTTP/1.0
- ... Content-Length: 102
- ... Content-Type: text/xml
- ...
- ... <?xml version='1.0'?>
- ... <methodCall>
- ... <methodName>contents</methodName>
- ... <params>
- ... </params>
- ... </methodCall>
- ... """)
- HTTP/1.0 401 Unauthorized
- Content-Length: 126
- Content-Type: text/xml;charset=utf-8
- WWW-Authenticate: basic realm="Zope"
- <BLANKLINE>
- <?xml version='1.0'?>
- <methodResponse>
- <params>
- <param>
- <value><string></string></value>
- </param>
- </params>
- </methodResponse>
- <BLANKLINE>
+ >>> proxy = ServerProxy("http://localhost/")
+ >>> proxy.contents()
+ Traceback (most recent call last):
+ ProtocolError: <ProtocolError for localhost/: 401 401 Unauthorized>
+
Named XML-RPC Views
-------------------
@@ -182,64 +135,19 @@
Now, when we access the `contents`, we do so through the listing view:
- >>> print http(r"""
- ... POST /listing/ HTTP/1.0
- ... Authorization: Basic bWdyOm1ncnB3
- ... Content-Length: 102
- ... Content-Type: text/xml
- ...
- ... <?xml version='1.0'?>
- ... <methodCall>
- ... <methodName>contents</methodName>
- ... <params>
- ... </params>
- ... </methodCall>
- ... """)
- HTTP/1.0 200 Ok
- Content-Length: 208
- Content-Type: text/xml;charset=utf-8
- <BLANKLINE>
- <?xml version='1.0'?>
- <methodResponse>
- <params>
- <param>
- <value><array><data>
- <value><string>f1</string></value>
- <value><string>f2</string></value>
- </data></array></value>
- </param>
- </params>
- </methodResponse>
- <BLANKLINE>
+ >>> proxy = ServerProxy("http://mgr:mgrpw@localhost/listing/")
+ >>> proxy.contents()
+ ['f1', 'f2']
+ >>> proxy = ServerProxy("http://mgr:mgrpw@localhost/")
+ >>> proxy.listing.contents()
+ ['f1', 'f2']
as before, we will get an error if we don't supply credentials:
- >>> print http(r"""
- ... POST /listing/ HTTP/1.0
- ... Content-Length: 102
- ... Content-Type: text/xml
- ...
- ... <?xml version='1.0'?>
- ... <methodCall>
- ... <methodName>contents</methodName>
- ... <params>
- ... </params>
- ... </methodCall>
- ... """)
- HTTP/1.0 401 Unauthorized
- Content-Length: 126
- Content-Type: text/xml;charset=utf-8
- WWW-Authenticate: basic realm="Zope"
- <BLANKLINE>
- <?xml version='1.0'?>
- <methodResponse>
- <params>
- <param>
- <value><string></string></value>
- </param>
- </params>
- </methodResponse>
- <BLANKLINE>
+ >>> proxy = ServerProxy("http://localhost/listing/")
+ >>> proxy.contents()
+ Traceback (most recent call last):
+ ProtocolError: <ProtocolError for localhost/listing/: 401 401 Unauthorized>
Parameters
----------
@@ -278,34 +186,9 @@
Then we can issue a remote procedure call with a parameter and get
back, surprise!, the sum:
- >>> print http(r"""
- ... POST / HTTP/1.0
- ... Authorization: Basic bWdyOm1ncnB3
- ... Content-Length: 159
- ... Content-Type: text/xml
- ...
- ... <?xml version='1.0'?>
- ... <methodCall>
- ... <methodName>add</methodName>
- ... <params>
- ... <param><int>20</int></param>
- ... <param><int>22</int></param>
- ... </params>
- ... </methodCall>
- ... """, handle_errors=False)
- HTTP/1.0 200 Ok
- Content-Length: 122
- Content-Type: text/xml;charset=utf-8
- <BLANKLINE>
- <?xml version='1.0'?>
- <methodResponse>
- <params>
- <param>
- <value><int>42</int></value>
- </param>
- </params>
- </methodResponse>
- <BLANKLINE>
+ >>> proxy = ServerProxy("http://mgr:mgrpw@localhost/")
+ >>> proxy.add(20, 22)
+ 42
Faults
------
@@ -346,40 +229,12 @@
Now, when we call it, we get a proper XML-RPC fault:
- >>> print http(r"""
- ... POST / HTTP/1.0
- ... Authorization: Basic bWdyOm1ncnB3
- ... Content-Length: 104
- ... Content-Type: text/xml
- ...
- ... <?xml version='1.0'?>
- ... <methodCall>
- ... <methodName>your_fault</methodName>
- ... <params>
- ... </params>
- ... </methodCall>
- ... """, handle_errors=False)
- HTTP/1.0 200 Ok
- Content-Length: 272
- Content-Type: text/xml;charset=utf-8
- <BLANKLINE>
- <?xml version='1.0'?>
- <methodResponse>
- <fault>
- <value><struct>
- <member>
- <name>faultCode</name>
- <value><int>42</int></value>
- </member>
- <member>
- <name>faultString</name>
- <value><string>It's your fault!</string></value>
- </member>
- </struct></value>
- </fault>
- </methodResponse>
- <BLANKLINE>
+ >>> proxy = ServerProxy("http://mgr:mgrpw@localhost/")
+ >>> proxy.your_fault()
+ Traceback (most recent call last):
+ Fault: <Fault 42: "It's your fault!">
+
DateTime values
---------------
@@ -420,29 +275,6 @@
Now, when we call it, we get a DateTime value
- >>> print http(r"""
- ... POST / HTTP/1.0
- ... Authorization: Basic bWdyOm1ncnB3
- ... Content-Length: 100
- ... Content-Type: text/xml
- ...
- ... <?xml version='1.0'?>
- ... <methodCall>
- ... <methodName>epoch</methodName>
- ... <params>
- ... </params>
- ... </methodCall>
- ... """, handle_errors=False)
- HTTP/1.0 200 Ok
- Content-Length: 163
- Content-Type: text/xml;charset=utf-8
- <BLANKLINE>
- <?xml version='1.0'?>
- <methodResponse>
- <params>
- <param>
- <value><dateTime.iso8601>19700101T01:00:01</dateTime.iso8601></value>
- </param>
- </params>
- </methodResponse>
- <BLANKLINE>
+ >>> proxy = ServerProxy("http://mgr:mgrpw@localhost/")
+ >>> proxy.epoch()
+ <DateTime u'19700101T01:00:01' at ...>
Added: Zope3/branches/ctheune-xmlrpc-testing/src/zope/app/testing/xmlrpc.py
===================================================================
--- Zope3/branches/ctheune-xmlrpc-testing/src/zope/app/testing/xmlrpc.py 2006-09-19 08:07:35 UTC (rev 70219)
+++ Zope3/branches/ctheune-xmlrpc-testing/src/zope/app/testing/xmlrpc.py 2006-09-19 08:09:57 UTC (rev 70220)
@@ -0,0 +1,69 @@
+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""XMLRPC testing helpers for Zope 3.
+
+$Id$
+"""
+
+from StringIO import StringIO
+import xmlrpclib
+
+from zope.app.testing.functional import HTTPCaller
+
+
+REQUEST_TEMPLATE = """POST %(handler)s HTTP/1.0
+Authorization: %(authorization)s
+Content-Length: %(content_length)i
+Content-Type: text/xml
+
+"""
+
+
+class ZopeTestTransport(xmlrpclib.Transport):
+ """xmlrpclib transport that delegates to
+ zope.app.testing.functional.HTTPCaller.
+ """
+
+ verbose = False
+
+ def request(self, host, handler, request_body, verbose=0):
+ request = "POST %s HTTP/1.0\n" % (handler,)
+ request += "Content-Length: %i\n" % len(request_body)
+ request += "Content-Type: text/xml\n"
+
+ host, extra_headers, x509 = self.get_host_info(host)
+ if extra_headers:
+ request += "Authorization: %s\n" % (dict(extra_headers)["Authorization"],)
+
+ request += "\n" + request_body
+ response = HTTPCaller()(request)
+
+ errcode = response.getStatus()
+ errmsg = response.getStatusString()
+ headers = response.getHeaders()
+
+ if errcode != 200:
+ raise xmlrpclib.ProtocolError(
+ host + handler,
+ errcode, errmsg,
+ headers
+ )
+
+ return self._parse_response(StringIO(response.getBody()), sock=None)
+
+
+
+def ServerProxy(uri, transport=ZopeTestTransport(), encoding=None,
+ verbose=0, allow_none=0):
+ return xmlrpclib.ServerProxy(uri, transport, encoding, verbose, allow_none)
Property changes on: Zope3/branches/ctheune-xmlrpc-testing/src/zope/app/testing/xmlrpc.py
___________________________________________________________________
Name: svn:keywords
+ Id Rev Date
Name: svn:eol-style
+ native
More information about the Zope3-Checkins
mailing list