/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
6404.6.4 by Vincent Ladeuil
Merge trunk resolving conflicts
1
# Copyright (C) 2010, 2011 Canonical Ltd
5017.3.1 by Vincent Ladeuil
Create a tests.test_server.TestServer class out of transport.Server (while retaining the later for some special non-tests usages).
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.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
17
import errno
5247.1.1 by Vincent Ladeuil
Merge previous attempt into current trunk
18
import socket
7479.2.1 by Jelmer Vernooij
Drop python2 support.
19
import socketserver
5247.2.2 by Vincent Ladeuil
Implement a thread that can re-raise exceptions.
20
import sys
21
import threading
5247.1.1 by Vincent Ladeuil
Merge previous attempt into current trunk
22
23
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
24
from breezy import (
5652.1.6 by Vincent Ladeuil
thread is already a python module, avoid confusion and use cethread instead.
25
    cethread,
6175.1.5 by John Arbash Meinel
Suppress ConnectionTimeout as a server-side exception.
26
    errors,
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
27
    osutils,
5017.3.1 by Vincent Ladeuil
Create a tests.test_server.TestServer class out of transport.Server (while retaining the later for some special non-tests usages).
28
    transport,
5017.3.15 by Vincent Ladeuil
Fix missing import.
29
    urlutils,
5017.3.1 by Vincent Ladeuil
Create a tests.test_server.TestServer class out of transport.Server (while retaining the later for some special non-tests usages).
30
    )
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
31
from breezy.transport import (
5017.3.20 by Vincent Ladeuil
Move TestingChrootServer to bzrlib.tests.test_server
32
    chroot,
5017.3.19 by Vincent Ladeuil
Move TestingPathFilteringServer to bzrlib.tests.test_server
33
    pathfilter,
34
    )
6670.4.16 by Jelmer Vernooij
Move smart to breezy.bzr.
35
from breezy.bzr.smart import (
5247.3.36 by Vincent Ladeuil
Start refactoring the smart server to control which thread it runs in.
36
    medium,
37
    server,
38
    )
5017.3.1 by Vincent Ladeuil
Create a tests.test_server.TestServer class out of transport.Server (while retaining the later for some special non-tests usages).
39
40
5247.5.17 by Vincent Ladeuil
Add some basic debug tracing controlled by -Ethreads.
41
def debug_threads():
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
42
    # FIXME: There is a dependency loop between breezy.tests and
43
    # breezy.tests.test_server that needs to be fixed. In the mean time
5247.5.17 by Vincent Ladeuil
Add some basic debug tracing controlled by -Ethreads.
44
    # defining this function is enough for our needs. -- vila 20100611
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
45
    from breezy import tests
5247.5.17 by Vincent Ladeuil
Add some basic debug tracing controlled by -Ethreads.
46
    return 'threads' in tests.selftest_debug_flags
47
48
5017.3.1 by Vincent Ladeuil
Create a tests.test_server.TestServer class out of transport.Server (while retaining the later for some special non-tests usages).
49
class TestServer(transport.Server):
50
    """A Transport Server dedicated to tests.
51
52
    The TestServer interface provides a server for a given transport. We use
53
    these servers as loopback testing tools. For any given transport the
54
    Servers it provides must either allow writing, or serve the contents
6619.3.26 by Martin
Fix fallout from 2to3 getcwdu transformation and other test uses
55
    of osutils.getcwd() at the time start_server is called.
5017.3.1 by Vincent Ladeuil
Create a tests.test_server.TestServer class out of transport.Server (while retaining the later for some special non-tests usages).
56
57
    Note that these are real servers - they must implement all the things
58
    that we want bzr transports to take advantage of.
59
    """
60
61
    def get_url(self):
62
        """Return a url for this server.
63
64
        If the transport does not represent a disk directory (i.e. it is
65
        a database like svn, or a memory only transport, it should return
66
        a connection to a newly established resource for this Server.
67
        Otherwise it should return a url that will provide access to the path
6619.3.26 by Martin
Fix fallout from 2to3 getcwdu transformation and other test uses
68
        that was osutils.getcwd() when start_server() was called.
5017.3.1 by Vincent Ladeuil
Create a tests.test_server.TestServer class out of transport.Server (while retaining the later for some special non-tests usages).
69
70
        Subsequent calls will return the same resource.
71
        """
72
        raise NotImplementedError
73
74
    def get_bogus_url(self):
75
        """Return a url for this protocol, that will fail to connect.
76
77
        This may raise NotImplementedError to indicate that this server cannot
78
        provide bogus urls.
79
        """
80
        raise NotImplementedError
81
82
5017.3.6 by Vincent Ladeuil
Fix some fallouts of moving test servers around.
83
class LocalURLServer(TestServer):
5017.3.3 by Vincent Ladeuil
Move LocalURLServer to bzrlib.tests.test_server
84
    """A pretend server for local transports, using file:// urls.
85
86
    Of course no actual server is required to access the local filesystem, so
87
    this just exists to tell the test code how to get to it.
88
    """
89
90
    def start_server(self):
91
        pass
92
93
    def get_url(self):
94
        """See Transport.Server.get_url."""
95
        return urlutils.local_path_to_url('')
96
97
5017.3.6 by Vincent Ladeuil
Fix some fallouts of moving test servers around.
98
class DecoratorServer(TestServer):
5017.3.2 by Vincent Ladeuil
Move DecoratorServer to test_server.py
99
    """Server for the TransportDecorator for testing with.
100
101
    To use this when subclassing TransportDecorator, override override the
102
    get_decorator_class method.
103
    """
104
105
    def start_server(self, server=None):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
106
        """See breezy.transport.Server.start_server.
5017.3.2 by Vincent Ladeuil
Move DecoratorServer to test_server.py
107
108
        :server: decorate the urls given by server. If not provided a
109
        LocalServer is created.
110
        """
111
        if server is not None:
112
            self._made_server = False
113
            self._server = server
114
        else:
115
            self._made_server = True
116
            self._server = LocalURLServer()
117
            self._server.start_server()
118
119
    def stop_server(self):
120
        if self._made_server:
121
            self._server.stop_server()
122
123
    def get_decorator_class(self):
124
        """Return the class of the decorators we should be constructing."""
125
        raise NotImplementedError(self.get_decorator_class)
126
127
    def get_url_prefix(self):
128
        """What URL prefix does this decorator produce?"""
129
        return self.get_decorator_class()._get_url_prefix()
130
131
    def get_bogus_url(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
132
        """See breezy.transport.Server.get_bogus_url."""
5017.3.2 by Vincent Ladeuil
Move DecoratorServer to test_server.py
133
        return self.get_url_prefix() + self._server.get_bogus_url()
134
135
    def get_url(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
136
        """See breezy.transport.Server.get_url."""
5017.3.2 by Vincent Ladeuil
Move DecoratorServer to test_server.py
137
        return self.get_url_prefix() + self._server.get_url()
138
139
5017.3.8 by Vincent Ladeuil
Move BrokenRenameServer to bzrlib.tests.test_server
140
class BrokenRenameServer(DecoratorServer):
141
    """Server for the BrokenRenameTransportDecorator for testing with."""
142
143
    def get_decorator_class(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
144
        from breezy.transport import brokenrename
5017.3.8 by Vincent Ladeuil
Move BrokenRenameServer to bzrlib.tests.test_server
145
        return brokenrename.BrokenRenameTransportDecorator
146
147
5017.3.7 by Vincent Ladeuil
Move FakeNFSServer to bzrlib.tests.test_server
148
class FakeNFSServer(DecoratorServer):
149
    """Server for the FakeNFSTransportDecorator for testing with."""
150
151
    def get_decorator_class(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
152
        from breezy.transport import fakenfs
5017.3.7 by Vincent Ladeuil
Move FakeNFSServer to bzrlib.tests.test_server
153
        return fakenfs.FakeNFSTransportDecorator
154
155
5017.3.9 by Vincent Ladeuil
Move FakeVFATServer to bzrlib.tests.test_server
156
class FakeVFATServer(DecoratorServer):
157
    """A server that suggests connections through FakeVFATTransportDecorator
158
159
    For use in testing.
160
    """
161
162
    def get_decorator_class(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
163
        from breezy.transport import fakevfat
5017.3.14 by Vincent Ladeuil
Fix some missing prefixes.
164
        return fakevfat.FakeVFATTransportDecorator
5017.3.9 by Vincent Ladeuil
Move FakeVFATServer to bzrlib.tests.test_server
165
166
5017.3.11 by Vincent Ladeuil
Move LogDecoratorServer to bzrlib.tests.test_server
167
class LogDecoratorServer(DecoratorServer):
168
    """Server for testing."""
169
170
    def get_decorator_class(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
171
        from breezy.transport import log
5017.3.11 by Vincent Ladeuil
Move LogDecoratorServer to bzrlib.tests.test_server
172
        return log.TransportLogDecorator
173
174
5017.3.12 by Vincent Ladeuil
Move NoSmartTransportServer to bzrlib.tests.test_server
175
class NoSmartTransportServer(DecoratorServer):
176
    """Server for the NoSmartTransportDecorator for testing with."""
177
178
    def get_decorator_class(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
179
        from breezy.transport import nosmart
5017.3.14 by Vincent Ladeuil
Fix some missing prefixes.
180
        return nosmart.NoSmartTransportDecorator
5017.3.12 by Vincent Ladeuil
Move NoSmartTransportServer to bzrlib.tests.test_server
181
182
5017.3.5 by Vincent Ladeuil
Move ReadonlyServer to bzrlib.tests.readonly
183
class ReadonlyServer(DecoratorServer):
184
    """Server for the ReadonlyTransportDecorator for testing with."""
185
186
    def get_decorator_class(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
187
        from breezy.transport import readonly
5017.3.5 by Vincent Ladeuil
Move ReadonlyServer to bzrlib.tests.readonly
188
        return readonly.ReadonlyTransportDecorator
189
190
5017.3.10 by Vincent Ladeuil
Move TraceServer to bzrlib.tests.test_server
191
class TraceServer(DecoratorServer):
192
    """Server for the TransportTraceDecorator for testing with."""
193
194
    def get_decorator_class(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
195
        from breezy.transport import trace
5017.3.14 by Vincent Ladeuil
Fix some missing prefixes.
196
        return trace.TransportTraceDecorator
5017.3.10 by Vincent Ladeuil
Move TraceServer to bzrlib.tests.test_server
197
198
5017.3.13 by Vincent Ladeuil
Move UnlistableServer to bzrlib.tests.test_server
199
class UnlistableServer(DecoratorServer):
200
    """Server for the UnlistableTransportDecorator for testing with."""
201
202
    def get_decorator_class(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
203
        from breezy.transport import unlistable
5017.3.13 by Vincent Ladeuil
Move UnlistableServer to bzrlib.tests.test_server
204
        return unlistable.UnlistableTransportDecorator
205
206
5017.3.19 by Vincent Ladeuil
Move TestingPathFilteringServer to bzrlib.tests.test_server
207
class TestingPathFilteringServer(pathfilter.PathFilteringServer):
208
209
    def __init__(self):
5017.3.20 by Vincent Ladeuil
Move TestingChrootServer to bzrlib.tests.test_server
210
        """TestingPathFilteringServer is not usable until start_server
211
        is called."""
5017.3.19 by Vincent Ladeuil
Move TestingPathFilteringServer to bzrlib.tests.test_server
212
213
    def start_server(self, backing_server=None):
214
        """Setup the Chroot on backing_server."""
215
        if backing_server is not None:
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
216
            self.backing_transport = transport.get_transport_from_url(
5017.3.19 by Vincent Ladeuil
Move TestingPathFilteringServer to bzrlib.tests.test_server
217
                backing_server.get_url())
218
        else:
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
219
            self.backing_transport = transport.get_transport_from_path('.')
5017.3.19 by Vincent Ladeuil
Move TestingPathFilteringServer to bzrlib.tests.test_server
220
        self.backing_transport.clone('added-by-filter').ensure_base()
221
        self.filter_func = lambda x: 'added-by-filter/' + x
222
        super(TestingPathFilteringServer, self).start_server()
223
5017.3.20 by Vincent Ladeuil
Move TestingChrootServer to bzrlib.tests.test_server
224
    def get_bogus_url(self):
225
        raise NotImplementedError
226
227
228
class TestingChrootServer(chroot.ChrootServer):
229
230
    def __init__(self):
231
        """TestingChrootServer is not usable until start_server is called."""
232
        super(TestingChrootServer, self).__init__(None)
233
234
    def start_server(self, backing_server=None):
235
        """Setup the Chroot on backing_server."""
236
        if backing_server is not None:
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
237
            self.backing_transport = transport.get_transport_from_url(
5017.3.20 by Vincent Ladeuil
Move TestingChrootServer to bzrlib.tests.test_server
238
                backing_server.get_url())
239
        else:
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
240
            self.backing_transport = transport.get_transport_from_path('.')
5017.3.20 by Vincent Ladeuil
Move TestingChrootServer to bzrlib.tests.test_server
241
        super(TestingChrootServer, self).start_server()
242
243
    def get_bogus_url(self):
244
        raise NotImplementedError
245
5017.3.19 by Vincent Ladeuil
Move TestingPathFilteringServer to bzrlib.tests.test_server
246
5652.1.6 by Vincent Ladeuil
thread is already a python module, avoid confusion and use cethread instead.
247
class TestThread(cethread.CatchingExceptionThread):
5247.2.2 by Vincent Ladeuil
Implement a thread that can re-raise exceptions.
248
5560.1.2 by Vincent Ladeuil
Oops, remove debug value.
249
    def join(self, timeout=5):
5652.1.1 by Vincent Ladeuil
Split ThreadWithException out of the tests hierarchy.
250
        """Overrides to use a default timeout.
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
251
252
        The default timeout is set to 5 and should expire only when a thread
253
        serving a client connection is hung.
5247.2.3 by Vincent Ladeuil
join(timeout=0) is useful to check for an exception without stopping the thread.
254
        """
5652.1.1 by Vincent Ladeuil
Split ThreadWithException out of the tests hierarchy.
255
        super(TestThread, self).join(timeout)
7290.38.1 by Jelmer Vernooij
Backport python3.8 support patch to breezy 3.0.
256
        if timeout and self.is_alive():
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
257
            # The timeout expired without joining the thread, the thread is
258
            # therefore stucked and that's a failure as far as the test is
259
            # concerned. We used to hang here.
5247.2.37 by Vincent Ladeuil
Don't make leaking tests fail on hung threads, there are only a few left.
260
261
            # FIXME: we need to kill the thread, but as far as the test is
262
            # concerned, raising an assertion is too strong. On most of the
263
            # platforms, this doesn't occur, so just mentioning the problem is
264
            # enough for now -- vila 2010824
265
            sys.stderr.write('thread %s hung\n' % (self.name,))
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
266
            # raise AssertionError('thread %s hung' % (self.name,))
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
267
5247.2.2 by Vincent Ladeuil
Implement a thread that can re-raise exceptions.
268
6133.4.32 by John Arbash Meinel
Don't use server.socket.close() go through the server._close() abstraction.
269
class TestingTCPServerMixin(object):
6621.25.1 by Martin
Adapt to SocketServer module name change
270
    """Mixin to support running socketserver.TCPServer in a thread.
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
271
272
    Tests are connecting from the main thread, the server has to be run in a
273
    separate thread.
274
    """
275
5247.5.32 by Vincent Ladeuil
Fix the sibling_class hack, we now know that we need only two methods
276
    def __init__(self):
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
277
        self.started = threading.Event()
5247.5.31 by Vincent Ladeuil
Use a boolean for server.serving, a threading.Event() is not needed here.
278
        self.serving = None
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
279
        self.stopped = threading.Event()
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
280
        # We collect the resources used by the clients so we can release them
281
        # when shutting down
282
        self.clients = []
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
283
        self.ignored_exceptions = None
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
284
5247.3.11 by Vincent Ladeuil
Start implementing the threading variants.
285
    def server_bind(self):
5247.5.32 by Vincent Ladeuil
Fix the sibling_class hack, we now know that we need only two methods
286
        self.socket.bind(self.server_address)
287
        self.server_address = self.socket.getsockname()
5247.3.11 by Vincent Ladeuil
Start implementing the threading variants.
288
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
289
    def serve(self):
5247.5.31 by Vincent Ladeuil
Use a boolean for server.serving, a threading.Event() is not needed here.
290
        self.serving = True
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
291
        # We are listening and ready to accept connections
292
        self.started.set()
5247.5.9 by Vincent Ladeuil
Use a better sync for test_exception_swallowed_while_serving test.
293
        try:
5247.5.31 by Vincent Ladeuil
Use a boolean for server.serving, a threading.Event() is not needed here.
294
            while self.serving:
5247.5.9 by Vincent Ladeuil
Use a better sync for test_exception_swallowed_while_serving test.
295
                # Really a connection but the python framework is generic and
296
                # call them requests
297
                self.handle_request()
298
            # Let's close the listening socket
299
            self.server_close()
300
        finally:
301
            self.stopped.set()
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
302
5247.5.10 by Vincent Ladeuil
Fix broken test.
303
    def handle_request(self):
304
        """Handle one request.
305
306
        The python version swallows some socket exceptions and we don't use
307
        timeout, so we override it to better control the server behavior.
308
        """
309
        request, client_address = self.get_request()
310
        if self.verify_request(request, client_address):
311
            try:
312
                self.process_request(request, client_address)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
313
            except BaseException:
5247.5.10 by Vincent Ladeuil
Fix broken test.
314
                self.handle_error(request, client_address)
6175.1.1 by John Arbash Meinel
Close the request when we don't process it.
315
        else:
316
            self.close_request(request)
5247.5.10 by Vincent Ladeuil
Fix broken test.
317
5247.5.32 by Vincent Ladeuil
Fix the sibling_class hack, we now know that we need only two methods
318
    def get_request(self):
319
        return self.socket.accept()
320
5247.3.9 by Vincent Ladeuil
Ensure a simple dialog can occur between a client and a server.
321
    def verify_request(self, request, client_address):
322
        """Verify the request.
323
324
        Return True if we should proceed with this request, False if we should
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
325
        not even touch a single byte in the socket ! This is useful when we
326
        stop the server with a dummy last connection.
5247.3.9 by Vincent Ladeuil
Ensure a simple dialog can occur between a client and a server.
327
        """
5247.5.31 by Vincent Ladeuil
Use a boolean for server.serving, a threading.Event() is not needed here.
328
        return self.serving
5247.3.9 by Vincent Ladeuil
Ensure a simple dialog can occur between a client and a server.
329
5247.3.10 by Vincent Ladeuil
Test errors during server life.
330
    def handle_error(self, request, client_address):
331
        # Stop serving and re-raise the last exception seen
5247.5.31 by Vincent Ladeuil
Use a boolean for server.serving, a threading.Event() is not needed here.
332
        self.serving = False
5247.6.8 by Vincent Ladeuil
Explain why we left some code commented: useful in rare debug cases.
333
        # The following can be used for debugging purposes, it will display the
334
        # exception and the traceback just when it occurs instead of waiting
335
        # for the thread to be joined.
6621.25.1 by Martin
Adapt to SocketServer module name change
336
        # socketserver.BaseServer.handle_error(self, request, client_address)
6175.1.6 by John Arbash Meinel
Separate the comments, for vila.
337
6175.1.1 by John Arbash Meinel
Close the request when we don't process it.
338
        # We call close_request manually, because we are going to raise an
6621.25.1 by Martin
Adapt to SocketServer module name change
339
        # exception. The socketserver implementation calls:
6175.1.1 by John Arbash Meinel
Close the request when we don't process it.
340
        #   handle_error(...)
341
        #   close_request(...)
342
        # But because we raise the exception, close_request will never be
343
        # triggered. This helps client not block waiting for a response when
344
        # the server gets an exception.
345
        self.close_request(request)
5247.3.10 by Vincent Ladeuil
Test errors during server life.
346
        raise
347
5247.5.7 by Vincent Ladeuil
Factor out socket exception handling during server shutdown.
348
    def ignored_exceptions_during_shutdown(self, e):
349
        if sys.platform == 'win32':
5247.2.40 by Vincent Ladeuil
Catch EPIPE during test server shutdown.
350
            accepted_errnos = [errno.EBADF,
351
                               errno.EPIPE,
352
                               errno.WSAEBADF,
353
                               errno.WSAECONNRESET,
354
                               errno.WSAENOTCONN,
355
                               errno.WSAESHUTDOWN,
356
                               ]
5247.5.7 by Vincent Ladeuil
Factor out socket exception handling during server shutdown.
357
        else:
5247.2.40 by Vincent Ladeuil
Catch EPIPE during test server shutdown.
358
            accepted_errnos = [errno.EBADF,
359
                               errno.ECONNRESET,
360
                               errno.ENOTCONN,
361
                               errno.EPIPE,
362
                               ]
6799 by Jelmer Vernooij
Merge lp:~jelmer/brz/escaping.
363
        if isinstance(e, socket.error) and e.errno in accepted_errnos:
5247.5.7 by Vincent Ladeuil
Factor out socket exception handling during server shutdown.
364
            return True
365
        return False
366
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
367
    # The following methods are called by the main thread
368
369
    def stop_client_connections(self):
370
        while self.clients:
371
            c = self.clients.pop()
372
            self.shutdown_client(c)
373
5247.5.9 by Vincent Ladeuil
Use a better sync for test_exception_swallowed_while_serving test.
374
    def shutdown_socket(self, sock):
375
        """Properly shutdown a socket.
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
376
377
        This should be called only when no other thread is trying to use the
378
        socket.
379
        """
380
        try:
381
            sock.shutdown(socket.SHUT_RDWR)
382
            sock.close()
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
383
        except Exception as e:
5247.5.7 by Vincent Ladeuil
Factor out socket exception handling during server shutdown.
384
            if self.ignored_exceptions(e):
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
385
                pass
386
            else:
387
                raise
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
388
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
389
    # The following methods are called by the main thread
390
391
    def set_ignored_exceptions(self, thread, ignored_exceptions):
392
        self.ignored_exceptions = ignored_exceptions
393
        thread.set_ignored_exceptions(self.ignored_exceptions)
394
395
    def _pending_exception(self, thread):
396
        """Raise server uncaught exception.
397
398
        Daughter classes can override this if they use daughter threads.
399
        """
400
        thread.pending_exception()
401
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
402
6621.25.1 by Martin
Adapt to SocketServer module name change
403
class TestingTCPServer(TestingTCPServerMixin, socketserver.TCPServer):
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
404
405
    def __init__(self, server_address, request_handler_class):
5247.5.32 by Vincent Ladeuil
Fix the sibling_class hack, we now know that we need only two methods
406
        TestingTCPServerMixin.__init__(self)
6621.25.1 by Martin
Adapt to SocketServer module name change
407
        socketserver.TCPServer.__init__(self, server_address,
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
408
                                        request_handler_class)
409
410
    def get_request(self):
411
        """Get the request and client address from the socket."""
5247.5.32 by Vincent Ladeuil
Fix the sibling_class hack, we now know that we need only two methods
412
        sock, addr = TestingTCPServerMixin.get_request(self)
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
413
        self.clients.append((sock, addr))
414
        return sock, addr
415
416
    # The following methods are called by the main thread
417
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
418
    def shutdown_client(self, client):
419
        sock, addr = client
5247.5.9 by Vincent Ladeuil
Use a better sync for test_exception_swallowed_while_serving test.
420
        self.shutdown_socket(sock)
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
421
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
422
5247.3.11 by Vincent Ladeuil
Start implementing the threading variants.
423
class TestingThreadingTCPServer(TestingTCPServerMixin,
6621.25.1 by Martin
Adapt to SocketServer module name change
424
                                socketserver.ThreadingTCPServer):
5247.3.11 by Vincent Ladeuil
Start implementing the threading variants.
425
426
    def __init__(self, server_address, request_handler_class):
5247.5.32 by Vincent Ladeuil
Fix the sibling_class hack, we now know that we need only two methods
427
        TestingTCPServerMixin.__init__(self)
6621.25.1 by Martin
Adapt to SocketServer module name change
428
        socketserver.ThreadingTCPServer.__init__(self, server_address,
5247.5.32 by Vincent Ladeuil
Fix the sibling_class hack, we now know that we need only two methods
429
                                                 request_handler_class)
5247.3.11 by Vincent Ladeuil
Start implementing the threading variants.
430
6175.1.1 by John Arbash Meinel
Close the request when we don't process it.
431
    def get_request(self):
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
432
        """Get the request and client address from the socket."""
5247.5.32 by Vincent Ladeuil
Fix the sibling_class hack, we now know that we need only two methods
433
        sock, addr = TestingTCPServerMixin.get_request(self)
6015.42.6 by Vincent Ladeuil
Ensures that the connection thread is detached from the server thread before handling the connection.
434
        # The thread is not created yet, it will be updated in process_request
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
435
        self.clients.append((sock, addr, None))
436
        return sock, addr
437
6015.42.6 by Vincent Ladeuil
Ensures that the connection thread is detached from the server thread before handling the connection.
438
    def process_request_thread(self, started, detached, stopped,
439
                               request, client_address):
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
440
        started.set()
6015.42.6 by Vincent Ladeuil
Ensures that the connection thread is detached from the server thread before handling the connection.
441
        # We will be on our own once the server tells us we're detached
442
        detached.wait()
6621.25.1 by Martin
Adapt to SocketServer module name change
443
        socketserver.ThreadingTCPServer.process_request_thread(
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
444
            self, request, client_address)
445
        self.close_request(request)
446
        stopped.set()
447
448
    def process_request(self, request, client_address):
449
        """Start a new thread to process the request."""
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
450
        started = threading.Event()
6015.42.6 by Vincent Ladeuil
Ensures that the connection thread is detached from the server thread before handling the connection.
451
        detached = threading.Event()
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
452
        stopped = threading.Event()
5652.1.1 by Vincent Ladeuil
Split ThreadWithException out of the tests hierarchy.
453
        t = TestThread(
5652.1.2 by Vincent Ladeuil
Use clearer names.
454
            sync_event=stopped,
5247.5.17 by Vincent Ladeuil
Add some basic debug tracing controlled by -Ethreads.
455
            name='%s -> %s' % (client_address, self.server_address),
7143.15.2 by Jelmer Vernooij
Run autopep8.
456
            target=self.process_request_thread,
457
            args=(started, detached, stopped, request, client_address))
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
458
        # Update the client description
6133.4.18 by John Arbash Meinel
Revert debugging changes to test_server.py
459
        self.clients.pop()
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
460
        self.clients.append((request, client_address, t))
5560.1.5 by Vincent Ladeuil
Fix spelling mistake.
461
        # Propagate the exception handler since we must use the same one as
5560.1.1 by Vincent Ladeuil
Catch the bogus ssl exception for closed sockets.
462
        # TestingTCPServer for connections running in their own threads.
6133.4.18 by John Arbash Meinel
Revert debugging changes to test_server.py
463
        t.set_ignored_exceptions(self.ignored_exceptions)
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
464
        t.start()
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
465
        started.wait()
466
        # If an exception occured during the thread start, it will get raised.
467
        t.pending_exception()
6015.42.6 by Vincent Ladeuil
Ensures that the connection thread is detached from the server thread before handling the connection.
468
        if debug_threads():
469
            sys.stderr.write('Client thread %s started\n' % (t.name,))
470
        # Tell the thread, it's now on its own for exception handling.
471
        detached.set()
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
472
473
    # The following methods are called by the main thread
474
475
    def shutdown_client(self, client):
5247.5.2 by Vincent Ladeuil
Cosmetic change.
476
        sock, addr, connection_thread = client
5247.5.9 by Vincent Ladeuil
Use a better sync for test_exception_swallowed_while_serving test.
477
        self.shutdown_socket(sock)
5247.5.2 by Vincent Ladeuil
Cosmetic change.
478
        if connection_thread is not None:
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
479
            # The thread has been created only if the request is processed but
480
            # after the connection is inited. This could happen during server
481
            # shutdown. If an exception occurred in the thread it will be
482
            # re-raised
5247.5.17 by Vincent Ladeuil
Add some basic debug tracing controlled by -Ethreads.
483
            if debug_threads():
5247.5.29 by Vincent Ladeuil
Fixed as per jam's review.
484
                sys.stderr.write('Client thread %s will be joined\n'
485
                                 % (connection_thread.name,))
5247.5.2 by Vincent Ladeuil
Cosmetic change.
486
            connection_thread.join()
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
487
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
488
    def set_ignored_exceptions(self, thread, ignored_exceptions):
489
        TestingTCPServerMixin.set_ignored_exceptions(self, thread,
490
                                                     ignored_exceptions)
491
        for sock, addr, connection_thread in self.clients:
492
            if connection_thread is not None:
493
                connection_thread.set_ignored_exceptions(
494
                    self.ignored_exceptions)
495
5247.5.3 by Vincent Ladeuil
Fix exception raising only once for a given ThreadWithException.
496
    def _pending_exception(self, thread):
497
        for sock, addr, connection_thread in self.clients:
498
            if connection_thread is not None:
499
                connection_thread.pending_exception()
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
500
        TestingTCPServerMixin._pending_exception(self, thread)
5247.5.3 by Vincent Ladeuil
Fix exception raising only once for a given ThreadWithException.
501
5247.3.11 by Vincent Ladeuil
Start implementing the threading variants.
502
5247.3.14 by Vincent Ladeuil
Use a proper load_tests.
503
class TestingTCPServerInAThread(transport.Server):
5247.3.11 by Vincent Ladeuil
Start implementing the threading variants.
504
    """A server in a thread that re-raise thread exceptions."""
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
505
506
    def __init__(self, server_address, server_class, request_handler_class):
507
        self.server_class = server_class
508
        self.request_handler_class = request_handler_class
5247.3.15 by Vincent Ladeuil
All http tests passing, https failing.
509
        self.host, self.port = server_address
5247.3.10 by Vincent Ladeuil
Test errors during server life.
510
        self.server = None
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
511
        self._server_thread = None
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
512
5247.3.14 by Vincent Ladeuil
Use a proper load_tests.
513
    def __repr__(self):
5247.3.15 by Vincent Ladeuil
All http tests passing, https failing.
514
        return "%s(%s:%s)" % (self.__class__.__name__, self.host, self.port)
5247.3.14 by Vincent Ladeuil
Use a proper load_tests.
515
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
516
    def create_server(self):
5247.3.15 by Vincent Ladeuil
All http tests passing, https failing.
517
        return self.server_class((self.host, self.port),
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
518
                                 self.request_handler_class)
519
520
    def start_server(self):
521
        self.server = self.create_server()
5652.1.1 by Vincent Ladeuil
Split ThreadWithException out of the tests hierarchy.
522
        self._server_thread = TestThread(
5652.1.2 by Vincent Ladeuil
Use clearer names.
523
            sync_event=self.server.started,
5247.5.17 by Vincent Ladeuil
Add some basic debug tracing controlled by -Ethreads.
524
            target=self.run_server)
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
525
        self._server_thread.start()
6015.42.1 by Vincent Ladeuil
Fix a naughty race in test_server_crash_while_responding
526
        # Wait for the server thread to start (i.e. release the lock)
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
527
        self.server.started.wait()
528
        # Get the real address, especially the port
5247.3.15 by Vincent Ladeuil
All http tests passing, https failing.
529
        self.host, self.port = self.server.server_address
5247.5.18 by Vincent Ladeuil
Compatibility with python 2.5 and 2.4 for ThreadWithException.name.
530
        self._server_thread.name = self.server.server_address
531
        if debug_threads():
5247.5.29 by Vincent Ladeuil
Fixed as per jam's review.
532
            sys.stderr.write('Server thread %s started\n'
533
                             % (self._server_thread.name,))
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
534
        # If an exception occured during the server start, it will get raised,
535
        # otherwise, the server is blocked on its accept() call.
536
        self._server_thread.pending_exception()
5247.3.10 by Vincent Ladeuil
Test errors during server life.
537
        # From now on, we'll use a different event to ensure the server can set
538
        # its exception
5652.1.2 by Vincent Ladeuil
Use clearer names.
539
        self._server_thread.set_sync_event(self.server.stopped)
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
540
541
    def run_server(self):
542
        self.server.serve()
543
544
    def stop_server(self):
545
        if self.server is None:
546
            return
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
547
        try:
548
            # The server has been started successfully, shut it down now.  As
5247.5.10 by Vincent Ladeuil
Fix broken test.
549
            # soon as we stop serving, no more connection are accepted except
550
            # one to get out of the blocking listen.
5247.5.7 by Vincent Ladeuil
Factor out socket exception handling during server shutdown.
551
            self.set_ignored_exceptions(
552
                self.server.ignored_exceptions_during_shutdown)
5247.5.31 by Vincent Ladeuil
Use a boolean for server.serving, a threading.Event() is not needed here.
553
            self.server.serving = False
5247.5.17 by Vincent Ladeuil
Add some basic debug tracing controlled by -Ethreads.
554
            if debug_threads():
5247.5.29 by Vincent Ladeuil
Fixed as per jam's review.
555
                sys.stderr.write('Server thread %s will be joined\n'
556
                                 % (self._server_thread.name,))
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
557
            # The server is listening for a last connection, let's give it:
558
            last_conn = None
559
            try:
5247.3.15 by Vincent Ladeuil
All http tests passing, https failing.
560
                last_conn = osutils.connect_socket((self.host, self.port))
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
561
            except socket.error:
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
562
                # But ignore connection errors as the point is to unblock the
563
                # server thread, it may happen that it's not blocked or even
564
                # not started.
6133.4.18 by John Arbash Meinel
Revert debugging changes to test_server.py
565
                pass
566
            # We start shutting down the clients while the server itself is
567
            # shutting down.
568
            self.server.stop_client_connections()
569
            # Now we wait for the thread running self.server.serve() to finish
570
            self.server.stopped.wait()
6133.4.8 by John Arbash Meinel
Refactor a bit. Use a common _wait_for_descriptor code.
571
            if last_conn is not None:
572
                # Close the last connection without trying to use it. The
573
                # server will not process a single byte on that socket to avoid
574
                # complications (SSL starts with a handshake for example).
575
                last_conn.close()
5247.3.10 by Vincent Ladeuil
Test errors during server life.
576
            # Check for any exception that could have occurred in the server
577
            # thread
5247.5.9 by Vincent Ladeuil
Use a better sync for test_exception_swallowed_while_serving test.
578
            try:
579
                self._server_thread.join()
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
580
            except Exception as e:
5247.5.9 by Vincent Ladeuil
Use a better sync for test_exception_swallowed_while_serving test.
581
                if self.server.ignored_exceptions(e):
582
                    pass
583
                else:
584
                    raise
5247.3.10 by Vincent Ladeuil
Test errors during server life.
585
        finally:
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
586
            # Make sure we can be called twice safely, note that this means
587
            # that we will raise a single exception even if several occurred in
588
            # the various threads involved.
5247.3.10 by Vincent Ladeuil
Test errors during server life.
589
            self.server = None
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
590
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
591
    def set_ignored_exceptions(self, ignored_exceptions):
592
        """Install an exception handler for the server."""
593
        self.server.set_ignored_exceptions(self._server_thread,
594
                                           ignored_exceptions)
595
5247.5.3 by Vincent Ladeuil
Fix exception raising only once for a given ThreadWithException.
596
    def pending_exception(self):
597
        """Raise uncaught exception in the server."""
598
        self.server._pending_exception(self._server_thread)
599
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
600
6621.25.1 by Martin
Adapt to SocketServer module name change
601
class TestingSmartConnectionHandler(socketserver.BaseRequestHandler,
5247.3.38 by Vincent Ladeuil
Fix the last remaining failures.
602
                                    medium.SmartServerSocketStreamMedium):
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
603
604
    def __init__(self, request, client_address, server):
605
        medium.SmartServerSocketStreamMedium.__init__(
606
            self, request, server.backing_transport,
6133.4.26 by John Arbash Meinel
get rid of the default timeout parameters.
607
            server.root_client_path,
608
            timeout=_DEFAULT_TESTING_CLIENT_TIMEOUT)
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
609
        request.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
6621.25.1 by Martin
Adapt to SocketServer module name change
610
        socketserver.BaseRequestHandler.__init__(self, request, client_address,
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
611
                                                 server)
612
613
    def handle(self):
6175.1.5 by John Arbash Meinel
Suppress ConnectionTimeout as a server-side exception.
614
        try:
615
            while not self.finished:
616
                server_protocol = self._build_protocol()
617
                self._serve_one_request(server_protocol)
618
        except errors.ConnectionTimeout:
619
            # idle connections aren't considered a failure of the server
620
            return
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
621
622
6404.6.3 by Vincent Ladeuil
Oops, remove debug setting.
623
_DEFAULT_TESTING_CLIENT_TIMEOUT = 60.0
6133.4.23 by John Arbash Meinel
Setup the TestingSmartServer to set a default client timeout,
624
7143.15.2 by Jelmer Vernooij
Run autopep8.
625
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
626
class TestingSmartServer(TestingThreadingTCPServer, server.SmartTCPServer):
627
628
    def __init__(self, server_address, request_handler_class,
629
                 backing_transport, root_client_path):
630
        TestingThreadingTCPServer.__init__(self, server_address,
631
                                           request_handler_class)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
632
        server.SmartTCPServer.__init__(
633
            self, backing_transport,
634
            root_client_path, client_timeout=_DEFAULT_TESTING_CLIENT_TIMEOUT)
6133.4.23 by John Arbash Meinel
Setup the TestingSmartServer to set a default client timeout,
635
5247.3.38 by Vincent Ladeuil
Fix the last remaining failures.
636
    def serve(self):
637
        self.run_server_started_hooks()
638
        try:
639
            TestingThreadingTCPServer.serve(self)
640
        finally:
641
            self.run_server_stopped_hooks()
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
642
643
    def get_url(self):
644
        """Return the url of the server"""
645
        return "bzr://%s:%d/" % self.server_address
646
647
648
class SmartTCPServer_for_testing(TestingTCPServerInAThread):
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
649
    """Server suitable for use by transport tests.
650
651
    This server is backed by the process's cwd.
652
    """
7143.15.2 by Jelmer Vernooij
Run autopep8.
653
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
654
    def __init__(self, thread_name_suffix=''):
655
        self.client_path_extra = None
656
        self.thread_name_suffix = thread_name_suffix
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
657
        self.host = '127.0.0.1'
658
        self.port = 0
659
        super(SmartTCPServer_for_testing, self).__init__(
7143.15.2 by Jelmer Vernooij
Run autopep8.
660
            (self.host, self.port),
661
            TestingSmartServer,
662
            TestingSmartConnectionHandler)
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
663
664
    def create_server(self):
665
        return self.server_class((self.host, self.port),
666
                                 self.request_handler_class,
667
                                 self.backing_transport,
668
                                 self.root_client_path)
669
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
670
    def start_server(self, backing_transport_server=None,
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
671
                     client_path_extra='/extra/'):
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
672
        """Set up server for testing.
673
674
        :param backing_transport_server: backing server to use.  If not
675
            specified, a LocalURLServer at the current working directory will
676
            be used.
677
        :param client_path_extra: a path segment starting with '/' to append to
678
            the root URL for this server.  For instance, a value of '/foo/bar/'
679
            will mean the root of the backing transport will be published at a
680
            URL like `bzr://127.0.0.1:nnnn/foo/bar/`, rather than
681
            `bzr://127.0.0.1:nnnn/`.  Default value is `extra`, so that tests
682
            by default will fail unless they do the necessary path translation.
683
        """
684
        if not client_path_extra.startswith('/'):
685
            raise ValueError(client_path_extra)
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
686
        self.root_client_path = self.client_path_extra = client_path_extra
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
687
        from breezy.transport.chroot import ChrootServer
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
688
        if backing_transport_server is None:
689
            backing_transport_server = LocalURLServer()
690
        self.chroot_server = ChrootServer(
691
            self.get_backing_transport(backing_transport_server))
692
        self.chroot_server.start_server()
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
693
        self.backing_transport = transport.get_transport_from_url(
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
694
            self.chroot_server.get_url())
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
695
        super(SmartTCPServer_for_testing, self).start_server()
696
5247.3.38 by Vincent Ladeuil
Fix the last remaining failures.
697
    def stop_server(self):
5247.3.40 by Vincent Ladeuil
Make sure the chroot server is shut down too.
698
        try:
699
            super(SmartTCPServer_for_testing, self).stop_server()
700
        finally:
701
            self.chroot_server.stop_server()
5247.3.38 by Vincent Ladeuil
Fix the last remaining failures.
702
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
703
    def get_backing_transport(self, backing_transport_server):
704
        """Get a backing transport from a server we are decorating."""
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
705
        return transport.get_transport_from_url(
706
            backing_transport_server.get_url())
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
707
708
    def get_url(self):
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
709
        url = self.server.get_url()
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
710
        return url[:-1] + self.client_path_extra
711
712
    def get_bogus_url(self):
713
        """Return a URL which will fail to connect"""
714
        return 'bzr://127.0.0.1:1/'
715
716
717
class ReadonlySmartTCPServer_for_testing(SmartTCPServer_for_testing):
718
    """Get a readonly server for testing."""
719
720
    def get_backing_transport(self, backing_transport_server):
721
        """Get a backing transport from a server we are decorating."""
722
        url = 'readonly+' + backing_transport_server.get_url()
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
723
        return transport.get_transport_from_url(url)
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
724
725
726
class SmartTCPServer_for_testing_v2_only(SmartTCPServer_for_testing):
727
    """A variation of SmartTCPServer_for_testing that limits the client to
728
    using RPCs in protocol v2 (i.e. bzr <= 1.5).
729
    """
730
731
    def get_url(self):
732
        url = super(SmartTCPServer_for_testing_v2_only, self).get_url()
733
        url = 'bzr-v2://' + url[len('bzr://'):]
734
        return url
735
736
737
class ReadonlySmartTCPServer_for_testing_v2_only(
7143.15.2 by Jelmer Vernooij
Run autopep8.
738
        SmartTCPServer_for_testing_v2_only):
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
739
    """Get a readonly server for testing."""
740
741
    def get_backing_transport(self, backing_transport_server):
742
        """Get a backing transport from a server we are decorating."""
743
        url = 'readonly+' + backing_transport_server.get_url()
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
744
        return transport.get_transport_from_url(url)