1
from xmlrpc.server import DocXMLRPCServer
4
from test import support
5
threading = support.import_module('threading')
12
def make_request_and_skipIf(condition, reason):
13
# If we skip the test, we have to make a request because the
14
# the server created in setUp blocks expecting one to come in.
16
return lambda func: func
18
def make_request_and_skip(self):
19
self.client.request("GET", "/")
20
self.client.getresponse()
21
raise unittest.SkipTest(reason)
22
return make_request_and_skip
26
def server(evt, numrequests):
27
serv = DocXMLRPCServer(("localhost", 0), logRequests=False)
31
PORT = serv.socket.getsockname()[1]
33
# Add some documentation
34
serv.set_server_title("DocXMLRPCServer Test Documentation")
35
serv.set_server_name("DocXMLRPCServer Test Docs")
36
serv.set_server_documentation(
37
"This is an XML-RPC server's documentation, but the server "
38
"can be used by POSTing to /RPC2. Try self.add, too.")
40
# Create and register classes and functions
41
class TestClass(object):
42
def test_method(self, arg):
43
"""Test method's docs. This method truly does very little."""
46
serv.register_introspection_functions()
47
serv.register_instance(TestClass())
50
"""Add two instances together. This follows PEP008, but has nothing
51
to do with RFC1952. Case should matter: pEp008 and rFC1952. Things
52
that start with http and ftp should be auto-linked, too:
57
def annotation(x: int):
58
""" Use function annotations. """
61
class ClassWithAnnotation:
62
def method_annotation(self, x: bytes):
65
serv.register_function(add)
66
serv.register_function(lambda x, y: x-y)
67
serv.register_function(annotation)
68
serv.register_instance(ClassWithAnnotation())
70
while numrequests > 0:
73
except socket.timeout:
80
class DocXMLRPCHTTPGETServer(unittest.TestCase):
82
self._threads = support.threading_setup()
83
# Enable server feedback
84
DocXMLRPCServer._send_traceback_header = True
86
self.evt = threading.Event()
87
threading.Thread(target=server, args=(self.evt, 1)).start()
89
# wait for port to be assigned
91
while n > 0 and PORT is None:
95
self.client = http.client.HTTPConnection("localhost:%d" % PORT)
102
# Disable server feedback
103
DocXMLRPCServer._send_traceback_header = False
104
support.threading_cleanup(*self._threads)
106
def test_valid_get_response(self):
107
self.client.request("GET", "/")
108
response = self.client.getresponse()
110
self.assertEqual(response.status, 200)
111
self.assertEqual(response.getheader("Content-type"), "text/html")
113
# Server raises an exception if we don't start to read the data
116
def test_invalid_get_response(self):
117
self.client.request("GET", "/spam")
118
response = self.client.getresponse()
120
self.assertEqual(response.status, 404)
121
self.assertEqual(response.getheader("Content-type"), "text/plain")
125
def test_lambda(self):
126
"""Test that lambda functionality stays the same. The output produced
127
currently is, I suspect invalid because of the unencoded brackets in the
130
The subtraction lambda method is tested.
132
self.client.request("GET", "/")
133
response = self.client.getresponse()
135
self.assertIn((b'<dl><dt><a name="-<lambda>"><strong>'
136
b'<lambda></strong></a>(x, y)</dt></dl>'),
139
@make_request_and_skipIf(sys.flags.optimize >= 2,
140
"Docstrings are omitted with -O2 and above")
141
def test_autolinking(self):
142
"""Test that the server correctly automatically wraps references to
143
PEPS and RFCs with links, and that it linkifies text starting with
144
http or ftp protocol prefixes.
146
The documentation for the "add" method contains the test material.
148
self.client.request("GET", "/")
149
response = self.client.getresponse().read()
152
(b'<dl><dt><a name="-add"><strong>add</strong></a>(x, y)</dt><dd>'
153
b'<tt>Add two instances together. This '
154
b'follows <a href="http://www.python.org/dev/peps/pep-0008/">'
155
b'PEP008</a>, but has nothing<br>\nto do '
156
b'with <a href="http://www.rfc-editor.org/rfc/rfc1952.txt">'
157
b'RFC1952</a>. Case should matter: pEp008 '
158
b'and rFC1952. Things<br>\nthat start '
159
b'with http and ftp should be '
160
b'auto-linked, too:<br>\n<a href="http://google.com">'
161
b'http://google.com</a>.</tt></dd></dl>'), response)
163
@make_request_and_skipIf(sys.flags.optimize >= 2,
164
"Docstrings are omitted with -O2 and above")
165
def test_system_methods(self):
166
"""Test the precense of three consecutive system.* methods.
168
This also tests their use of parameter type recognition and the
169
systems related to that process.
171
self.client.request("GET", "/")
172
response = self.client.getresponse().read()
175
(b'<dl><dt><a name="-system.methodHelp"><strong>system.methodHelp'
176
b'</strong></a>(method_name)</dt><dd><tt><a href="#-system.method'
177
b'Help">system.methodHelp</a>(\'add\') => "Adds '
178
b'two integers together"<br>\n <br>\nReturns a'
179
b' string containing documentation for '
180
b'the specified method.</tt></dd></dl>\n<dl><dt><a name'
181
b'="-system.methodSignature"><strong>system.methodSignature</strong>'
182
b'</a>(method_name)</dt><dd><tt><a href="#-system.methodSignature">'
183
b'system.methodSignature</a>(\'add\') => [double, '
184
b'int, int]<br>\n <br>\nReturns a list '
185
b'describing the signature of the method.'
186
b' In the<br>\nabove example, the add '
187
b'method takes two integers as arguments'
188
b'<br>\nand returns a double result.<br>\n '
189
b'<br>\nThis server does NOT support system'
190
b'.methodSignature.</tt></dd></dl>'), response)
192
def test_autolink_dotted_methods(self):
193
"""Test that selfdot values are made strong automatically in the
195
self.client.request("GET", "/")
196
response = self.client.getresponse()
198
self.assertIn(b"""Try self.<strong>add</strong>, too.""",
201
def test_annotations(self):
202
""" Test that annotations works as expected """
203
self.client.request("GET", "/")
204
response = self.client.getresponse()
206
(b'<dl><dt><a name="-annotation"><strong>annotation</strong></a>'
207
b'(x: int)</dt><dd><tt>Use function annotations.</tt>'
208
b'</dd></dl>\n<dl><dt><a name="-method_annotation"><strong>'
209
b'method_annotation</strong></a>(x: bytes)</dt></dl>'),
214
support.run_unittest(DocXMLRPCHTTPGETServer)
216
if __name__ == '__main__':