/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1
# Copyright (C) 2010, 2011, 2016 Canonical Ltd
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
5247.3.10 by Vincent Ladeuil
Test errors during server life.
17
import errno
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
18
import socket
6621.25.1 by Martin
Adapt to SocketServer module name change
19
try:
20
    import socketserver
21
except ImportError:
22
    import SocketServer as socketserver
5247.5.3 by Vincent Ladeuil
Fix exception raising only once for a given ThreadWithException.
23
import threading
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
24
6175.1.1 by John Arbash Meinel
Close the request when we don't process it.
25
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
26
from breezy import (
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
27
    osutils,
28
    tests,
29
    )
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
30
from breezy.tests import test_server
31
from breezy.tests.scenarios import load_tests_apply_scenarios
5559.2.2 by Martin Pool
Change to using standard load_tests_apply_scenarios.
32
33
34
load_tests = load_tests_apply_scenarios
5247.3.14 by Vincent Ladeuil
Use a proper load_tests.
35
36
6175.1.5 by John Arbash Meinel
Suppress ConnectionTimeout as a server-side exception.
37
def portable_socket_pair():
38
    """Return a pair of TCP sockets connected to each other.
39
40
    Unlike socket.socketpair, this should work on Windows.
41
    """
42
    listen_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
43
    listen_sock.bind(('127.0.0.1', 0))
44
    listen_sock.listen(1)
45
    client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
46
    client_sock.connect(listen_sock.getsockname())
47
    server_sock, addr = listen_sock.accept()
48
    listen_sock.close()
49
    return server_sock, client_sock
50
51
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
52
class TCPClient(object):
53
54
    def __init__(self):
55
        self.sock = None
56
57
    def connect(self, addr):
5247.3.9 by Vincent Ladeuil
Ensure a simple dialog can occur between a client and a server.
58
        if self.sock is not None:
59
            raise AssertionError('Already connected to %r'
60
                                 % (self.sock.getsockname(),))
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
61
        self.sock = osutils.connect_socket(addr)
62
63
    def disconnect(self):
64
        if self.sock is not None:
5247.3.10 by Vincent Ladeuil
Test errors during server life.
65
            try:
66
                self.sock.shutdown(socket.SHUT_RDWR)
67
                self.sock.close()
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
68
            except socket.error as e:
7121.1.1 by Jelmer Vernooij
Cope with the server being really quick with its disconnects.
69
                if e.errno in (errno.EBADF, errno.ENOTCONN, errno.ECONNRESET):
5247.3.10 by Vincent Ladeuil
Test errors during server life.
70
                    # Right, the socket is already down
71
                    pass
72
                else:
73
                    raise
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
74
            self.sock = None
75
5247.3.9 by Vincent Ladeuil
Ensure a simple dialog can occur between a client and a server.
76
    def write(self, s):
77
        return self.sock.sendall(s)
78
79
    def read(self, bufsize=4096):
80
        return self.sock.recv(bufsize)
81
82
6621.25.1 by Martin
Adapt to SocketServer module name change
83
class TCPConnectionHandler(socketserver.BaseRequestHandler):
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
84
85
    def handle(self):
5247.3.9 by Vincent Ladeuil
Ensure a simple dialog can occur between a client and a server.
86
        self.done = False
87
        self.handle_connection()
88
        while not self.done:
89
            self.handle_connection()
90
6175.1.2 by John Arbash Meinel
Change the TCPConnectionHandler to inherit from BaseRequestHandler.
91
    def readline(self):
92
        # TODO: We should be buffering any extra data sent, etc. However, in
93
        #       practice, we don't send extra content, so we haven't bothered
94
        #       to implement it yet.
95
        req = self.request.recv(4096)
96
        # An empty string is allowed, to indicate the end of the connection
6973.7.5 by Jelmer Vernooij
s/file/open.
97
        if not req or (req.endswith(b'\n') and req.count(b'\n') == 1):
6175.1.2 by John Arbash Meinel
Change the TCPConnectionHandler to inherit from BaseRequestHandler.
98
            return req
99
        raise ValueError('[%r] not a simple line' % (req,))
100
5247.3.9 by Vincent Ladeuil
Ensure a simple dialog can occur between a client and a server.
101
    def handle_connection(self):
6175.1.2 by John Arbash Meinel
Change the TCPConnectionHandler to inherit from BaseRequestHandler.
102
        req = self.readline()
5247.3.9 by Vincent Ladeuil
Ensure a simple dialog can occur between a client and a server.
103
        if not req:
104
            self.done = True
6973.7.5 by Jelmer Vernooij
s/file/open.
105
        elif req == b'ping\n':
106
            self.request.sendall(b'pong\n')
5247.3.9 by Vincent Ladeuil
Ensure a simple dialog can occur between a client and a server.
107
        else:
108
            raise ValueError('[%s] not understood' % req)
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
109
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
110
111
class TestTCPServerInAThread(tests.TestCase):
112
6133.4.23 by John Arbash Meinel
Setup the TestingSmartServer to set a default client timeout,
113
    scenarios = [
5559.2.2 by Martin Pool
Change to using standard load_tests_apply_scenarios.
114
        (name, {'server_class': getattr(test_server, name)})
115
        for name in
116
        ('TestingTCPServer', 'TestingThreadingTCPServer')]
117
5247.3.10 by Vincent Ladeuil
Test errors during server life.
118
    def get_server(self, server_class=None, connection_handler_class=None):
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
119
        if server_class is not None:
120
            self.server_class = server_class
5247.3.10 by Vincent Ladeuil
Test errors during server life.
121
        if connection_handler_class is None:
122
            connection_handler_class = TCPConnectionHandler
6175.1.1 by John Arbash Meinel
Close the request when we don't process it.
123
        server = test_server.TestingTCPServerInAThread(
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
124
            ('localhost', 0), self.server_class, connection_handler_class)
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
125
        server.start_server()
126
        self.addCleanup(server.stop_server)
5247.3.9 by Vincent Ladeuil
Ensure a simple dialog can occur between a client and a server.
127
        return server
128
129
    def get_client(self):
130
        client = TCPClient()
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
131
        self.addCleanup(client.disconnect)
5247.3.9 by Vincent Ladeuil
Ensure a simple dialog can occur between a client and a server.
132
        return client
133
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
134
    def get_server_connection(self, server, conn_rank):
135
        return server.server.clients[conn_rank]
136
137
    def assertClientAddr(self, client, server, conn_rank):
138
        conn = self.get_server_connection(server, conn_rank)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
139
        self.assertEqual(client.sock.getsockname(), conn[1])
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
140
5247.3.9 by Vincent Ladeuil
Ensure a simple dialog can occur between a client and a server.
141
    def test_start_stop(self):
142
        server = self.get_server()
143
        client = self.get_client()
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
144
        server.stop_server()
145
        # since the server doesn't accept connections anymore attempting to
146
        # connect should fail
5247.3.9 by Vincent Ladeuil
Ensure a simple dialog can occur between a client and a server.
147
        client = self.get_client()
5247.3.18 by Vincent Ladeuil
Fix some fallouts from previous fixes, all tests passing (no more http leaks).
148
        self.assertRaises(socket.error,
149
                          client.connect, (server.host, server.port))
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
150
5247.3.9 by Vincent Ladeuil
Ensure a simple dialog can occur between a client and a server.
151
    def test_client_talks_server_respond(self):
152
        server = self.get_server()
153
        client = self.get_client()
5247.3.18 by Vincent Ladeuil
Fix some fallouts from previous fixes, all tests passing (no more http leaks).
154
        client.connect((server.host, server.port))
6973.7.5 by Jelmer Vernooij
s/file/open.
155
        self.assertIs(None, client.write(b'ping\n'))
5247.3.9 by Vincent Ladeuil
Ensure a simple dialog can occur between a client and a server.
156
        resp = client.read()
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
157
        self.assertClientAddr(client, server, 0)
6973.7.5 by Jelmer Vernooij
s/file/open.
158
        self.assertEqual(b'pong\n', resp)
5247.3.10 by Vincent Ladeuil
Test errors during server life.
159
160
    def test_server_fails_to_start(self):
161
        class CantStart(Exception):
162
            pass
163
164
        class CantStartServer(test_server.TestingTCPServer):
165
166
            def server_bind(self):
167
                raise CantStart()
168
169
        # The exception is raised in the main thread
170
        self.assertRaises(CantStart,
171
                          self.get_server, server_class=CantStartServer)
172
5247.5.10 by Vincent Ladeuil
Fix broken test.
173
    def test_server_fails_while_serving_or_stopping(self):
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
174
        class CantConnect(Exception):
5247.3.10 by Vincent Ladeuil
Test errors during server life.
175
            pass
176
6175.1.2 by John Arbash Meinel
Change the TCPConnectionHandler to inherit from BaseRequestHandler.
177
        class FailingConnectionHandler(TCPConnectionHandler):
5247.3.10 by Vincent Ladeuil
Test errors during server life.
178
179
            def handle(self):
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
180
                raise CantConnect()
5247.3.10 by Vincent Ladeuil
Test errors during server life.
181
182
        server = self.get_server(
183
            connection_handler_class=FailingConnectionHandler)
184
        # The server won't fail until a client connect
185
        client = self.get_client()
5247.3.18 by Vincent Ladeuil
Fix some fallouts from previous fixes, all tests passing (no more http leaks).
186
        client.connect((server.host, server.port))
6175.1.1 by John Arbash Meinel
Close the request when we don't process it.
187
        # We make sure the server wants to handle a request, but the request is
188
        # guaranteed to fail. However, the server should make sure that the
189
        # connection gets closed, and stop_server should then raise the
190
        # original exception.
6973.7.5 by Jelmer Vernooij
s/file/open.
191
        client.write(b'ping\n')
5247.3.10 by Vincent Ladeuil
Test errors during server life.
192
        try:
6973.7.5 by Jelmer Vernooij
s/file/open.
193
            self.assertEqual(b'', client.read())
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
194
        except socket.error as e:
6175.1.3 by John Arbash Meinel
Restrict the socket errors we will suppress.
195
            # On Windows, failing during 'handle' means we get
196
            # 'forced-close-of-connection'. Possibly because we haven't
197
            # processed the write request before we close the socket.
198
            WSAECONNRESET = 10054
199
            if e.errno in (WSAECONNRESET,):
200
                pass
5247.5.9 by Vincent Ladeuil
Use a better sync for test_exception_swallowed_while_serving test.
201
        # Now the server has raised the exception in its own thread
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
202
        self.assertRaises(CantConnect, server.stop_server)
5247.3.11 by Vincent Ladeuil
Start implementing the threading variants.
203
5247.5.3 by Vincent Ladeuil
Fix exception raising only once for a given ThreadWithException.
204
    def test_server_crash_while_responding(self):
6015.42.4 by Vincent Ladeuil
Less code, more explanations.
205
        # We want to ensure the exception has been caught
6015.42.2 by Vincent Ladeuil
One race can hide another... the exception may pass from the connection thread to the server thread so both need to be checked, with care.
206
        caught = threading.Event()
207
        caught.clear()
6015.42.4 by Vincent Ladeuil
Less code, more explanations.
208
        # The thread that will serve the client, this needs to be an attribute
209
        # so the handler below can modify it when it's executed (it's
210
        # instantiated when the request is processed)
6015.42.1 by Vincent Ladeuil
Fix a naughty race in test_server_crash_while_responding
211
        self.connection_thread = None
6015.42.4 by Vincent Ladeuil
Less code, more explanations.
212
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
213
        class FailToRespond(Exception):
5247.5.3 by Vincent Ladeuil
Fix exception raising only once for a given ThreadWithException.
214
            pass
215
216
        class FailingDuringResponseHandler(TCPConnectionHandler):
217
6015.42.5 by Vincent Ladeuil
More comments after review discussions.
218
            # We use 'request' instead of 'self' below because the test matters
219
            # more and we need a container to properly set connection_thread.
6015.42.2 by Vincent Ladeuil
One race can hide another... the exception may pass from the connection thread to the server thread so both need to be checked, with care.
220
            def handle_connection(request):
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
221
                request.readline()
6015.42.2 by Vincent Ladeuil
One race can hide another... the exception may pass from the connection thread to the server thread so both need to be checked, with care.
222
                # Capture the thread and make it use 'caught' so we can wait on
6015.42.5 by Vincent Ladeuil
More comments after review discussions.
223
                # the event that will be set when the exception is caught. We
6015.42.4 by Vincent Ladeuil
Less code, more explanations.
224
                # also capture the thread to know where to look.
6015.42.2 by Vincent Ladeuil
One race can hide another... the exception may pass from the connection thread to the server thread so both need to be checked, with care.
225
                self.connection_thread = threading.currentThread()
226
                self.connection_thread.set_sync_event(caught)
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
227
                raise FailToRespond()
5247.5.3 by Vincent Ladeuil
Fix exception raising only once for a given ThreadWithException.
228
229
        server = self.get_server(
230
            connection_handler_class=FailingDuringResponseHandler)
231
        client = self.get_client()
5247.3.21 by Vincent Ladeuil
Merge propagate-exceptions into http-leaks
232
        client.connect((server.host, server.port))
6973.7.5 by Jelmer Vernooij
s/file/open.
233
        client.write(b'ping\n')
6015.42.2 by Vincent Ladeuil
One race can hide another... the exception may pass from the connection thread to the server thread so both need to be checked, with care.
234
        # Wait for the exception to be caught
235
        caught.wait()
7143.15.2 by Jelmer Vernooij
Run autopep8.
236
        self.assertEqual(b'', client.read())  # connection closed
6015.42.1 by Vincent Ladeuil
Fix a naughty race in test_server_crash_while_responding
237
        # Check that the connection thread did catch the exception,
238
        # http://pad.lv/869366 was wrongly checking the server thread which
239
        # works for TestingTCPServer where the connection is handled in the
6015.42.6 by Vincent Ladeuil
Ensures that the connection thread is detached from the server thread before handling the connection.
240
        # same thread than the server one but was racy for
6015.42.7 by Vincent Ladeuil
Fix typo.
241
        # TestingThreadingTCPServer. Since the connection thread detaches
6015.42.6 by Vincent Ladeuil
Ensures that the connection thread is detached from the server thread before handling the connection.
242
        # itself before handling the request, we are guaranteed that the
243
        # exception won't leak into the server thread anymore.
244
        self.assertRaises(FailToRespond,
245
                          self.connection_thread.pending_exception)
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
246
247
    def test_exception_swallowed_while_serving(self):
6015.42.2 by Vincent Ladeuil
One race can hide another... the exception may pass from the connection thread to the server thread so both need to be checked, with care.
248
        # We need to ensure the exception has been caught
249
        caught = threading.Event()
250
        caught.clear()
6015.42.4 by Vincent Ladeuil
Less code, more explanations.
251
        # The thread that will serve the client, this needs to be an attribute
252
        # so the handler below can access it when it's executed (it's
253
        # instantiated when the request is processed)
6015.42.1 by Vincent Ladeuil
Fix a naughty race in test_server_crash_while_responding
254
        self.connection_thread = None
7143.15.2 by Jelmer Vernooij
Run autopep8.
255
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
256
        class CantServe(Exception):
257
            pass
258
259
        class FailingWhileServingConnectionHandler(TCPConnectionHandler):
260
6015.42.5 by Vincent Ladeuil
More comments after review discussions.
261
            # We use 'request' instead of 'self' below because the test matters
262
            # more and we need a container to properly set connection_thread.
6015.42.1 by Vincent Ladeuil
Fix a naughty race in test_server_crash_while_responding
263
            def handle(request):
6015.42.2 by Vincent Ladeuil
One race can hide another... the exception may pass from the connection thread to the server thread so both need to be checked, with care.
264
                # Capture the thread and make it use 'caught' so we can wait on
6015.42.5 by Vincent Ladeuil
More comments after review discussions.
265
                # the event that will be set when the exception is caught. We
6015.42.4 by Vincent Ladeuil
Less code, more explanations.
266
                # also capture the thread to know where to look.
6015.42.2 by Vincent Ladeuil
One race can hide another... the exception may pass from the connection thread to the server thread so both need to be checked, with care.
267
                self.connection_thread = threading.currentThread()
268
                self.connection_thread.set_sync_event(caught)
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
269
                raise CantServe()
270
271
        server = self.get_server(
272
            connection_handler_class=FailingWhileServingConnectionHandler)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
273
        self.assertEqual(True, server.server.serving)
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
274
        # Install the exception swallower
275
        server.set_ignored_exceptions(CantServe)
276
        client = self.get_client()
5247.5.9 by Vincent Ladeuil
Use a better sync for test_exception_swallowed_while_serving test.
277
        # Connect to the server so the exception is raised there
5247.3.21 by Vincent Ladeuil
Merge propagate-exceptions into http-leaks
278
        client.connect((server.host, server.port))
6015.42.2 by Vincent Ladeuil
One race can hide another... the exception may pass from the connection thread to the server thread so both need to be checked, with care.
279
        # Wait for the exception to be caught
280
        caught.wait()
7143.15.2 by Jelmer Vernooij
Run autopep8.
281
        self.assertEqual(b'', client.read())  # connection closed
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
282
        # The connection wasn't served properly but the exception should have
6015.42.1 by Vincent Ladeuil
Fix a naughty race in test_server_crash_while_responding
283
        # been swallowed (see test_server_crash_while_responding remark about
284
        # http://pad.lv/869366 explaining why we can't check the server thread
6015.42.2 by Vincent Ladeuil
One race can hide another... the exception may pass from the connection thread to the server thread so both need to be checked, with care.
285
        # here). More precisely, the exception *has* been caught and captured
286
        # but it is cleared when joining the thread (or trying to acquire the
287
        # exception) and as such won't propagate to the server thread.
6015.42.5 by Vincent Ladeuil
More comments after review discussions.
288
        self.assertIs(None, self.connection_thread.pending_exception())
289
        self.assertIs(None, server.pending_exception())
6133.4.23 by John Arbash Meinel
Setup the TestingSmartServer to set a default client timeout,
290
6175.1.1 by John Arbash Meinel
Close the request when we don't process it.
291
    def test_handle_request_closes_if_it_doesnt_process(self):
292
        server = self.get_server()
293
        client = self.get_client()
294
        server.server.serving = False
7121.1.1 by Jelmer Vernooij
Cope with the server being really quick with its disconnects.
295
        try:
296
            client.connect((server.host, server.port))
297
            self.assertEqual(b'', client.read())
298
        except socket.error as e:
299
            if e.errno != errno.ECONNRESET:
300
                raise
6175.1.1 by John Arbash Meinel
Close the request when we don't process it.
301
6133.4.23 by John Arbash Meinel
Setup the TestingSmartServer to set a default client timeout,
302
303
class TestTestingSmartServer(tests.TestCase):
304
305
    def test_sets_client_timeout(self):
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
306
        server = test_server.TestingSmartServer(
307
            ('localhost', 0), None, None,
308
            root_client_path='/no-such-client/path')
6133.4.23 by John Arbash Meinel
Setup the TestingSmartServer to set a default client timeout,
309
        self.assertEqual(test_server._DEFAULT_TESTING_CLIENT_TIMEOUT,
310
                         server._client_timeout)
311
        sock = socket.socket()
6133.4.24 by John Arbash Meinel
Change the name from _create_handler to _make_handler, to match similar code in the file.
312
        h = server._make_handler(sock)
6133.4.23 by John Arbash Meinel
Setup the TestingSmartServer to set a default client timeout,
313
        self.assertEqual(test_server._DEFAULT_TESTING_CLIENT_TIMEOUT,
314
                         h._client_timeout)
6175.1.5 by John Arbash Meinel
Suppress ConnectionTimeout as a server-side exception.
315
316
317
class FakeServer(object):
318
    """Minimal implementation to pass to TestingSmartConnectionHandler"""
319
    backing_transport = None
320
    root_client_path = '/'
321
322
323
class TestTestingSmartConnectionHandler(tests.TestCase):
324
325
    def test_connection_timeout_suppressed(self):
326
        self.overrideAttr(test_server, '_DEFAULT_TESTING_CLIENT_TIMEOUT', 0.01)
327
        s = FakeServer()
328
        server_sock, client_sock = portable_socket_pair()
329
        # This should timeout quickly, but not generate an exception.
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
330
        test_server.TestingSmartConnectionHandler(
331
            server_sock, server_sock.getpeername(), s)
6175.1.5 by John Arbash Meinel
Suppress ConnectionTimeout as a server-side exception.
332
333
    def test_connection_shutdown_while_serving_no_error(self):
334
        s = FakeServer()
335
        server_sock, client_sock = portable_socket_pair()
7143.15.2 by Jelmer Vernooij
Run autopep8.
336
6175.1.5 by John Arbash Meinel
Suppress ConnectionTimeout as a server-side exception.
337
        class ShutdownConnectionHandler(
7143.15.2 by Jelmer Vernooij
Run autopep8.
338
                test_server.TestingSmartConnectionHandler):
6175.1.5 by John Arbash Meinel
Suppress ConnectionTimeout as a server-side exception.
339
340
            def _build_protocol(self):
341
                self.finished = True
342
                return super(ShutdownConnectionHandler, self)._build_protocol()
343
        # This should trigger shutdown after the entering _build_protocol, and
344
        # we should exit cleanly, without raising an exception.
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
345
        ShutdownConnectionHandler(server_sock, server_sock.getpeername(), s)