~ubuntu-branches/ubuntu/trusty/python3.4/trusty-proposed

« back to all changes in this revision

Viewing changes to Lib/test/test_docxmlrpc.py

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2013-11-25 09:44:27 UTC
  • Revision ID: package-import@ubuntu.com-20131125094427-lzxj8ap5w01lmo7f
Tags: upstream-3.4~b1
ImportĀ upstreamĀ versionĀ 3.4~b1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
from xmlrpc.server import DocXMLRPCServer
 
2
import http.client
 
3
import sys
 
4
from test import support
 
5
threading = support.import_module('threading')
 
6
import time
 
7
import socket
 
8
import unittest
 
9
 
 
10
PORT = None
 
11
 
 
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.
 
15
    if not condition:
 
16
        return lambda func: func
 
17
    def decorator(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
 
23
    return decorator
 
24
 
 
25
 
 
26
def server(evt, numrequests):
 
27
    serv = DocXMLRPCServer(("localhost", 0), logRequests=False)
 
28
 
 
29
    try:
 
30
        global PORT
 
31
        PORT = serv.socket.getsockname()[1]
 
32
 
 
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.")
 
39
 
 
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."""
 
44
                self.arg = arg
 
45
 
 
46
        serv.register_introspection_functions()
 
47
        serv.register_instance(TestClass())
 
48
 
 
49
        def add(x, y):
 
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:
 
53
            http://google.com.
 
54
            """
 
55
            return x + y
 
56
 
 
57
        def annotation(x: int):
 
58
            """ Use function annotations. """
 
59
            return x
 
60
 
 
61
        class ClassWithAnnotation:
 
62
            def method_annotation(self, x: bytes):
 
63
                return x.decode()
 
64
 
 
65
        serv.register_function(add)
 
66
        serv.register_function(lambda x, y: x-y)
 
67
        serv.register_function(annotation)
 
68
        serv.register_instance(ClassWithAnnotation())
 
69
 
 
70
        while numrequests > 0:
 
71
            serv.handle_request()
 
72
            numrequests -= 1
 
73
    except socket.timeout:
 
74
        pass
 
75
    finally:
 
76
        serv.server_close()
 
77
        PORT = None
 
78
        evt.set()
 
79
 
 
80
class DocXMLRPCHTTPGETServer(unittest.TestCase):
 
81
    def setUp(self):
 
82
        self._threads = support.threading_setup()
 
83
        # Enable server feedback
 
84
        DocXMLRPCServer._send_traceback_header = True
 
85
 
 
86
        self.evt = threading.Event()
 
87
        threading.Thread(target=server, args=(self.evt, 1)).start()
 
88
 
 
89
        # wait for port to be assigned
 
90
        n = 1000
 
91
        while n > 0 and PORT is None:
 
92
            time.sleep(0.001)
 
93
            n -= 1
 
94
 
 
95
        self.client = http.client.HTTPConnection("localhost:%d" % PORT)
 
96
 
 
97
    def tearDown(self):
 
98
        self.client.close()
 
99
 
 
100
        self.evt.wait()
 
101
 
 
102
        # Disable server feedback
 
103
        DocXMLRPCServer._send_traceback_header = False
 
104
        support.threading_cleanup(*self._threads)
 
105
 
 
106
    def test_valid_get_response(self):
 
107
        self.client.request("GET", "/")
 
108
        response = self.client.getresponse()
 
109
 
 
110
        self.assertEqual(response.status, 200)
 
111
        self.assertEqual(response.getheader("Content-type"), "text/html")
 
112
 
 
113
        # Server raises an exception if we don't start to read the data
 
114
        response.read()
 
115
 
 
116
    def test_invalid_get_response(self):
 
117
        self.client.request("GET", "/spam")
 
118
        response = self.client.getresponse()
 
119
 
 
120
        self.assertEqual(response.status, 404)
 
121
        self.assertEqual(response.getheader("Content-type"), "text/plain")
 
122
 
 
123
        response.read()
 
124
 
 
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
 
128
        HTML, "<lambda>".
 
129
 
 
130
        The subtraction lambda method is tested.
 
131
        """
 
132
        self.client.request("GET", "/")
 
133
        response = self.client.getresponse()
 
134
 
 
135
        self.assertIn((b'<dl><dt><a name="-&lt;lambda&gt;"><strong>'
 
136
                       b'&lt;lambda&gt;</strong></a>(x, y)</dt></dl>'),
 
137
                      response.read())
 
138
 
 
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.
 
145
 
 
146
        The documentation for the "add" method contains the test material.
 
147
        """
 
148
        self.client.request("GET", "/")
 
149
        response = self.client.getresponse().read()
 
150
 
 
151
        self.assertIn(
 
152
            (b'<dl><dt><a name="-add"><strong>add</strong></a>(x, y)</dt><dd>'
 
153
             b'<tt>Add&nbsp;two&nbsp;instances&nbsp;together.&nbsp;This&nbsp;'
 
154
             b'follows&nbsp;<a href="http://www.python.org/dev/peps/pep-0008/">'
 
155
             b'PEP008</a>,&nbsp;but&nbsp;has&nbsp;nothing<br>\nto&nbsp;do&nbsp;'
 
156
             b'with&nbsp;<a href="http://www.rfc-editor.org/rfc/rfc1952.txt">'
 
157
             b'RFC1952</a>.&nbsp;Case&nbsp;should&nbsp;matter:&nbsp;pEp008&nbsp;'
 
158
             b'and&nbsp;rFC1952.&nbsp;&nbsp;Things<br>\nthat&nbsp;start&nbsp;'
 
159
             b'with&nbsp;http&nbsp;and&nbsp;ftp&nbsp;should&nbsp;be&nbsp;'
 
160
             b'auto-linked,&nbsp;too:<br>\n<a href="http://google.com">'
 
161
             b'http://google.com</a>.</tt></dd></dl>'), response)
 
162
 
 
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.
 
167
 
 
168
        This also tests their use of parameter type recognition and the
 
169
        systems related to that process.
 
170
        """
 
171
        self.client.request("GET", "/")
 
172
        response = self.client.getresponse().read()
 
173
 
 
174
        self.assertIn(
 
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\')&nbsp;=&gt;&nbsp;"Adds&nbsp;'
 
178
             b'two&nbsp;integers&nbsp;together"<br>\n&nbsp;<br>\nReturns&nbsp;a'
 
179
             b'&nbsp;string&nbsp;containing&nbsp;documentation&nbsp;for&nbsp;'
 
180
             b'the&nbsp;specified&nbsp;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\')&nbsp;=&gt;&nbsp;[double,&nbsp;'
 
184
             b'int,&nbsp;int]<br>\n&nbsp;<br>\nReturns&nbsp;a&nbsp;list&nbsp;'
 
185
             b'describing&nbsp;the&nbsp;signature&nbsp;of&nbsp;the&nbsp;method.'
 
186
             b'&nbsp;In&nbsp;the<br>\nabove&nbsp;example,&nbsp;the&nbsp;add&nbsp;'
 
187
             b'method&nbsp;takes&nbsp;two&nbsp;integers&nbsp;as&nbsp;arguments'
 
188
             b'<br>\nand&nbsp;returns&nbsp;a&nbsp;double&nbsp;result.<br>\n&nbsp;'
 
189
             b'<br>\nThis&nbsp;server&nbsp;does&nbsp;NOT&nbsp;support&nbsp;system'
 
190
             b'.methodSignature.</tt></dd></dl>'), response)
 
191
 
 
192
    def test_autolink_dotted_methods(self):
 
193
        """Test that selfdot values are made strong automatically in the
 
194
        documentation."""
 
195
        self.client.request("GET", "/")
 
196
        response = self.client.getresponse()
 
197
 
 
198
        self.assertIn(b"""Try&nbsp;self.<strong>add</strong>,&nbsp;too.""",
 
199
                      response.read())
 
200
 
 
201
    def test_annotations(self):
 
202
        """ Test that annotations works as expected """
 
203
        self.client.request("GET", "/")
 
204
        response = self.client.getresponse()
 
205
        self.assertIn(
 
206
            (b'<dl><dt><a name="-annotation"><strong>annotation</strong></a>'
 
207
             b'(x: int)</dt><dd><tt>Use&nbsp;function&nbsp;annotations.</tt>'
 
208
             b'</dd></dl>\n<dl><dt><a name="-method_annotation"><strong>'
 
209
             b'method_annotation</strong></a>(x: bytes)</dt></dl>'),
 
210
            response.read())
 
211
 
 
212
 
 
213
def test_main():
 
214
    support.run_unittest(DocXMLRPCHTTPGETServer)
 
215
 
 
216
if __name__ == '__main__':
 
217
    test_main()