/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
7290.38.1 by Jelmer Vernooij
Backport python3.8 support patch to breezy 3.0.
249
    if not getattr(cethread.CatchingExceptionThread, 'is_alive', None):
250
        def is_alive(self):
251
            return self.isAlive()
252
5560.1.2 by Vincent Ladeuil
Oops, remove debug value.
253
    def join(self, timeout=5):
5652.1.1 by Vincent Ladeuil
Split ThreadWithException out of the tests hierarchy.
254
        """Overrides to use a default timeout.
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
255
256
        The default timeout is set to 5 and should expire only when a thread
257
        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.
258
        """
5652.1.1 by Vincent Ladeuil
Split ThreadWithException out of the tests hierarchy.
259
        super(TestThread, self).join(timeout)
7290.38.1 by Jelmer Vernooij
Backport python3.8 support patch to breezy 3.0.
260
        if timeout and self.is_alive():
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
261
            # The timeout expired without joining the thread, the thread is
262
            # therefore stucked and that's a failure as far as the test is
263
            # 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.
264
265
            # FIXME: we need to kill the thread, but as far as the test is
266
            # concerned, raising an assertion is too strong. On most of the
267
            # platforms, this doesn't occur, so just mentioning the problem is
268
            # enough for now -- vila 2010824
269
            sys.stderr.write('thread %s hung\n' % (self.name,))
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
270
            # 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.
271
5247.2.2 by Vincent Ladeuil
Implement a thread that can re-raise exceptions.
272
6133.4.32 by John Arbash Meinel
Don't use server.socket.close() go through the server._close() abstraction.
273
class TestingTCPServerMixin(object):
6621.25.1 by Martin
Adapt to SocketServer module name change
274
    """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
275
276
    Tests are connecting from the main thread, the server has to be run in a
277
    separate thread.
278
    """
279
5247.5.32 by Vincent Ladeuil
Fix the sibling_class hack, we now know that we need only two methods
280
    def __init__(self):
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
281
        self.started = threading.Event()
5247.5.31 by Vincent Ladeuil
Use a boolean for server.serving, a threading.Event() is not needed here.
282
        self.serving = None
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
283
        self.stopped = threading.Event()
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
284
        # We collect the resources used by the clients so we can release them
285
        # when shutting down
286
        self.clients = []
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
287
        self.ignored_exceptions = None
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
288
5247.3.11 by Vincent Ladeuil
Start implementing the threading variants.
289
    def server_bind(self):
5247.5.32 by Vincent Ladeuil
Fix the sibling_class hack, we now know that we need only two methods
290
        self.socket.bind(self.server_address)
291
        self.server_address = self.socket.getsockname()
5247.3.11 by Vincent Ladeuil
Start implementing the threading variants.
292
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
293
    def serve(self):
5247.5.31 by Vincent Ladeuil
Use a boolean for server.serving, a threading.Event() is not needed here.
294
        self.serving = True
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
295
        # We are listening and ready to accept connections
296
        self.started.set()
5247.5.9 by Vincent Ladeuil
Use a better sync for test_exception_swallowed_while_serving test.
297
        try:
5247.5.31 by Vincent Ladeuil
Use a boolean for server.serving, a threading.Event() is not needed here.
298
            while self.serving:
5247.5.9 by Vincent Ladeuil
Use a better sync for test_exception_swallowed_while_serving test.
299
                # Really a connection but the python framework is generic and
300
                # call them requests
301
                self.handle_request()
302
            # Let's close the listening socket
303
            self.server_close()
304
        finally:
305
            self.stopped.set()
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
306
5247.5.10 by Vincent Ladeuil
Fix broken test.
307
    def handle_request(self):
308
        """Handle one request.
309
310
        The python version swallows some socket exceptions and we don't use
311
        timeout, so we override it to better control the server behavior.
312
        """
313
        request, client_address = self.get_request()
314
        if self.verify_request(request, client_address):
315
            try:
316
                self.process_request(request, client_address)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
317
            except BaseException:
5247.5.10 by Vincent Ladeuil
Fix broken test.
318
                self.handle_error(request, client_address)
6175.1.1 by John Arbash Meinel
Close the request when we don't process it.
319
        else:
320
            self.close_request(request)
5247.5.10 by Vincent Ladeuil
Fix broken test.
321
5247.5.32 by Vincent Ladeuil
Fix the sibling_class hack, we now know that we need only two methods
322
    def get_request(self):
323
        return self.socket.accept()
324
5247.3.9 by Vincent Ladeuil
Ensure a simple dialog can occur between a client and a server.
325
    def verify_request(self, request, client_address):
326
        """Verify the request.
327
328
        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.
329
        not even touch a single byte in the socket ! This is useful when we
330
        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.
331
        """
5247.5.31 by Vincent Ladeuil
Use a boolean for server.serving, a threading.Event() is not needed here.
332
        return self.serving
5247.3.9 by Vincent Ladeuil
Ensure a simple dialog can occur between a client and a server.
333
5247.3.10 by Vincent Ladeuil
Test errors during server life.
334
    def handle_error(self, request, client_address):
335
        # 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.
336
        self.serving = False
5247.6.8 by Vincent Ladeuil
Explain why we left some code commented: useful in rare debug cases.
337
        # The following can be used for debugging purposes, it will display the
338
        # exception and the traceback just when it occurs instead of waiting
339
        # for the thread to be joined.
6621.25.1 by Martin
Adapt to SocketServer module name change
340
        # socketserver.BaseServer.handle_error(self, request, client_address)
6175.1.6 by John Arbash Meinel
Separate the comments, for vila.
341
6175.1.1 by John Arbash Meinel
Close the request when we don't process it.
342
        # We call close_request manually, because we are going to raise an
6621.25.1 by Martin
Adapt to SocketServer module name change
343
        # exception. The socketserver implementation calls:
6175.1.1 by John Arbash Meinel
Close the request when we don't process it.
344
        #   handle_error(...)
345
        #   close_request(...)
346
        # But because we raise the exception, close_request will never be
347
        # triggered. This helps client not block waiting for a response when
348
        # the server gets an exception.
349
        self.close_request(request)
5247.3.10 by Vincent Ladeuil
Test errors during server life.
350
        raise
351
5247.5.7 by Vincent Ladeuil
Factor out socket exception handling during server shutdown.
352
    def ignored_exceptions_during_shutdown(self, e):
353
        if sys.platform == 'win32':
5247.2.40 by Vincent Ladeuil
Catch EPIPE during test server shutdown.
354
            accepted_errnos = [errno.EBADF,
355
                               errno.EPIPE,
356
                               errno.WSAEBADF,
357
                               errno.WSAECONNRESET,
358
                               errno.WSAENOTCONN,
359
                               errno.WSAESHUTDOWN,
360
                               ]
5247.5.7 by Vincent Ladeuil
Factor out socket exception handling during server shutdown.
361
        else:
5247.2.40 by Vincent Ladeuil
Catch EPIPE during test server shutdown.
362
            accepted_errnos = [errno.EBADF,
363
                               errno.ECONNRESET,
364
                               errno.ENOTCONN,
365
                               errno.EPIPE,
366
                               ]
6799 by Jelmer Vernooij
Merge lp:~jelmer/brz/escaping.
367
        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.
368
            return True
369
        return False
370
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
371
    # The following methods are called by the main thread
372
373
    def stop_client_connections(self):
374
        while self.clients:
375
            c = self.clients.pop()
376
            self.shutdown_client(c)
377
5247.5.9 by Vincent Ladeuil
Use a better sync for test_exception_swallowed_while_serving test.
378
    def shutdown_socket(self, sock):
379
        """Properly shutdown a socket.
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
380
381
        This should be called only when no other thread is trying to use the
382
        socket.
383
        """
384
        try:
385
            sock.shutdown(socket.SHUT_RDWR)
386
            sock.close()
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
387
        except Exception as e:
5247.5.7 by Vincent Ladeuil
Factor out socket exception handling during server shutdown.
388
            if self.ignored_exceptions(e):
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
389
                pass
390
            else:
391
                raise
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
392
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
393
    # The following methods are called by the main thread
394
395
    def set_ignored_exceptions(self, thread, ignored_exceptions):
396
        self.ignored_exceptions = ignored_exceptions
397
        thread.set_ignored_exceptions(self.ignored_exceptions)
398
399
    def _pending_exception(self, thread):
400
        """Raise server uncaught exception.
401
402
        Daughter classes can override this if they use daughter threads.
403
        """
404
        thread.pending_exception()
405
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
406
6621.25.1 by Martin
Adapt to SocketServer module name change
407
class TestingTCPServer(TestingTCPServerMixin, socketserver.TCPServer):
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
408
409
    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
410
        TestingTCPServerMixin.__init__(self)
6621.25.1 by Martin
Adapt to SocketServer module name change
411
        socketserver.TCPServer.__init__(self, server_address,
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
412
                                        request_handler_class)
413
414
    def get_request(self):
415
        """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
416
        sock, addr = TestingTCPServerMixin.get_request(self)
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
417
        self.clients.append((sock, addr))
418
        return sock, addr
419
420
    # The following methods are called by the main thread
421
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
422
    def shutdown_client(self, client):
423
        sock, addr = client
5247.5.9 by Vincent Ladeuil
Use a better sync for test_exception_swallowed_while_serving test.
424
        self.shutdown_socket(sock)
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
425
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
426
5247.3.11 by Vincent Ladeuil
Start implementing the threading variants.
427
class TestingThreadingTCPServer(TestingTCPServerMixin,
6621.25.1 by Martin
Adapt to SocketServer module name change
428
                                socketserver.ThreadingTCPServer):
5247.3.11 by Vincent Ladeuil
Start implementing the threading variants.
429
430
    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
431
        TestingTCPServerMixin.__init__(self)
6621.25.1 by Martin
Adapt to SocketServer module name change
432
        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
433
                                                 request_handler_class)
5247.3.11 by Vincent Ladeuil
Start implementing the threading variants.
434
6175.1.1 by John Arbash Meinel
Close the request when we don't process it.
435
    def get_request(self):
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
436
        """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
437
        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.
438
        # 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.
439
        self.clients.append((sock, addr, None))
440
        return sock, addr
441
6015.42.6 by Vincent Ladeuil
Ensures that the connection thread is detached from the server thread before handling the connection.
442
    def process_request_thread(self, started, detached, stopped,
443
                               request, client_address):
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
444
        started.set()
6015.42.6 by Vincent Ladeuil
Ensures that the connection thread is detached from the server thread before handling the connection.
445
        # We will be on our own once the server tells us we're detached
446
        detached.wait()
6621.25.1 by Martin
Adapt to SocketServer module name change
447
        socketserver.ThreadingTCPServer.process_request_thread(
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
448
            self, request, client_address)
449
        self.close_request(request)
450
        stopped.set()
451
452
    def process_request(self, request, client_address):
453
        """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.
454
        started = threading.Event()
6015.42.6 by Vincent Ladeuil
Ensures that the connection thread is detached from the server thread before handling the connection.
455
        detached = threading.Event()
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
456
        stopped = threading.Event()
5652.1.1 by Vincent Ladeuil
Split ThreadWithException out of the tests hierarchy.
457
        t = TestThread(
5652.1.2 by Vincent Ladeuil
Use clearer names.
458
            sync_event=stopped,
5247.5.17 by Vincent Ladeuil
Add some basic debug tracing controlled by -Ethreads.
459
            name='%s -> %s' % (client_address, self.server_address),
7143.15.2 by Jelmer Vernooij
Run autopep8.
460
            target=self.process_request_thread,
461
            args=(started, detached, stopped, request, client_address))
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
462
        # Update the client description
6133.4.18 by John Arbash Meinel
Revert debugging changes to test_server.py
463
        self.clients.pop()
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
464
        self.clients.append((request, client_address, t))
5560.1.5 by Vincent Ladeuil
Fix spelling mistake.
465
        # 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.
466
        # TestingTCPServer for connections running in their own threads.
6133.4.18 by John Arbash Meinel
Revert debugging changes to test_server.py
467
        t.set_ignored_exceptions(self.ignored_exceptions)
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
468
        t.start()
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
469
        started.wait()
470
        # If an exception occured during the thread start, it will get raised.
471
        t.pending_exception()
6015.42.6 by Vincent Ladeuil
Ensures that the connection thread is detached from the server thread before handling the connection.
472
        if debug_threads():
473
            sys.stderr.write('Client thread %s started\n' % (t.name,))
474
        # Tell the thread, it's now on its own for exception handling.
475
        detached.set()
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
476
477
    # The following methods are called by the main thread
478
479
    def shutdown_client(self, client):
5247.5.2 by Vincent Ladeuil
Cosmetic change.
480
        sock, addr, connection_thread = client
5247.5.9 by Vincent Ladeuil
Use a better sync for test_exception_swallowed_while_serving test.
481
        self.shutdown_socket(sock)
5247.5.2 by Vincent Ladeuil
Cosmetic change.
482
        if connection_thread is not None:
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
483
            # The thread has been created only if the request is processed but
484
            # after the connection is inited. This could happen during server
485
            # shutdown. If an exception occurred in the thread it will be
486
            # re-raised
5247.5.17 by Vincent Ladeuil
Add some basic debug tracing controlled by -Ethreads.
487
            if debug_threads():
5247.5.29 by Vincent Ladeuil
Fixed as per jam's review.
488
                sys.stderr.write('Client thread %s will be joined\n'
489
                                 % (connection_thread.name,))
5247.5.2 by Vincent Ladeuil
Cosmetic change.
490
            connection_thread.join()
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
491
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
492
    def set_ignored_exceptions(self, thread, ignored_exceptions):
493
        TestingTCPServerMixin.set_ignored_exceptions(self, thread,
494
                                                     ignored_exceptions)
495
        for sock, addr, connection_thread in self.clients:
496
            if connection_thread is not None:
497
                connection_thread.set_ignored_exceptions(
498
                    self.ignored_exceptions)
499
5247.5.3 by Vincent Ladeuil
Fix exception raising only once for a given ThreadWithException.
500
    def _pending_exception(self, thread):
501
        for sock, addr, connection_thread in self.clients:
502
            if connection_thread is not None:
503
                connection_thread.pending_exception()
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
504
        TestingTCPServerMixin._pending_exception(self, thread)
5247.5.3 by Vincent Ladeuil
Fix exception raising only once for a given ThreadWithException.
505
5247.3.11 by Vincent Ladeuil
Start implementing the threading variants.
506
5247.3.14 by Vincent Ladeuil
Use a proper load_tests.
507
class TestingTCPServerInAThread(transport.Server):
5247.3.11 by Vincent Ladeuil
Start implementing the threading variants.
508
    """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
509
510
    def __init__(self, server_address, server_class, request_handler_class):
511
        self.server_class = server_class
512
        self.request_handler_class = request_handler_class
5247.3.15 by Vincent Ladeuil
All http tests passing, https failing.
513
        self.host, self.port = server_address
5247.3.10 by Vincent Ladeuil
Test errors during server life.
514
        self.server = None
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
515
        self._server_thread = None
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
516
5247.3.14 by Vincent Ladeuil
Use a proper load_tests.
517
    def __repr__(self):
5247.3.15 by Vincent Ladeuil
All http tests passing, https failing.
518
        return "%s(%s:%s)" % (self.__class__.__name__, self.host, self.port)
5247.3.14 by Vincent Ladeuil
Use a proper load_tests.
519
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
520
    def create_server(self):
5247.3.15 by Vincent Ladeuil
All http tests passing, https failing.
521
        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
522
                                 self.request_handler_class)
523
524
    def start_server(self):
525
        self.server = self.create_server()
5652.1.1 by Vincent Ladeuil
Split ThreadWithException out of the tests hierarchy.
526
        self._server_thread = TestThread(
5652.1.2 by Vincent Ladeuil
Use clearer names.
527
            sync_event=self.server.started,
5247.5.17 by Vincent Ladeuil
Add some basic debug tracing controlled by -Ethreads.
528
            target=self.run_server)
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
529
        self._server_thread.start()
6015.42.1 by Vincent Ladeuil
Fix a naughty race in test_server_crash_while_responding
530
        # 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
531
        self.server.started.wait()
532
        # Get the real address, especially the port
5247.3.15 by Vincent Ladeuil
All http tests passing, https failing.
533
        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.
534
        self._server_thread.name = self.server.server_address
535
        if debug_threads():
5247.5.29 by Vincent Ladeuil
Fixed as per jam's review.
536
            sys.stderr.write('Server thread %s started\n'
537
                             % (self._server_thread.name,))
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
538
        # If an exception occured during the server start, it will get raised,
539
        # otherwise, the server is blocked on its accept() call.
540
        self._server_thread.pending_exception()
5247.3.10 by Vincent Ladeuil
Test errors during server life.
541
        # From now on, we'll use a different event to ensure the server can set
542
        # its exception
5652.1.2 by Vincent Ladeuil
Use clearer names.
543
        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
544
545
    def run_server(self):
546
        self.server.serve()
547
548
    def stop_server(self):
549
        if self.server is None:
550
            return
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
551
        try:
552
            # The server has been started successfully, shut it down now.  As
5247.5.10 by Vincent Ladeuil
Fix broken test.
553
            # soon as we stop serving, no more connection are accepted except
554
            # one to get out of the blocking listen.
5247.5.7 by Vincent Ladeuil
Factor out socket exception handling during server shutdown.
555
            self.set_ignored_exceptions(
556
                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.
557
            self.server.serving = False
5247.5.17 by Vincent Ladeuil
Add some basic debug tracing controlled by -Ethreads.
558
            if debug_threads():
5247.5.29 by Vincent Ladeuil
Fixed as per jam's review.
559
                sys.stderr.write('Server thread %s will be joined\n'
560
                                 % (self._server_thread.name,))
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
561
            # The server is listening for a last connection, let's give it:
562
            last_conn = None
563
            try:
5247.3.15 by Vincent Ladeuil
All http tests passing, https failing.
564
                last_conn = osutils.connect_socket((self.host, self.port))
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
565
            except socket.error:
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
566
                # But ignore connection errors as the point is to unblock the
567
                # server thread, it may happen that it's not blocked or even
568
                # not started.
6133.4.18 by John Arbash Meinel
Revert debugging changes to test_server.py
569
                pass
570
            # We start shutting down the clients while the server itself is
571
            # shutting down.
572
            self.server.stop_client_connections()
573
            # Now we wait for the thread running self.server.serve() to finish
574
            self.server.stopped.wait()
6133.4.8 by John Arbash Meinel
Refactor a bit. Use a common _wait_for_descriptor code.
575
            if last_conn is not None:
576
                # Close the last connection without trying to use it. The
577
                # server will not process a single byte on that socket to avoid
578
                # complications (SSL starts with a handshake for example).
579
                last_conn.close()
5247.3.10 by Vincent Ladeuil
Test errors during server life.
580
            # Check for any exception that could have occurred in the server
581
            # thread
5247.5.9 by Vincent Ladeuil
Use a better sync for test_exception_swallowed_while_serving test.
582
            try:
583
                self._server_thread.join()
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
584
            except Exception as e:
5247.5.9 by Vincent Ladeuil
Use a better sync for test_exception_swallowed_while_serving test.
585
                if self.server.ignored_exceptions(e):
586
                    pass
587
                else:
588
                    raise
5247.3.10 by Vincent Ladeuil
Test errors during server life.
589
        finally:
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
590
            # Make sure we can be called twice safely, note that this means
591
            # that we will raise a single exception even if several occurred in
592
            # the various threads involved.
5247.3.10 by Vincent Ladeuil
Test errors during server life.
593
            self.server = None
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
594
5247.5.4 by Vincent Ladeuil
Implement an execption handling mechanism that can be injected in ThreadWithException.
595
    def set_ignored_exceptions(self, ignored_exceptions):
596
        """Install an exception handler for the server."""
597
        self.server.set_ignored_exceptions(self._server_thread,
598
                                           ignored_exceptions)
599
5247.5.3 by Vincent Ladeuil
Fix exception raising only once for a given ThreadWithException.
600
    def pending_exception(self):
601
        """Raise uncaught exception in the server."""
602
        self.server._pending_exception(self._server_thread)
603
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
604
6621.25.1 by Martin
Adapt to SocketServer module name change
605
class TestingSmartConnectionHandler(socketserver.BaseRequestHandler,
5247.3.38 by Vincent Ladeuil
Fix the last remaining failures.
606
                                    medium.SmartServerSocketStreamMedium):
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
607
608
    def __init__(self, request, client_address, server):
609
        medium.SmartServerSocketStreamMedium.__init__(
610
            self, request, server.backing_transport,
6133.4.26 by John Arbash Meinel
get rid of the default timeout parameters.
611
            server.root_client_path,
612
            timeout=_DEFAULT_TESTING_CLIENT_TIMEOUT)
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
613
        request.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
6621.25.1 by Martin
Adapt to SocketServer module name change
614
        socketserver.BaseRequestHandler.__init__(self, request, client_address,
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
615
                                                 server)
616
617
    def handle(self):
6175.1.5 by John Arbash Meinel
Suppress ConnectionTimeout as a server-side exception.
618
        try:
619
            while not self.finished:
620
                server_protocol = self._build_protocol()
621
                self._serve_one_request(server_protocol)
622
        except errors.ConnectionTimeout:
623
            # idle connections aren't considered a failure of the server
624
            return
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
625
626
6404.6.3 by Vincent Ladeuil
Oops, remove debug setting.
627
_DEFAULT_TESTING_CLIENT_TIMEOUT = 60.0
6133.4.23 by John Arbash Meinel
Setup the TestingSmartServer to set a default client timeout,
628
7143.15.2 by Jelmer Vernooij
Run autopep8.
629
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
630
class TestingSmartServer(TestingThreadingTCPServer, server.SmartTCPServer):
631
632
    def __init__(self, server_address, request_handler_class,
633
                 backing_transport, root_client_path):
634
        TestingThreadingTCPServer.__init__(self, server_address,
635
                                           request_handler_class)
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
636
        server.SmartTCPServer.__init__(
637
            self, backing_transport,
638
            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,
639
5247.3.38 by Vincent Ladeuil
Fix the last remaining failures.
640
    def serve(self):
641
        self.run_server_started_hooks()
642
        try:
643
            TestingThreadingTCPServer.serve(self)
644
        finally:
645
            self.run_server_stopped_hooks()
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
646
647
    def get_url(self):
648
        """Return the url of the server"""
649
        return "bzr://%s:%d/" % self.server_address
650
651
652
class SmartTCPServer_for_testing(TestingTCPServerInAThread):
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
653
    """Server suitable for use by transport tests.
654
655
    This server is backed by the process's cwd.
656
    """
7143.15.2 by Jelmer Vernooij
Run autopep8.
657
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
658
    def __init__(self, thread_name_suffix=''):
659
        self.client_path_extra = None
660
        self.thread_name_suffix = thread_name_suffix
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
661
        self.host = '127.0.0.1'
662
        self.port = 0
663
        super(SmartTCPServer_for_testing, self).__init__(
7143.15.2 by Jelmer Vernooij
Run autopep8.
664
            (self.host, self.port),
665
            TestingSmartServer,
666
            TestingSmartConnectionHandler)
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
667
668
    def create_server(self):
669
        return self.server_class((self.host, self.port),
670
                                 self.request_handler_class,
671
                                 self.backing_transport,
672
                                 self.root_client_path)
673
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
674
    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.
675
                     client_path_extra='/extra/'):
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
676
        """Set up server for testing.
677
678
        :param backing_transport_server: backing server to use.  If not
679
            specified, a LocalURLServer at the current working directory will
680
            be used.
681
        :param client_path_extra: a path segment starting with '/' to append to
682
            the root URL for this server.  For instance, a value of '/foo/bar/'
683
            will mean the root of the backing transport will be published at a
684
            URL like `bzr://127.0.0.1:nnnn/foo/bar/`, rather than
685
            `bzr://127.0.0.1:nnnn/`.  Default value is `extra`, so that tests
686
            by default will fail unless they do the necessary path translation.
687
        """
688
        if not client_path_extra.startswith('/'):
689
            raise ValueError(client_path_extra)
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
690
        self.root_client_path = self.client_path_extra = client_path_extra
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
691
        from breezy.transport.chroot import ChrootServer
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
692
        if backing_transport_server is None:
693
            backing_transport_server = LocalURLServer()
694
        self.chroot_server = ChrootServer(
695
            self.get_backing_transport(backing_transport_server))
696
        self.chroot_server.start_server()
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
697
        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
698
            self.chroot_server.get_url())
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
699
        super(SmartTCPServer_for_testing, self).start_server()
700
5247.3.38 by Vincent Ladeuil
Fix the last remaining failures.
701
    def stop_server(self):
5247.3.40 by Vincent Ladeuil
Make sure the chroot server is shut down too.
702
        try:
703
            super(SmartTCPServer_for_testing, self).stop_server()
704
        finally:
705
            self.chroot_server.stop_server()
5247.3.38 by Vincent Ladeuil
Fix the last remaining failures.
706
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
707
    def get_backing_transport(self, backing_transport_server):
708
        """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.
709
        return transport.get_transport_from_url(
710
            backing_transport_server.get_url())
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
711
712
    def get_url(self):
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
713
        url = self.server.get_url()
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
714
        return url[:-1] + self.client_path_extra
715
716
    def get_bogus_url(self):
717
        """Return a URL which will fail to connect"""
718
        return 'bzr://127.0.0.1:1/'
719
720
721
class ReadonlySmartTCPServer_for_testing(SmartTCPServer_for_testing):
722
    """Get a readonly server for testing."""
723
724
    def get_backing_transport(self, backing_transport_server):
725
        """Get a backing transport from a server we are decorating."""
726
        url = 'readonly+' + backing_transport_server.get_url()
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
727
        return transport.get_transport_from_url(url)
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
728
729
730
class SmartTCPServer_for_testing_v2_only(SmartTCPServer_for_testing):
731
    """A variation of SmartTCPServer_for_testing that limits the client to
732
    using RPCs in protocol v2 (i.e. bzr <= 1.5).
733
    """
734
735
    def get_url(self):
736
        url = super(SmartTCPServer_for_testing_v2_only, self).get_url()
737
        url = 'bzr-v2://' + url[len('bzr://'):]
738
        return url
739
740
741
class ReadonlySmartTCPServer_for_testing_v2_only(
7143.15.2 by Jelmer Vernooij
Run autopep8.
742
        SmartTCPServer_for_testing_v2_only):
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
743
    """Get a readonly server for testing."""
744
745
    def get_backing_transport(self, backing_transport_server):
746
        """Get a backing transport from a server we are decorating."""
747
        url = 'readonly+' + backing_transport_server.get_url()
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
748
        return transport.get_transport_from_url(url)