/breezy/unstable

To get this branch, use:
bzr branch https://code.breezy-vcs.org/breezy/unstable

« back to all changes in this revision

Viewing changes to breezy/tests/test_server.py

  • Committer: Jelmer Vernooij
  • Date: 2017-05-24 01:39:33 UTC
  • mfrom: (3815.3776.6)
  • Revision ID: jelmer@jelmer.uk-20170524013933-ir4y4tqtrsiz2ka2
New upstream snapshot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
import errno
18
18
import socket
19
 
import SocketServer
 
19
try:
 
20
    import socketserver
 
21
except ImportError:
 
22
    import SocketServer as socketserver
20
23
import sys
21
24
import threading
22
25
import traceback
23
26
 
24
27
 
25
 
from bzrlib import (
 
28
from breezy import (
26
29
    cethread,
27
30
    errors,
28
31
    osutils,
29
32
    transport,
30
33
    urlutils,
31
34
    )
32
 
from bzrlib.transport import (
 
35
from breezy.transport import (
33
36
    chroot,
34
37
    pathfilter,
35
38
    )
36
 
from bzrlib.smart import (
 
39
from breezy.smart import (
37
40
    medium,
38
41
    server,
39
42
    )
40
43
 
41
44
 
42
45
def debug_threads():
43
 
    # FIXME: There is a dependency loop between bzrlib.tests and
44
 
    # bzrlib.tests.test_server that needs to be fixed. In the mean time
 
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
45
48
    # defining this function is enough for our needs. -- vila 20100611
46
 
    from bzrlib import tests
 
49
    from breezy import tests
47
50
    return 'threads' in tests.selftest_debug_flags
48
51
 
49
52
 
53
56
    The TestServer interface provides a server for a given transport. We use
54
57
    these servers as loopback testing tools. For any given transport the
55
58
    Servers it provides must either allow writing, or serve the contents
56
 
    of os.getcwdu() at the time start_server is called.
 
59
    of osutils.getcwd() at the time start_server is called.
57
60
 
58
61
    Note that these are real servers - they must implement all the things
59
62
    that we want bzr transports to take advantage of.
66
69
        a database like svn, or a memory only transport, it should return
67
70
        a connection to a newly established resource for this Server.
68
71
        Otherwise it should return a url that will provide access to the path
69
 
        that was os.getcwdu() when start_server() was called.
 
72
        that was osutils.getcwd() when start_server() was called.
70
73
 
71
74
        Subsequent calls will return the same resource.
72
75
        """
104
107
    """
105
108
 
106
109
    def start_server(self, server=None):
107
 
        """See bzrlib.transport.Server.start_server.
 
110
        """See breezy.transport.Server.start_server.
108
111
 
109
112
        :server: decorate the urls given by server. If not provided a
110
113
        LocalServer is created.
130
133
        return self.get_decorator_class()._get_url_prefix()
131
134
 
132
135
    def get_bogus_url(self):
133
 
        """See bzrlib.transport.Server.get_bogus_url."""
 
136
        """See breezy.transport.Server.get_bogus_url."""
134
137
        return self.get_url_prefix() + self._server.get_bogus_url()
135
138
 
136
139
    def get_url(self):
137
 
        """See bzrlib.transport.Server.get_url."""
 
140
        """See breezy.transport.Server.get_url."""
138
141
        return self.get_url_prefix() + self._server.get_url()
139
142
 
140
143
 
142
145
    """Server for the BrokenRenameTransportDecorator for testing with."""
143
146
 
144
147
    def get_decorator_class(self):
145
 
        from bzrlib.transport import brokenrename
 
148
        from breezy.transport import brokenrename
146
149
        return brokenrename.BrokenRenameTransportDecorator
147
150
 
148
151
 
150
153
    """Server for the FakeNFSTransportDecorator for testing with."""
151
154
 
152
155
    def get_decorator_class(self):
153
 
        from bzrlib.transport import fakenfs
 
156
        from breezy.transport import fakenfs
154
157
        return fakenfs.FakeNFSTransportDecorator
155
158
 
156
159
 
161
164
    """
162
165
 
163
166
    def get_decorator_class(self):
164
 
        from bzrlib.transport import fakevfat
 
167
        from breezy.transport import fakevfat
165
168
        return fakevfat.FakeVFATTransportDecorator
166
169
 
167
170
 
169
172
    """Server for testing."""
170
173
 
171
174
    def get_decorator_class(self):
172
 
        from bzrlib.transport import log
 
175
        from breezy.transport import log
173
176
        return log.TransportLogDecorator
174
177
 
175
178
 
177
180
    """Server for the NoSmartTransportDecorator for testing with."""
178
181
 
179
182
    def get_decorator_class(self):
180
 
        from bzrlib.transport import nosmart
 
183
        from breezy.transport import nosmart
181
184
        return nosmart.NoSmartTransportDecorator
182
185
 
183
186
 
185
188
    """Server for the ReadonlyTransportDecorator for testing with."""
186
189
 
187
190
    def get_decorator_class(self):
188
 
        from bzrlib.transport import readonly
 
191
        from breezy.transport import readonly
189
192
        return readonly.ReadonlyTransportDecorator
190
193
 
191
194
 
193
196
    """Server for the TransportTraceDecorator for testing with."""
194
197
 
195
198
    def get_decorator_class(self):
196
 
        from bzrlib.transport import trace
 
199
        from breezy.transport import trace
197
200
        return trace.TransportTraceDecorator
198
201
 
199
202
 
201
204
    """Server for the UnlistableTransportDecorator for testing with."""
202
205
 
203
206
    def get_decorator_class(self):
204
 
        from bzrlib.transport import unlistable
 
207
        from breezy.transport import unlistable
205
208
        return unlistable.UnlistableTransportDecorator
206
209
 
207
210
 
268
271
 
269
272
 
270
273
class TestingTCPServerMixin(object):
271
 
    """Mixin to support running SocketServer.TCPServer in a thread.
 
274
    """Mixin to support running socketserver.TCPServer in a thread.
272
275
 
273
276
    Tests are connecting from the main thread, the server has to be run in a
274
277
    separate thread.
334
337
        # The following can be used for debugging purposes, it will display the
335
338
        # exception and the traceback just when it occurs instead of waiting
336
339
        # for the thread to be joined.
337
 
        # SocketServer.BaseServer.handle_error(self, request, client_address)
 
340
        # socketserver.BaseServer.handle_error(self, request, client_address)
338
341
 
339
342
        # We call close_request manually, because we are going to raise an
340
 
        # exception. The SocketServer implementation calls:
 
343
        # exception. The socketserver implementation calls:
341
344
        #   handle_error(...)
342
345
        #   close_request(...)
343
346
        # But because we raise the exception, close_request will never be
381
384
        try:
382
385
            sock.shutdown(socket.SHUT_RDWR)
383
386
            sock.close()
384
 
        except Exception, e:
 
387
        except Exception as e:
385
388
            if self.ignored_exceptions(e):
386
389
                pass
387
390
            else:
401
404
        thread.pending_exception()
402
405
 
403
406
 
404
 
class TestingTCPServer(TestingTCPServerMixin, SocketServer.TCPServer):
 
407
class TestingTCPServer(TestingTCPServerMixin, socketserver.TCPServer):
405
408
 
406
409
    def __init__(self, server_address, request_handler_class):
407
410
        TestingTCPServerMixin.__init__(self)
408
 
        SocketServer.TCPServer.__init__(self, server_address,
 
411
        socketserver.TCPServer.__init__(self, server_address,
409
412
                                        request_handler_class)
410
413
 
411
414
    def get_request(self):
422
425
 
423
426
 
424
427
class TestingThreadingTCPServer(TestingTCPServerMixin,
425
 
                                SocketServer.ThreadingTCPServer):
 
428
                                socketserver.ThreadingTCPServer):
426
429
 
427
430
    def __init__(self, server_address, request_handler_class):
428
431
        TestingTCPServerMixin.__init__(self)
429
 
        SocketServer.ThreadingTCPServer.__init__(self, server_address,
 
432
        socketserver.ThreadingTCPServer.__init__(self, server_address,
430
433
                                                 request_handler_class)
431
434
 
432
435
    def get_request(self):
441
444
        started.set()
442
445
        # We will be on our own once the server tells us we're detached
443
446
        detached.wait()
444
 
        SocketServer.ThreadingTCPServer.process_request_thread(
 
447
        socketserver.ThreadingTCPServer.process_request_thread(
445
448
            self, request, client_address)
446
449
        self.close_request(request)
447
450
        stopped.set()
559
562
            last_conn = None
560
563
            try:
561
564
                last_conn = osutils.connect_socket((self.host, self.port))
562
 
            except socket.error, e:
 
565
            except socket.error as e:
563
566
                # But ignore connection errors as the point is to unblock the
564
567
                # server thread, it may happen that it's not blocked or even
565
568
                # not started.
578
581
            # thread
579
582
            try:
580
583
                self._server_thread.join()
581
 
            except Exception, e:
 
584
            except Exception as e:
582
585
                if self.server.ignored_exceptions(e):
583
586
                    pass
584
587
                else:
599
602
        self.server._pending_exception(self._server_thread)
600
603
 
601
604
 
602
 
class TestingSmartConnectionHandler(SocketServer.BaseRequestHandler,
 
605
class TestingSmartConnectionHandler(socketserver.BaseRequestHandler,
603
606
                                    medium.SmartServerSocketStreamMedium):
604
607
 
605
608
    def __init__(self, request, client_address, server):
608
611
            server.root_client_path,
609
612
            timeout=_DEFAULT_TESTING_CLIENT_TIMEOUT)
610
613
        request.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
611
 
        SocketServer.BaseRequestHandler.__init__(self, request, client_address,
 
614
        socketserver.BaseRequestHandler.__init__(self, request, client_address,
612
615
                                                 server)
613
616
 
614
617
    def handle(self):
683
686
        if not client_path_extra.startswith('/'):
684
687
            raise ValueError(client_path_extra)
685
688
        self.root_client_path = self.client_path_extra = client_path_extra
686
 
        from bzrlib.transport.chroot import ChrootServer
 
689
        from breezy.transport.chroot import ChrootServer
687
690
        if backing_transport_server is None:
688
691
            backing_transport_server = LocalURLServer()
689
692
        self.chroot_server = ChrootServer(