from DocXMLRPCServer import DocXMLRPCServer import httplib from test import test_support import threading import time import unittest import xmlrpclib import socket PORT = None def server_inner(evt, numrequests): serv = DocXMLRPCServer(("localhost", 0), logRequests=False) try: global PORT PORT = serv.socket.getsockname()[1] # Add some documentation serv.set_server_title("DocXMLRPCServer Test Documentation") serv.set_server_name("DocXMLRPCServer Test Docs") serv.set_server_documentation( """This is an XML-RPC server's documentation, but the server can be used by POSTing to /RPC2. Try self.add, too.""") # Create and register classes and functions class TestClass(object): def test_method(self, arg): """Test method's docs. This method truly does very little.""" self.arg = arg serv.register_introspection_functions() serv.register_instance(TestClass()) def add(x, y): """Add two instances together. This follows PEP008, but has nothing to do with RFC1952. Case should matter: pEp008 and rFC1952. Things that start with http and ftp should be auto-linked, too: http://google.com. """ return x + y serv.register_function(add) serv.register_function(lambda x, y: x-y) while numrequests > 0: serv.handle_request() numrequests -= 1 except socket.timeout: pass finally: serv.server_close() PORT = None def server(evt, numrequests): try: try: return server_inner(evt, numrequests) except: import traceback traceback.print_exc() raise finally: evt.set() class DocXMLRPCHTTPGETServer(unittest.TestCase): def setUp(self): # Enable server feedback DocXMLRPCServer._send_traceback_header = True self.evt = threading.Event() threading.Thread(target=server, args=(self.evt, 1)).start() # wait for port to be assigned n = 1000 while n > 0 and PORT is None: time.sleep(0.001) n -= 1 self.client = httplib.HTTPConnection("localhost:%d" % PORT) def tearDown(self): self.client.close() self.evt.wait() # Disable server feedback DocXMLRPCServer._send_traceback_header = False def test_valid_get_response(self): self.client.request("GET", "/") response = self.client.getresponse() self.assertEqual(response.status, 200) self.assertEqual(response.getheader("Content-type"), "text/html") # Server throws an exception if we don't start to read the data response.read() def test_invalid_get_response(self): self.client.request("GET", "/spam") response = self.client.getresponse() self.assertEqual(response.status, 404) self.assertEqual(response.getheader("Content-type"), "text/plain") response.read() def test_lambda(self): """Test that lambda functionality stays the same. The output produced currently is, I suspect invalid because of the unencoded brackets in the HTML, "". The subtraction lambda method is tested. """ self.client.request("GET", "/") response = self.client.getresponse() self.assertTrue( """
<lambda>(x, y)
""" in response.read()) def test_autolinking(self): """Test that the server correctly automatically wraps references to PEPS and RFCs with links, and that it linkifies text starting with http or ftp protocol prefixes. The documentation for the "add" method contains the test material. """ self.client.request("GET", "/") response = self.client.getresponse() self.assertTrue( # This is ugly ... how can it be made better? """
add(x, y)
Add two instances together. This follows PEP008, but has nothing
\nto do with RFC1952. Case should matter: pEp008 and rFC1952.  Things
\nthat start with http and ftp should be auto-linked, too:
\nhttp://google.com.
""" in response.read()) def test_system_methods(self): """Test the precense of three consecutive system.* methods. This also tests their use of parameter type recognition and the systems related to that process. """ self.client.request("GET", "/") response = self.client.getresponse() self.assertTrue( """
system.listMethods()
system.listMethods() => [\'add\', \'subtract\', \'multiple\']
\n 
\nReturns a list of the methods supported by the server.
\n
system.methodHelp(method_name)
system.methodHelp(\'add\') => "Adds two integers together"
\n 
\nReturns a string containing documentation for the specified method.
\n
system.methodSignature(method_name)
system.methodSignature(\'add\') => [double, int, int]
\n 
\nReturns a list describing the signature of the method. In the
\nabove example, the add method takes two integers as arguments
\nand returns a double result.
\n 
\nThis server does NOT support system.methodSignature.
""" in response.read()) def test_autolink_dotted_methods(self): """Test that selfdot values are made strong automatically in the documentation.""" self.client.request("GET", "/") response = self.client.getresponse() self.assertTrue("""Try self.add, too.""" in response.read()) def test_main(): test_support.run_unittest(DocXMLRPCHTTPGETServer) if __name__ == '__main__': test_main()