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