blob: 13a3a9f83acfae0e82bc2f29dd7c90fc3bc88d53 [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 Brandl708c4872010-02-07 12:01:19 +00006import socket
Georg Brandle6daafb2007-12-09 22:39:12 +00007import unittest
8import xmlrpclib
9
10PORT = None
11
12def server(evt, numrequests):
Benjamin Petersonbe2c0a92008-10-04 21:33:08 +000013 serv = DocXMLRPCServer(("localhost", 0), logRequests=False)
Georg Brandle6daafb2007-12-09 22:39:12 +000014
Benjamin Petersonbe2c0a92008-10-04 21:33:08 +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(
23"""This is an XML-RPC server's documentation, but the server can be used by
24POSTing to /RPC2. Try self.add, too.""")
25
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):
58 # Enable server feedback
59 DocXMLRPCServer._send_traceback_header = True
60
61 self.evt = threading.Event()
62 threading.Thread(target=server, args=(self.evt, 1)).start()
63
64 # wait for port to be assigned
65 n = 1000
66 while n > 0 and PORT is None:
67 time.sleep(0.001)
68 n -= 1
69
70 self.client = httplib.HTTPConnection("localhost:%d" % PORT)
71
72 def tearDown(self):
73 self.client.close()
74
75 self.evt.wait()
76
77 # Disable server feedback
78 DocXMLRPCServer._send_traceback_header = False
79
80 def test_valid_get_response(self):
81 self.client.request("GET", "/")
82 response = self.client.getresponse()
83
84 self.assertEqual(response.status, 200)
85 self.assertEqual(response.getheader("Content-type"), "text/html")
86
87 # Server throws an exception if we don't start to read the data
88 response.read()
89
90 def test_invalid_get_response(self):
91 self.client.request("GET", "/spam")
92 response = self.client.getresponse()
93
94 self.assertEqual(response.status, 404)
95 self.assertEqual(response.getheader("Content-type"), "text/plain")
96
97 response.read()
98
99 def test_lambda(self):
100 """Test that lambda functionality stays the same. The output produced
101 currently is, I suspect invalid because of the unencoded brackets in the
102 HTML, "<lambda>".
103
104 The subtraction lambda method is tested.
105 """
106 self.client.request("GET", "/")
107 response = self.client.getresponse()
108
109 self.assert_(
110"""<dl><dt><a name="-&lt;lambda&gt;"><strong>&lt;lambda&gt;</strong></a>(x, y)</dt></dl>"""
111 in response.read())
112
113 def test_autolinking(self):
114 """Test that the server correctly automatically wraps references to PEPS
115 and RFCs with links, and that it linkifies text starting with http or
116 ftp protocol prefixes.
117
118 The documentation for the "add" method contains the test material.
119 """
120 self.client.request("GET", "/")
121 response = self.client.getresponse()
122
123 self.assert_( # This is ugly ... how can it be made better?
Andrew M. Kuchling8d119302008-02-07 11:43:47 +0000124"""<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>"""
Georg Brandle6daafb2007-12-09 22:39:12 +0000125 in response.read())
126
127 def test_system_methods(self):
128 """Test the precense of three consecutive system.* methods.
129
130 This also tests their use of parameter type recognition and the systems
131 related to that process.
132 """
133 self.client.request("GET", "/")
134 response = self.client.getresponse()
135
136 self.assert_(
137"""<dl><dt><a name="-system.listMethods"><strong>system.listMethods</strong></a>()</dt><dd><tt><a href="#-system.listMethods">system.listMethods</a>()&nbsp;=&gt;&nbsp;[\'add\',&nbsp;\'subtract\',&nbsp;\'multiple\']<br>\n&nbsp;<br>\nReturns&nbsp;a&nbsp;list&nbsp;of&nbsp;the&nbsp;methods&nbsp;supported&nbsp;by&nbsp;the&nbsp;server.</tt></dd></dl>\n <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>"""
138 in response.read())
139
140 def test_autolink_dotted_methods(self):
141 """Test that selfdot values are made strong automatically in the
142 documentation."""
143 self.client.request("GET", "/")
144 response = self.client.getresponse()
145
146 self.assert_("""Try&nbsp;self.<strong>add</strong>,&nbsp;too.""" in
147 response.read())
148
149def test_main():
150 test_support.run_unittest(DocXMLRPCHTTPGETServer)
151
152if __name__ == '__main__':
153 test_main()