/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
6175.1.1 by John Arbash Meinel
Close the request when we don't process it.
25
import traceback
5247.1.1 by Vincent Ladeuil
Merge previous attempt into current trunk
26
27
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
28
from breezy import (
5652.1.6 by Vincent Ladeuil
thread is already a python module, avoid confusion and use cethread instead.
29
    cethread,
6175.1.5 by John Arbash Meinel
Suppress ConnectionTimeout as a server-side exception.
30
    errors,
5247.3.8 by Vincent Ladeuil
Start implementing a TCP server running in its own thread (using
31
    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).
32
    transport,
5017.3.15 by Vincent Ladeuil
Fix missing import.
33
    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).
34
    )
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
35
from breezy.transport import (
5017.3.20 by Vincent Ladeuil
Move TestingChrootServer to bzrlib.tests.test_server
36
    chroot,
5017.3.19 by Vincent Ladeuil
Move TestingPathFilteringServer to bzrlib.tests.test_server
37
    pathfilter,
38
    )
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
39
from breezy.smart import (
5247.3.36 by Vincent Ladeuil
Start refactoring the smart server to control which thread it runs in.
40
    medium,
41
    server,
42
    )
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).
43
44
5247.5.17 by Vincent Ladeuil
Add some basic debug tracing controlled by -Ethreads.
45
def debug_threads():
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
46
    # FIXME: There is a dependency loop between breezy.tests and
47
    # 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.
48
    # defining this function is enough for our needs. -- vila 20100611
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
49
    from breezy import tests
5247.5.17 by Vincent Ladeuil
Add some basic debug tracing controlled by -Ethreads.
50
    return 'threads' in tests.selftest_debug_flags
51
52
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).
53
class TestServer(transport.Server):
54
    """A Transport Server dedicated to tests.
55
56
    The TestServer interface provides a server for a given transport. We use
57
    these servers as loopback testing tools. For any given transport the
58
    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
59
    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).
60
61
    Note that these are real servers - they must implement all the things
62
    that we want bzr transports to take advantage of.
63
    """
64
65
    def get_url(self):
66
        """Return a url for this server.
67
68
        If the transport does not represent a disk directory (i.e. it is
69
        a database like svn, or a memory only transport, it should return
70
        a connection to a newly established resource for this Server.
71
        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
72
        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).
73
74
        Subsequent calls will return the same resource.
75
        """
76
        raise NotImplementedError
77
78
    def get_bogus_url(self):
79
        """Return a url for this protocol, that will fail to connect.
80
81
        This may raise NotImplementedError to indicate that this server cannot
82
        provide bogus urls.
83
        """
84
        raise NotImplementedError
85
86
5017.3.6 by Vincent Ladeuil
Fix some fallouts of moving test servers around.
87
class LocalURLServer(TestServer):
5017.3.3 by Vincent Ladeuil
Move LocalURLServer to bzrlib.tests.test_server
88
    """A pretend server for local transports, using file:// urls.
89
90
    Of course no actual server is required to access the local filesystem, so
91
    this just exists to tell the test code how to get to it.
92
    """
93
94
    def start_server(self):
95
        pass
96
97
    def get_url(self):
98
        """See Transport.Server.get_url."""
99
        return urlutils.local_path_to_url('')
100
101
5017.3.6 by Vincent Ladeuil
Fix some fallouts of moving test servers around.
102
class DecoratorServer(TestServer):
5017.3.2 by Vincent Ladeuil
Move DecoratorServer to test_server.py
103
    """Server for the TransportDecorator for testing with.
104
105
    To use this when subclassing TransportDecorator, override override the
106
    get_decorator_class method.
107
    """
108
109
    def start_server(self, server=None):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
110
        """See breezy.transport.Server.start_server.
5017.3.2 by Vincent Ladeuil
Move DecoratorServer to test_server.py
111
112
        :server: decorate the urls given by server. If not provided a
113
        LocalServer is created.
114
        """
115
        if server is not None:
116
            self._made_server = False
117
            self._server = server
118
        else:
119
            self._made_server = True
120
            self._server = LocalURLServer()
121
            self._server.start_server()
122
123
    def stop_server(self):
124
        if self._made_server:
125
            self._server.stop_server()
126
127
    def get_decorator_class(self):
128
        """Return the class of the decorators we should be constructing."""
129
        raise NotImplementedError(self.get_decorator_class)
130
131
    def get_url_prefix(self):
132
        """What URL prefix does this decorator produce?"""
133
        return self.get_decorator_class()._get_url_prefix()
134
135
    def get_bogus_url(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
136
        """See breezy.transport.Server.get_bogus_url."""
5017.3.2 by Vincent Ladeuil
Move DecoratorServer to test_server.py
137
        return self.get_url_prefix() + self._server.get_bogus_url()
138
139
    def get_url(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
140
        """See breezy.transport.Server.get_url."""
5017.3.2 by Vincent Ladeuil
Move DecoratorServer to test_server.py
141
        return self.get_url_prefix() + self._server.get_url()
142
143
5017.3.8 by Vincent Ladeuil
Move BrokenRenameServer to bzrlib.tests.test_server
144
class BrokenRenameServer(DecoratorServer):
145
    """Server for the BrokenRenameTransportDecorator for testing with."""
146
147
    def get_decorator_class(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
148
        from breezy.transport import brokenrename
5017.3.8 by Vincent Ladeuil
Move BrokenRenameServer to bzrlib.tests.test_server
149
        return brokenrename.BrokenRenameTransportDecorator
150
151
5017.3.7 by Vincent Ladeuil
Move FakeNFSServer to bzrlib.tests.test_server
152
class FakeNFSServer(DecoratorServer):
153
    """Server for the FakeNFSTransportDecorator for testing with."""
154
155
    def get_decorator_class(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
156
        from breezy.transport import fakenfs
5017.3.7 by Vincent Ladeuil
Move FakeNFSServer to bzrlib.tests.test_server
157
        return fakenfs.FakeNFSTransportDecorator
158
159
5017.3.9 by Vincent Ladeuil
Move FakeVFATServer to bzrlib.tests.test_server
160
class FakeVFATServer(DecoratorServer):
161
    """A server that suggests connections through FakeVFATTransportDecorator
162
163
    For use in testing.
164
    """
165
166
    def get_decorator_class(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
167
        from breezy.transport import fakevfat
5017.3.14 by Vincent Ladeuil
Fix some missing prefixes.
168
        return fakevfat.FakeVFATTransportDecorator
5017.3.9 by Vincent Ladeuil
Move FakeVFATServer to bzrlib.tests.test_server
169
170
5017.3.11 by Vincent Ladeuil
Move LogDecoratorServer to bzrlib.tests.test_server
171
class LogDecoratorServer(DecoratorServer):
172
    """Server for testing."""
173
174
    def get_decorator_class(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
175
        from breezy.transport import log
5017.3.11 by Vincent Ladeuil
Move LogDecoratorServer to bzrlib.tests.test_server
176
        return log.TransportLogDecorator
177
178
5017.3.12 by Vincent Ladeuil
Move NoSmartTransportServer to bzrlib.tests.test_server
179
class NoSmartTransportServer(DecoratorServer):
180
    """Server for the NoSmartTransportDecorator for testing with."""
181
182
    def get_decorator_class(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
183
        from breezy.transport import nosmart
5017.3.14 by Vincent Ladeuil
Fix some missing prefixes.
184
        return nosmart.NoSmartTransportDecorator
5017.3.12 by Vincent Ladeuil
Move NoSmartTransportServer to bzrlib.tests.test_server
185
186
5017.3.5 by Vincent Ladeuil
Move ReadonlyServer to bzrlib.tests.readonly
187
class ReadonlyServer(DecoratorServer):
188
    """Server for the ReadonlyTransportDecorator for testing with."""
189
190
    def get_decorator_class(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
191
        from breezy.transport import readonly
5017.3.5 by Vincent Ladeuil
Move ReadonlyServer to bzrlib.tests.readonly
192
        return readonly.ReadonlyTransportDecorator
193
194
5017.3.10 by Vincent Ladeuil
Move TraceServer to bzrlib.tests.test_server
195
class TraceServer(DecoratorServer):
196
    """Server for the TransportTraceDecorator for testing with."""
197
198
    def get_decorator_class(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
199
        from breezy.transport import trace
5017.3.14 by Vincent Ladeuil
Fix some missing prefixes.
200
        return trace.TransportTraceDecorator
5017.3.10 by Vincent Ladeuil
Move TraceServer to bzrlib.tests.test_server
201
202
5017.3.13 by Vincent Ladeuil
Move UnlistableServer to bzrlib.tests.test_server
203
class UnlistableServer(DecoratorServer):
204
    """Server for the UnlistableTransportDecorator for testing with."""
205
206
    def get_decorator_class(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
207
        from breezy.transport import unlistable
5017.3.13 by Vincent Ladeuil
Move UnlistableServer to bzrlib.tests.test_server
208
        return unlistable.UnlistableTransportDecorator
209
210
5017.3.19 by Vincent Ladeuil
Move TestingPathFilteringServer to bzrlib.tests.test_server
211
class TestingPathFilteringServer(pathfilter.PathFilteringServer):
212
213
    def __init__(self):
5017.3.20 by Vincent Ladeuil
Move TestingChrootServer to bzrlib.tests.test_server
214
        """TestingPathFilteringServer is not usable until start_server
215
        is called."""
5017.3.19 by Vincent Ladeuil
Move TestingPathFilteringServer to bzrlib.tests.test_server
216
217
    def start_server(self, backing_server=None):
218
        """Setup the Chroot on backing_server."""
219
        if backing_server is not None:
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
220
            self.backing_transport = transport.get_transport_from_url(
5017.3.19 by Vincent Ladeuil
Move TestingPathFilteringServer to bzrlib.tests.test_server
221
                backing_server.get_url())
222
        else:
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
223
            self.backing_transport = transport.get_transport_from_path('.')
5017.3.19 by Vincent Ladeuil
Move TestingPathFilteringServer to bzrlib.tests.test_server
224
        self.backing_transport.clone('added-by-filter').ensure_base()
225
        self.filter_func = lambda x: 'added-by-filter/' + x
226
        super(TestingPathFilteringServer, self).start_server()
227
5017.3.20 by Vincent Ladeuil
Move TestingChrootServer to bzrlib.tests.test_server
228
    def get_bogus_url(self):
229
        raise NotImplementedError
230
231
232
class TestingChrootServer(chroot.ChrootServer):
233
234
    def __init__(self):
235
        """TestingChrootServer is not usable until start_server is called."""
236
        super(TestingChrootServer, self).__init__(None)
237
238
    def start_server(self, backing_server=None):
239
        """Setup the Chroot on backing_server."""
240
        if backing_server is not None:
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
241
            self.backing_transport = transport.get_transport_from_url(
5017.3.20 by Vincent Ladeuil
Move TestingChrootServer to bzrlib.tests.test_server
242
                backing_server.get_url())
243
        else:
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
244
            self.backing_transport = transport.get_transport_from_path('.')
5017.3.20 by Vincent Ladeuil
Move TestingChrootServer to bzrlib.tests.test_server
245
        super(TestingChrootServer, self).start_server()
246
247
    def get_bogus_url(self):
248
        raise NotImplementedError
249
5017.3.19 by Vincent Ladeuil
Move TestingPathFilteringServer to bzrlib.tests.test_server
250
5652.1.6 by Vincent Ladeuil
thread is already a python module, avoid confusion and use cethread instead.
251
class TestThread(cethread.CatchingExceptionThread):
5247.2.2 by Vincent Ladeuil
Implement a thread that can re-raise exceptions.
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)
5247.3.13 by Vincent Ladeuil
Really test against a threading server and properly shutdown socket and threads.
260
        if timeout and self.isAlive():
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,))
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)
317
            except:
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
                               ]
5247.5.7 by Vincent Ladeuil
Factor out socket exception handling during server shutdown.
367
        if isinstance(e, socket.error) and e[0] in accepted_errnos:
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),
5247.3.12 by Vincent Ladeuil
Spawn a thread for each connection from a client.
460
            target = self.process_request_thread,
6015.42.6 by Vincent Ladeuil
Ensures that the connection thread is detached from the server thread before handling the connection.
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))
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
565
            except socket.error as e:
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
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)
635
        server.SmartTCPServer.__init__(self, backing_transport,
6133.4.23 by John Arbash Meinel
Setup the TestingSmartServer to set a default client timeout,
636
            root_client_path, client_timeout=_DEFAULT_TESTING_CLIENT_TIMEOUT)
637
5247.3.38 by Vincent Ladeuil
Fix the last remaining failures.
638
    def serve(self):
639
        self.run_server_started_hooks()
640
        try:
641
            TestingThreadingTCPServer.serve(self)
642
        finally:
643
            self.run_server_stopped_hooks()
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
644
645
    def get_url(self):
646
        """Return the url of the server"""
647
        return "bzr://%s:%d/" % self.server_address
648
649
650
class SmartTCPServer_for_testing(TestingTCPServerInAThread):
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
651
    """Server suitable for use by transport tests.
652
653
    This server is backed by the process's cwd.
654
    """
655
    def __init__(self, thread_name_suffix=''):
656
        self.client_path_extra = None
657
        self.thread_name_suffix = thread_name_suffix
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
658
        self.host = '127.0.0.1'
659
        self.port = 0
660
        super(SmartTCPServer_for_testing, self).__init__(
661
                (self.host, self.port),
662
                TestingSmartServer,
5247.3.38 by Vincent Ladeuil
Fix the last remaining failures.
663
                TestingSmartConnectionHandler)
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
664
665
    def create_server(self):
666
        return self.server_class((self.host, self.port),
667
                                 self.request_handler_class,
668
                                 self.backing_transport,
669
                                 self.root_client_path)
670
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
671
672
    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.
673
                     client_path_extra='/extra/'):
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
674
        """Set up server for testing.
675
676
        :param backing_transport_server: backing server to use.  If not
677
            specified, a LocalURLServer at the current working directory will
678
            be used.
679
        :param client_path_extra: a path segment starting with '/' to append to
680
            the root URL for this server.  For instance, a value of '/foo/bar/'
681
            will mean the root of the backing transport will be published at a
682
            URL like `bzr://127.0.0.1:nnnn/foo/bar/`, rather than
683
            `bzr://127.0.0.1:nnnn/`.  Default value is `extra`, so that tests
684
            by default will fail unless they do the necessary path translation.
685
        """
686
        if not client_path_extra.startswith('/'):
687
            raise ValueError(client_path_extra)
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
688
        self.root_client_path = self.client_path_extra = client_path_extra
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
689
        from breezy.transport.chroot import ChrootServer
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
690
        if backing_transport_server is None:
691
            backing_transport_server = LocalURLServer()
692
        self.chroot_server = ChrootServer(
693
            self.get_backing_transport(backing_transport_server))
694
        self.chroot_server.start_server()
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
695
        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
696
            self.chroot_server.get_url())
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
697
        super(SmartTCPServer_for_testing, self).start_server()
698
5247.3.38 by Vincent Ladeuil
Fix the last remaining failures.
699
    def stop_server(self):
5247.3.40 by Vincent Ladeuil
Make sure the chroot server is shut down too.
700
        try:
701
            super(SmartTCPServer_for_testing, self).stop_server()
702
        finally:
703
            self.chroot_server.stop_server()
5247.3.38 by Vincent Ladeuil
Fix the last remaining failures.
704
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
705
    def get_backing_transport(self, backing_transport_server):
706
        """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.
707
        return transport.get_transport_from_url(
708
            backing_transport_server.get_url())
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
709
710
    def get_url(self):
5247.3.37 by Vincent Ladeuil
Use TestingTCPServerInAThread for smart test servers, only 4 test failures remaining.
711
        url = self.server.get_url()
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
712
        return url[:-1] + self.client_path_extra
713
714
    def get_bogus_url(self):
715
        """Return a URL which will fail to connect"""
716
        return 'bzr://127.0.0.1:1/'
717
718
719
class ReadonlySmartTCPServer_for_testing(SmartTCPServer_for_testing):
720
    """Get a readonly server for testing."""
721
722
    def get_backing_transport(self, backing_transport_server):
723
        """Get a backing transport from a server we are decorating."""
724
        url = 'readonly+' + backing_transport_server.get_url()
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
725
        return transport.get_transport_from_url(url)
5017.3.18 by Vincent Ladeuil
Move SmartTCPServer_for_testing and friends to bzrlib.tests.test_server
726
727
728
class SmartTCPServer_for_testing_v2_only(SmartTCPServer_for_testing):
729
    """A variation of SmartTCPServer_for_testing that limits the client to
730
    using RPCs in protocol v2 (i.e. bzr <= 1.5).
731
    """
732
733
    def get_url(self):
734
        url = super(SmartTCPServer_for_testing_v2_only, self).get_url()
735
        url = 'bzr-v2://' + url[len('bzr://'):]
736
        return url
737
738
739
class ReadonlySmartTCPServer_for_testing_v2_only(
740
    SmartTCPServer_for_testing_v2_only):
741
    """Get a readonly server for testing."""
742
743
    def get_backing_transport(self, backing_transport_server):
744
        """Get a backing transport from a server we are decorating."""
745
        url = 'readonly+' + backing_transport_server.get_url()
6083.1.1 by Jelmer Vernooij
Use get_transport_from_{url,path} in more places.
746
        return transport.get_transport_from_url(url)