blob: c7b7775c95a6784c4bc8ebef026ce89e6a50c895 [file] [log] [blame]
Georg Brandle6daafb2007-12-09 22:39:12 +00001from DocXMLRPCServer import DocXMLRPCServer
2import httplib
3from test import test_support
4import threading
5import time
Georg Brandl12cad202010-02-06 23:58:25 +00006import socket
Georg Brandle6daafb2007-12-09 22:39:12 +00007import unittest
8import xmlrpclib
9
10PORT = None
11
12def server(evt, numrequests):
Hirokazu Yamamotob7df32e2008-10-03 16:18:42 +000013 serv = DocXMLRPCServer(("localhost", 0), logRequests=False)
Georg Brandle6daafb2007-12-09 22:39:12 +000014
Hirokazu Yamamotob7df32e2008-10-03 16:18:42 +000015 try:
Georg Brandle6daafb2007-12-09 22:39:12 +000016 global PORT
17 PORT = serv.socket.getsockname()[1]
18
19 # Add some documentation
20 serv.set_server_title("DocXMLRPCServer Test Documentation")
21 serv.set_server_name("DocXMLRPCServer Test Docs")
22 serv.set_server_documentation(
Ezio Melottiaa980582010-01-23 23:04:36 +000023 "This is an XML-RPC server's documentation, but the server "
24 "can be used by POSTing to /RPC2. Try self.add, too.")
Georg Brandle6daafb2007-12-09 22:39:12 +000025
26 # Create and register classes and functions
27 class TestClass(object):
28 def test_method(self, arg):
29 """Test method's docs. This method truly does very little."""
30 self.arg = arg
31
32 serv.register_introspection_functions()
33 serv.register_instance(TestClass())
34
35 def add(x, y):
36 """Add two instances together. This follows PEP008, but has nothing
37 to do with RFC1952. Case should matter: pEp008 and rFC1952. Things
38 that start with http and ftp should be auto-linked, too:
39 http://google.com.
40 """
41 return x + y
42
43 serv.register_function(add)
44 serv.register_function(lambda x, y: x-y)
45
46 while numrequests > 0:
47 serv.handle_request()
48 numrequests -= 1
49 except socket.timeout:
50 pass
51 finally:
52 serv.server_close()
53 PORT = None
54 evt.set()
55
56class DocXMLRPCHTTPGETServer(unittest.TestCase):
57 def setUp(self):
Antoine Pitrou61d5f6f2009-10-30 17:33:28 +000058 self._threads = test_support.threading_setup()
Georg Brandle6daafb2007-12-09 22:39:12 +000059 # Enable server feedback
60 DocXMLRPCServer._send_traceback_header = True
61
62 self.evt = threading.Event()
63 threading.Thread(target=server, args=(self.evt, 1)).start()
64
65 # wait for port to be assigned
66 n = 1000
67 while n > 0 and PORT is None:
68 time.sleep(0.001)
69 n -= 1
70
71 self.client = httplib.HTTPConnection("localhost:%d" % PORT)
72
73 def tearDown(self):
74 self.client.close()
75
76 self.evt.wait()
77
78 # Disable server feedback
79 DocXMLRPCServer._send_traceback_header = False
Antoine Pitrou61d5f6f2009-10-30 17:33:28 +000080 test_support.threading_cleanup(*self._threads)
Georg Brandle6daafb2007-12-09 22:39:12 +000081
82 def test_valid_get_response(self):
83 self.client.request("GET", "/")
84 response = self.client.getresponse()
85
86 self.assertEqual(response.status, 200)
87 self.assertEqual(response.getheader("Content-type"), "text/html")
88
89 # Server throws an exception if we don't start to read the data
90 response.read()
91
92 def test_invalid_get_response(self):
93 self.client.request("GET", "/spam")
94 response = self.client.getresponse()
95
96 self.assertEqual(response.status, 404)
97 self.assertEqual(response.getheader("Content-type"), "text/plain")
98
99 response.read()
100
101 def test_lambda(self):
102 """Test that lambda functionality stays the same. The output produced
103 currently is, I suspect invalid because of the unencoded brackets in the
104 HTML, "<lambda>".
105
106 The subtraction lambda method is tested.
107 """
108 self.client.request("GET", "/")
109 response = self.client.getresponse()
110
Ezio Melottiaa980582010-01-23 23:04:36 +0000111 self.assertIn('<dl><dt><a name="-&lt;lambda&gt;"><strong>'
112 '&lt;lambda&gt;</strong></a>(x, y)</dt></dl>',
113 response.read())
Georg Brandle6daafb2007-12-09 22:39:12 +0000114
115 def test_autolinking(self):
116 """Test that the server correctly automatically wraps references to PEPS
117 and RFCs with links, and that it linkifies text starting with http or
118 ftp protocol prefixes.
119
120 The documentation for the "add" method contains the test material.
121 """
122 self.client.request("GET", "/")
123 response = self.client.getresponse()
124
Ezio Melottiaa980582010-01-23 23:04:36 +0000125 self.assertIn(
126 ('<dl><dt><a name="-add"><strong>add</strong></a>(x, y)</dt><dd>'
127 '<tt>Add&nbsp;two&nbsp;instances&nbsp;together.&nbsp;This&nbsp;'
128 'follows&nbsp;<a href="http://www.python.org/dev/peps/pep-0008/">'
129 'PEP008</a>,&nbsp;but&nbsp;has&nbsp;nothing<br>\nto&nbsp;do&nbsp;'
130 'with&nbsp;<a href="http://www.rfc-editor.org/rfc/rfc1952.txt">'
131 'RFC1952</a>.&nbsp;Case&nbsp;should&nbsp;matter:&nbsp;pEp008&nbsp;'
132 'and&nbsp;rFC1952.&nbsp;&nbsp;Things<br>\nthat&nbsp;start&nbsp;'
133 'with&nbsp;http&nbsp;and&nbsp;ftp&nbsp;should&nbsp;be&nbsp;'
134 'auto-linked,&nbsp;too:<br>\n<a href="http://google.com">'
135 'http://google.com</a>.</tt></dd></dl>'), response.read())
Georg Brandle6daafb2007-12-09 22:39:12 +0000136
137 def test_system_methods(self):
138 """Test the precense of three consecutive system.* methods.
139
140 This also tests their use of parameter type recognition and the systems
141 related to that process.
142 """
143 self.client.request("GET", "/")
144 response = self.client.getresponse()
145
Ezio Melottiaa980582010-01-23 23:04:36 +0000146 self.assertIn(
147 ('<dl><dt><a name="-system.listMethods"><strong>system.listMethods'
148 '</strong></a>()</dt><dd><tt><a href="#-system.listMethods">system'
149 '.listMethods</a>()&nbsp;=&gt;&nbsp;[\'add\',&nbsp;\'subtract\','
150 '&nbsp;\'multiple\']<br>\n&nbsp;<br>\nReturns&nbsp;a&nbsp;list'
151 '&nbsp;of&nbsp;the&nbsp;methods&nbsp;supported&nbsp;by&nbsp;the'
152 '&nbsp;server.</tt></dd></dl>\n <dl><dt><a name="-system.methodHelp">'
153 '<strong>system.methodHelp</strong></a>(method_name)</dt><dd><tt>'
154 '<a href="#-system.methodHelp">system.methodHelp</a>(\'add\')&nbsp;'
155 '=&gt;&nbsp;"Adds&nbsp;two&nbsp;integers&nbsp;together"<br>\n&nbsp;'
156 '<br>\nReturns&nbsp;a&nbsp;string&nbsp;containing&nbsp;documentation'
157 '&nbsp;for&nbsp;the&nbsp;specified&nbsp;method.</tt></dd></dl>\n '
158 '<dl><dt><a name="-system.methodSignature"><strong>system.'
159 'methodSignature</strong></a>(method_name)</dt><dd><tt><a href="#-'
160 'system.methodSignature">system.methodSignature</a>(\'add\')&nbsp;'
161 '=&gt;&nbsp;[double,&nbsp;int,&nbsp;int]<br>\n&nbsp;<br>\nReturns'
162 '&nbsp;a&nbsp;list&nbsp;describing&nbsp;the&nbsp;signature&nbsp;of'
163 '&nbsp;the&nbsp;method.&nbsp;In&nbsp;the<br>\nabove&nbsp;example,'
164 '&nbsp;the&nbsp;add&nbsp;method&nbsp;takes&nbsp;two&nbsp;integers'
165 '&nbsp;as&nbsp;arguments<br>\nand&nbsp;returns&nbsp;a&nbsp;double'
166 '&nbsp;result.<br>\n&nbsp;<br>\nThis&nbsp;server&nbsp;does&nbsp;'
167 'NOT&nbsp;support&nbsp;system.methodSignature.</tt></dd></dl>'),
168 response.read())
Georg Brandle6daafb2007-12-09 22:39:12 +0000169
170 def test_autolink_dotted_methods(self):
171 """Test that selfdot values are made strong automatically in the
172 documentation."""
173 self.client.request("GET", "/")
174 response = self.client.getresponse()
175
Ezio Melottiaa980582010-01-23 23:04:36 +0000176 self.assertIn("""Try&nbsp;self.<strong>add</strong>,&nbsp;too.""",
177 response.read())
Georg Brandle6daafb2007-12-09 22:39:12 +0000178
179def test_main():
180 test_support.run_unittest(DocXMLRPCHTTPGETServer)
181
182if __name__ == '__main__':
183 test_main()