blob: 7bffa483886c37e750b65028c40fb07e6570cd03 [file] [log] [blame]
Georg Brandl38eceaa2008-05-26 11:14:17 +00001from xmlrpc.server import DocXMLRPCServer
Georg Brandl24420152008-05-26 16:32:26 +00002import http.client
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003from test import support
Christian Heimes2f1019e2007-12-10 16:18:49 +00004import threading
5import time
6import unittest
Christian Heimes2f1019e2007-12-10 16:18:49 +00007
8PORT = None
9
10def server(evt, numrequests):
Benjamin Petersonf10a79a2008-10-11 00:49:57 +000011 serv = DocXMLRPCServer(("localhost", 0), logRequests=False)
Christian Heimes2f1019e2007-12-10 16:18:49 +000012
Benjamin Petersonf10a79a2008-10-11 00:49:57 +000013 try:
Christian Heimes2f1019e2007-12-10 16:18:49 +000014 global PORT
15 PORT = serv.socket.getsockname()[1]
16
17 # Add some documentation
18 serv.set_server_title("DocXMLRPCServer Test Documentation")
19 serv.set_server_name("DocXMLRPCServer Test Docs")
20 serv.set_server_documentation(
21"""This is an XML-RPC server's documentation, but the server can be used by
22POSTing to /RPC2. Try self.add, too.""")
23
24 # Create and register classes and functions
25 class TestClass(object):
26 def test_method(self, arg):
27 """Test method's docs. This method truly does very little."""
28 self.arg = arg
29
30 serv.register_introspection_functions()
31 serv.register_instance(TestClass())
32
33 def add(x, y):
34 """Add two instances together. This follows PEP008, but has nothing
35 to do with RFC1952. Case should matter: pEp008 and rFC1952. Things
36 that start with http and ftp should be auto-linked, too:
37 http://google.com.
38 """
39 return x + y
40
41 serv.register_function(add)
42 serv.register_function(lambda x, y: x-y)
43
44 while numrequests > 0:
45 serv.handle_request()
46 numrequests -= 1
47 except socket.timeout:
48 pass
49 finally:
50 serv.server_close()
51 PORT = None
52 evt.set()
53
54class DocXMLRPCHTTPGETServer(unittest.TestCase):
55 def setUp(self):
56 # Enable server feedback
57 DocXMLRPCServer._send_traceback_header = True
58
59 self.evt = threading.Event()
60 threading.Thread(target=server, args=(self.evt, 1)).start()
61
62 # wait for port to be assigned
63 n = 1000
64 while n > 0 and PORT is None:
65 time.sleep(0.001)
66 n -= 1
67
Georg Brandl24420152008-05-26 16:32:26 +000068 self.client = http.client.HTTPConnection("localhost:%d" % PORT)
Christian Heimes2f1019e2007-12-10 16:18:49 +000069
70 def tearDown(self):
71 self.client.close()
72
73 self.evt.wait()
74
75 # Disable server feedback
76 DocXMLRPCServer._send_traceback_header = False
77
78 def test_valid_get_response(self):
79 self.client.request("GET", "/")
80 response = self.client.getresponse()
81
82 self.assertEqual(response.status, 200)
83 self.assertEqual(response.getheader("Content-type"), "text/html")
84
85 # Server throws an exception if we don't start to read the data
86 response.read()
87
88 def test_invalid_get_response(self):
89 self.client.request("GET", "/spam")
90 response = self.client.getresponse()
91
92 self.assertEqual(response.status, 404)
93 self.assertEqual(response.getheader("Content-type"), "text/plain")
94
95 response.read()
96
97 def test_lambda(self):
98 """Test that lambda functionality stays the same. The output produced
99 currently is, I suspect invalid because of the unencoded brackets in the
100 HTML, "<lambda>".
101
102 The subtraction lambda method is tested.
103 """
104 self.client.request("GET", "/")
105 response = self.client.getresponse()
106
Georg Brandlab91fde2009-08-13 08:51:18 +0000107 self.assertTrue(
Christian Heimesa5535f22007-12-10 20:18:07 +0000108b"""<dl><dt><a name="-&lt;lambda&gt;"><strong>&lt;lambda&gt;</strong></a>(x, y)</dt></dl>"""
Christian Heimes2f1019e2007-12-10 16:18:49 +0000109 in response.read())
110
111 def test_autolinking(self):
112 """Test that the server correctly automatically wraps references to PEPS
113 and RFCs with links, and that it linkifies text starting with http or
114 ftp protocol prefixes.
115
116 The documentation for the "add" method contains the test material.
117 """
118 self.client.request("GET", "/")
Christian Heimes2202f872008-02-06 14:31:34 +0000119 response = self.client.getresponse().read()
Christian Heimes2f1019e2007-12-10 16:18:49 +0000120
Georg Brandlab91fde2009-08-13 08:51:18 +0000121 self.assertTrue( # This is ugly ... how can it be made better?
Christian Heimes2202f872008-02-06 14:31:34 +0000122b"""<dl><dt><a name="-add"><strong>add</strong></a>(x, y)</dt><dd><tt>Add&nbsp;two&nbsp;instances&nbsp;together.&nbsp;This&nbsp;follows&nbsp;<a href="http://www.python.org/dev/peps/pep-0008/">PEP008</a>,&nbsp;but&nbsp;has&nbsp;nothing<br>\nto&nbsp;do&nbsp;with&nbsp;<a href="http://www.rfc-editor.org/rfc/rfc1952.txt">RFC1952</a>.&nbsp;Case&nbsp;should&nbsp;matter:&nbsp;pEp008&nbsp;and&nbsp;rFC1952.&nbsp;&nbsp;Things<br>\nthat&nbsp;start&nbsp;with&nbsp;http&nbsp;and&nbsp;ftp&nbsp;should&nbsp;be&nbsp;auto-linked,&nbsp;too:<br>\n<a href="http://google.com">http://google.com</a>.</tt></dd></dl>"""
123 in response, response)
Christian Heimes2f1019e2007-12-10 16:18:49 +0000124
125 def test_system_methods(self):
126 """Test the precense of three consecutive system.* methods.
127
128 This also tests their use of parameter type recognition and the systems
129 related to that process.
130 """
131 self.client.request("GET", "/")
Christian Heimesa5535f22007-12-10 20:18:07 +0000132 response = self.client.getresponse().read()
Christian Heimes2f1019e2007-12-10 16:18:49 +0000133
Georg Brandlab91fde2009-08-13 08:51:18 +0000134 self.assertTrue(
Christian Heimesa5535f22007-12-10 20:18:07 +0000135b"""<dl><dt><a name="-system.methodHelp"><strong>system.methodHelp</strong></a>(method_name)</dt><dd><tt><a href="#-system.methodHelp">system.methodHelp</a>(\'add\')&nbsp;=&gt;&nbsp;"Adds&nbsp;two&nbsp;integers&nbsp;together"<br>\n&nbsp;<br>\nReturns&nbsp;a&nbsp;string&nbsp;containing&nbsp;documentation&nbsp;for&nbsp;the&nbsp;specified&nbsp;method.</tt></dd></dl>\n<dl><dt><a name="-system.methodSignature"><strong>system.methodSignature</strong></a>(method_name)</dt><dd><tt><a href="#-system.methodSignature">system.methodSignature</a>(\'add\')&nbsp;=&gt;&nbsp;[double,&nbsp;int,&nbsp;int]<br>\n&nbsp;<br>\nReturns&nbsp;a&nbsp;list&nbsp;describing&nbsp;the&nbsp;signature&nbsp;of&nbsp;the&nbsp;method.&nbsp;In&nbsp;the<br>\nabove&nbsp;example,&nbsp;the&nbsp;add&nbsp;method&nbsp;takes&nbsp;two&nbsp;integers&nbsp;as&nbsp;arguments<br>\nand&nbsp;returns&nbsp;a&nbsp;double&nbsp;result.<br>\n&nbsp;<br>\nThis&nbsp;server&nbsp;does&nbsp;NOT&nbsp;support&nbsp;system.methodSignature.</tt></dd></dl>\n<dl><dt><a name="-test_method"><strong>test_method</strong></a>(arg)</dt><dd><tt>Test&nbsp;method\'s&nbsp;docs.&nbsp;This&nbsp;method&nbsp;truly&nbsp;does&nbsp;very&nbsp;little.</tt></dd></dl>""" in response)
Christian Heimes2f1019e2007-12-10 16:18:49 +0000136
137 def test_autolink_dotted_methods(self):
138 """Test that selfdot values are made strong automatically in the
139 documentation."""
140 self.client.request("GET", "/")
141 response = self.client.getresponse()
142
Georg Brandlab91fde2009-08-13 08:51:18 +0000143 self.assertTrue(b"""Try&nbsp;self.<strong>add</strong>,&nbsp;too.""" in
Christian Heimes2f1019e2007-12-10 16:18:49 +0000144 response.read())
145
146def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000147 support.run_unittest(DocXMLRPCHTTPGETServer)
Christian Heimes2f1019e2007-12-10 16:18:49 +0000148
149if __name__ == '__main__':
150 test_main()