/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
4763.2.4 by John Arbash Meinel
merge bzr.2.1 in preparation for NEWS entry.
1
# Copyright (C) 2006-2010 Canonical Ltd
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
16
17
import errno
3111.1.2 by Vincent Ladeuil
Preparatory cleanup.
18
import httplib
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
19
import os
2146.1.1 by Alexander Belchenko
fixes for test suite: forgotten imports in HttpServer.py
20
import posixpath
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
21
import random
22
import re
3734.2.8 by Vincent Ladeuil
Catch spurious exceptions (python-2.6) when SocketServer is shut down.
23
import select
3111.1.2 by Vincent Ladeuil
Preparatory cleanup.
24
import SimpleHTTPServer
25
import socket
3111.1.3 by Vincent Ladeuil
Rework http test servers classes. Both 1.0 and 1.1 passing tests (1.1 forced manually).
26
import SocketServer
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
27
import sys
28
import threading
29
import time
2146.1.1 by Alexander Belchenko
fixes for test suite: forgotten imports in HttpServer.py
30
import urllib
31
import urlparse
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
32
4731.2.9 by Vincent Ladeuil
Implement a new -Ethreads to better track the leaks.
33
from bzrlib import (
34
    tests,
35
    transport,
36
    )
5017.3.23 by Vincent Ladeuil
selftest -s bt.test_bzrdir passing
37
from bzrlib.tests import test_server
3111.1.2 by Vincent Ladeuil
Preparatory cleanup.
38
from bzrlib.transport import local
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
39
40
41
class BadWebserverPath(ValueError):
42
    def __str__(self):
43
        return 'path %s is not in %s' % self.args
44
45
3111.1.2 by Vincent Ladeuil
Preparatory cleanup.
46
class TestingHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
2420.1.10 by Vincent Ladeuil
Doc fixes.
47
    """Handles one request.
48
3111.1.21 by Vincent Ladeuil
Add some comments.
49
    A TestingHTTPRequestHandler is instantiated for every request received by
50
    the associated server. Note that 'request' here is inherited from the base
51
    TCPServer class, for the HTTP server it is really a connection which itself
52
    will handle one or several HTTP requests.
2420.1.10 by Vincent Ladeuil
Doc fixes.
53
    """
3111.1.24 by Vincent Ladeuil
Cleanups.
54
    # Default protocol version
55
    protocol_version = 'HTTP/1.1'
56
3111.1.2 by Vincent Ladeuil
Preparatory cleanup.
57
    # The Message-like class used to parse the request headers
58
    MessageClass = httplib.HTTPMessage
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
59
3111.1.15 by Vincent Ladeuil
Provide a way to specify the protocol version at the server layer.
60
    def setup(self):
61
        SimpleHTTPServer.SimpleHTTPRequestHandler.setup(self)
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
62
        self._cwd = self.server._home_dir
3111.1.15 by Vincent Ladeuil
Provide a way to specify the protocol version at the server layer.
63
        tcs = self.server.test_case_server
64
        if tcs.protocol_version is not None:
65
            # If the test server forced a protocol version, use it
66
            self.protocol_version = tcs.protocol_version
67
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
68
    def log_message(self, format, *args):
2164.2.28 by Vincent Ladeuil
TestingHTTPServer.test_case_server renamed from test_case to avoid confusions.
69
        tcs = self.server.test_case_server
70
        tcs.log('webserver - %s - - [%s] %s "%s" "%s"',
71
                self.address_string(),
72
                self.log_date_time_string(),
73
                format % args,
3111.1.19 by Vincent Ladeuil
Merge back test_http_implementations.pc into test_http.py.
74
                self.headers.get('referer', '-'),
2164.2.28 by Vincent Ladeuil
TestingHTTPServer.test_case_server renamed from test_case to avoid confusions.
75
                self.headers.get('user-agent', '-'))
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
76
77
    def handle_one_request(self):
78
        """Handle a single HTTP request.
79
2831.6.1 by Vincent Ladeuil
Remove some more noise from test suite.
80
        We catch all socket errors occurring when the client close the
81
        connection early to avoid polluting the test results.
82
        """
83
        try:
4731.2.3 by Vincent Ladeuil
Reduce the leaking http tests from ~200 to ~5.
84
            self._handle_one_request()
2831.6.1 by Vincent Ladeuil
Remove some more noise from test suite.
85
        except socket.error, e:
3111.1.24 by Vincent Ladeuil
Cleanups.
86
            # Any socket error should close the connection, but some errors are
87
            # due to the client closing early and we don't want to pollute test
3111.1.20 by Vincent Ladeuil
Make all the test pass. Looks like we are HTTP/1.1 compliant.
88
            # results, so we raise only the others.
89
            self.close_connection = 1
90
            if (len(e.args) == 0
91
                or e.args[0] not in (errno.EPIPE, errno.ECONNRESET,
92
                                     errno.ECONNABORTED, errno.EBADF)):
2831.6.1 by Vincent Ladeuil
Remove some more noise from test suite.
93
                raise
94
4731.2.3 by Vincent Ladeuil
Reduce the leaking http tests from ~200 to ~5.
95
    def _handle_one_request(self):
96
        SimpleHTTPServer.SimpleHTTPRequestHandler.handle_one_request(self)
97
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
98
    _range_regexp = re.compile(r'^(?P<start>\d+)-(?P<end>\d+)$')
99
    _tail_regexp = re.compile(r'^-(?P<tail>\d+)$')
100
101
    def parse_ranges(self, ranges_header):
2182.2.1 by v.ladeuil+lp at free
Aaron was right. Thanks to him, the http server RFC2616 compliance
102
        """Parse the range header value and returns ranges and tail.
103
104
        RFC2616 14.35 says that syntactically invalid range
105
        specifiers MUST be ignored. In that case, we return 0 for
106
        tail and [] for ranges.
107
        """
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
108
        tail = 0
109
        ranges = []
2182.2.1 by v.ladeuil+lp at free
Aaron was right. Thanks to him, the http server RFC2616 compliance
110
        if not ranges_header.startswith('bytes='):
111
            # Syntactically invalid header
112
            return 0, []
113
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
114
        ranges_header = ranges_header[len('bytes='):]
115
        for range_str in ranges_header.split(','):
2182.2.1 by v.ladeuil+lp at free
Aaron was right. Thanks to him, the http server RFC2616 compliance
116
            # FIXME: RFC2616 says end is optional and default to file_size
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
117
            range_match = self._range_regexp.match(range_str)
118
            if range_match is not None:
2182.2.2 by v.ladeuil+lp at free
Thanks again to Aaron, the http server RFC2616 compliance
119
                start = int(range_match.group('start'))
120
                end = int(range_match.group('end'))
121
                if start > end:
122
                    # Syntactically invalid range
123
                    return 0, []
124
                ranges.append((start, end))
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
125
            else:
126
                tail_match = self._tail_regexp.match(range_str)
127
                if tail_match is not None:
128
                    tail = int(tail_match.group('tail'))
2182.2.1 by v.ladeuil+lp at free
Aaron was right. Thanks to him, the http server RFC2616 compliance
129
                else:
130
                    # Syntactically invalid range
131
                    return 0, []
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
132
        return tail, ranges
133
3111.1.28 by Vincent Ladeuil
Fix the multi-ranges http server and add tests.
134
    def _header_line_length(self, keyword, value):
135
        header_line = '%s: %s\r\n' % (keyword, value)
136
        return len(header_line)
137
3111.1.23 by Vincent Ladeuil
Make HTTP/1.1 the default implementation reveals one more bug.
138
    def send_head(self):
139
        """Overrides base implementation to work around a bug in python2.5."""
140
        path = self.translate_path(self.path)
141
        if os.path.isdir(path) and not self.path.endswith('/'):
142
            # redirect browser - doing basically what apache does when
143
            # DirectorySlash option is On which is quite common (braindead, but
144
            # common)
145
            self.send_response(301)
146
            self.send_header("Location", self.path + "/")
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
147
            # Indicates that the body is empty for HTTP/1.1 clients
3111.1.23 by Vincent Ladeuil
Make HTTP/1.1 the default implementation reveals one more bug.
148
            self.send_header('Content-Length', '0')
149
            self.end_headers()
150
            return None
151
152
        return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self)
153
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
154
    def send_range_content(self, file, start, length):
155
        file.seek(start)
156
        self.wfile.write(file.read(length))
157
158
    def get_single_range(self, file, file_size, start, end):
159
        self.send_response(206)
160
        length = end - start + 1
161
        self.send_header('Accept-Ranges', 'bytes')
162
        self.send_header("Content-Length", "%d" % length)
163
164
        self.send_header("Content-Type", 'application/octet-stream')
165
        self.send_header("Content-Range", "bytes %d-%d/%d" % (start,
166
                                                              end,
167
                                                              file_size))
168
        self.end_headers()
169
        self.send_range_content(file, start, length)
170
171
    def get_multiple_ranges(self, file, file_size, ranges):
172
        self.send_response(206)
173
        self.send_header('Accept-Ranges', 'bytes')
3111.1.28 by Vincent Ladeuil
Fix the multi-ranges http server and add tests.
174
        boundary = '%d' % random.randint(0,0x7FFFFFFF)
175
        self.send_header('Content-Type',
176
                         'multipart/byteranges; boundary=%s' % boundary)
177
        boundary_line = '--%s\r\n' % boundary
178
        # Calculate the Content-Length
179
        content_length = 0
180
        for (start, end) in ranges:
181
            content_length += len(boundary_line)
182
            content_length += self._header_line_length(
183
                'Content-type', 'application/octet-stream')
184
            content_length += self._header_line_length(
185
                'Content-Range', 'bytes %d-%d/%d' % (start, end, file_size))
186
            content_length += len('\r\n') # end headers
2929.3.19 by Vincent Ladeuil
Fix 1.1 related bugs in HTTP server, add HTTPS passing tests (by temporarily disabling pycurl certificate verification).
187
            content_length += end - start + 1
3111.1.28 by Vincent Ladeuil
Fix the multi-ranges http server and add tests.
188
        content_length += len(boundary_line)
189
        self.send_header('Content-length', content_length)
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
190
        self.end_headers()
3111.1.28 by Vincent Ladeuil
Fix the multi-ranges http server and add tests.
191
192
        # Send the multipart body
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
193
        for (start, end) in ranges:
3111.1.28 by Vincent Ladeuil
Fix the multi-ranges http server and add tests.
194
            self.wfile.write(boundary_line)
195
            self.send_header('Content-type', 'application/octet-stream')
196
            self.send_header('Content-Range', 'bytes %d-%d/%d'
197
                             % (start, end, file_size))
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
198
            self.end_headers()
199
            self.send_range_content(file, start, end - start + 1)
3059.2.12 by Vincent Ladeuil
Spiv review feedback.
200
        # Final boundary
3111.1.28 by Vincent Ladeuil
Fix the multi-ranges http server and add tests.
201
        self.wfile.write(boundary_line)
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
202
203
    def do_GET(self):
204
        """Serve a GET request.
205
206
        Handles the Range header.
207
        """
3052.3.2 by Vincent Ladeuil
Add tests and fix trivial bugs and other typos.
208
        # Update statistics
209
        self.server.test_case_server.GET_request_nb += 1
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
210
211
        path = self.translate_path(self.path)
212
        ranges_header_value = self.headers.get('Range')
213
        if ranges_header_value is None or os.path.isdir(path):
214
            # Let the mother class handle most cases
3111.1.2 by Vincent Ladeuil
Preparatory cleanup.
215
            return SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
216
217
        try:
218
            # Always read in binary mode. Opening files in text
219
            # mode may cause newline translations, making the
220
            # actual size of the content transmitted *less* than
221
            # the content-length!
222
            file = open(path, 'rb')
223
        except IOError:
224
            self.send_error(404, "File not found")
2000.3.9 by v.ladeuil+lp at free
The tests that would have help avoid bug #73948 and all that mess :)
225
            return
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
226
227
        file_size = os.fstat(file.fileno())[6]
228
        tail, ranges = self.parse_ranges(ranges_header_value)
229
        # Normalize tail into ranges
230
        if tail != 0:
231
            ranges.append((file_size - tail, file_size))
232
2182.2.2 by v.ladeuil+lp at free
Thanks again to Aaron, the http server RFC2616 compliance
233
        self._satisfiable_ranges = True
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
234
        if len(ranges) == 0:
2182.2.2 by v.ladeuil+lp at free
Thanks again to Aaron, the http server RFC2616 compliance
235
            self._satisfiable_ranges = False
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
236
        else:
2182.2.1 by v.ladeuil+lp at free
Aaron was right. Thanks to him, the http server RFC2616 compliance
237
            def check_range(range_specifier):
238
                start, end = range_specifier
2182.2.2 by v.ladeuil+lp at free
Thanks again to Aaron, the http server RFC2616 compliance
239
                # RFC2616 14.35, ranges are invalid if start >= file_size
240
                if start >= file_size:
241
                    self._satisfiable_ranges = False # Side-effect !
2182.2.1 by v.ladeuil+lp at free
Aaron was right. Thanks to him, the http server RFC2616 compliance
242
                    return 0, 0
243
                # RFC2616 14.35, end values should be truncated
244
                # to file_size -1 if they exceed it
245
                end = min(end, file_size - 1)
246
                return start, end
247
248
            ranges = map(check_range, ranges)
249
2182.2.2 by v.ladeuil+lp at free
Thanks again to Aaron, the http server RFC2616 compliance
250
        if not self._satisfiable_ranges:
2182.2.1 by v.ladeuil+lp at free
Aaron was right. Thanks to him, the http server RFC2616 compliance
251
            # RFC2616 14.16 and 14.35 says that when a server
252
            # encounters unsatisfiable range specifiers, it
253
            # SHOULD return a 416.
2000.3.9 by v.ladeuil+lp at free
The tests that would have help avoid bug #73948 and all that mess :)
254
            file.close()
2182.2.1 by v.ladeuil+lp at free
Aaron was right. Thanks to him, the http server RFC2616 compliance
255
            # FIXME: We SHOULD send a Content-Range header too,
256
            # but the implementation of send_error does not
257
            # allows that. So far.
2000.3.9 by v.ladeuil+lp at free
The tests that would have help avoid bug #73948 and all that mess :)
258
            self.send_error(416, "Requested range not satisfiable")
259
            return
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
260
261
        if len(ranges) == 1:
262
            (start, end) = ranges[0]
263
            self.get_single_range(file, file_size, start, end)
264
        else:
265
            self.get_multiple_ranges(file, file_size, ranges)
266
        file.close()
267
2420.1.9 by Vincent Ladeuil
Refactor proxy and auth test classes. Tests failing for digest auth.
268
    def translate_path(self, path):
269
        """Translate a /-separated PATH to the local filename syntax.
270
271
        If the server requires it, proxy the path before the usual translation
272
        """
273
        if self.server.test_case_server.proxy_requests:
274
            # We need to act as a proxy and accept absolute urls,
275
            # which SimpleHTTPRequestHandler (parent) is not
276
            # ready for. So we just drop the protocol://host:port
277
            # part in front of the request-url (because we know
278
            # we would not forward the request to *another*
279
            # proxy).
280
281
            # So we do what SimpleHTTPRequestHandler.translate_path
282
            # do beginning with python 2.4.3: abandon query
283
            # parameters, scheme, host port, etc (which ensure we
284
            # provide the right behaviour on all python versions).
285
            path = urlparse.urlparse(path)[2]
286
            # And now, we can apply *our* trick to proxy files
287
            path += '-proxied'
288
289
        return self._translate_path(path)
290
291
    def _translate_path(self, path):
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
292
        """Translate a /-separated PATH to the local filename syntax.
293
3221.9.5 by Ian Clatworthy
some tweaks from abentley's earlier review feedback
294
        Note that we're translating http URLs here, not file URLs.
295
        The URL root location is the server's startup directory.
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
296
        Components that mean special things to the local file system
297
        (e.g. drive or directory names) are ignored.  (XXX They should
298
        probably be diagnosed.)
299
300
        Override from python standard library to stop it calling os.getcwd()
301
        """
302
        # abandon query parameters
303
        path = urlparse.urlparse(path)[2]
304
        path = posixpath.normpath(urllib.unquote(path))
3221.9.4 by Ian Clatworthy
fix failing unicode_paths test
305
        path = path.decode('utf-8')
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
306
        words = path.split('/')
307
        words = filter(None, words)
308
        path = self._cwd
3221.9.5 by Ian Clatworthy
some tweaks from abentley's earlier review feedback
309
        for num, word in enumerate(words):
310
            if num == 0:
311
                drive, word = os.path.splitdrive(word)
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
312
            head, word = os.path.split(word)
313
            if word in (os.curdir, os.pardir): continue
314
            path = os.path.join(path, word)
315
        return path
2420.1.9 by Vincent Ladeuil
Refactor proxy and auth test classes. Tests failing for digest auth.
316
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
317
5247.3.2 by Vincent Ladeuil
Some notes for defining TestingServerInAThread.
318
# FIXME: This should be called TestingServerInAThread
3111.1.22 by Vincent Ladeuil
Rework TestingHTTPServer classes, fix test bug.
319
class TestingHTTPServerMixin:
320
321
    def __init__(self, test_case_server):
2164.2.28 by Vincent Ladeuil
TestingHTTPServer.test_case_server renamed from test_case to avoid confusions.
322
        # test_case_server can be used to communicate between the
2164.2.29 by Vincent Ladeuil
Test the http redirection at the request level even if it's not
323
        # tests and the server (or the request handler and the
324
        # server), allowing dynamic behaviors to be defined from
325
        # the tests cases.
3111.1.22 by Vincent Ladeuil
Rework TestingHTTPServer classes, fix test bug.
326
        self.test_case_server = test_case_server
3221.11.13 by Robert Collins
Allow push --shallow to just work, and fix the testing HTTPServer to not be affected by chdir() calls.
327
        self._home_dir = test_case_server._home_dir
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
328
        self.serving = None
4731.2.2 by Vincent Ladeuil
Cleanup and refactor the server shutdown.
329
        self.is_shut_down = threading.Event()
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
330
        # We collect the sockets/threads used by the clients so we can
331
        # close/join them when shutting down
332
        self.clients = []
333
334
    def get_request (self):
335
        """Get the request and client address from the socket.
336
        """
337
        sock, addr = self._get_request()
338
        self.clients.append([sock, addr])
339
        return sock, addr
340
341
    def verify_request(self, request, client_address):
342
        """Verify the request.
343
344
        Return True if we should proceed with this request, False if we should
345
        not even touch a single byte in the socket !
346
        """
347
        return self.serving is not None and self.serving.isSet()
348
349
    def handle_request(self):
350
        request, client_address = self.get_request()
351
        try:
352
            if self.verify_request(request, client_address):
353
                self.process_request(request, client_address)
354
        except:
355
            if self.serving is not None and self.serving.isSet():
356
                self.handle_error(request, client_address)
357
            else:
358
                # Exceptions raised while we shut down are just noise, but feel
359
                # free to put a breakpoint here if you suspect something
360
                # else. Such an example is the SSL handshake: it's automatic
361
                # once we start processing the request but the last connection
362
                # will close immediately and will not be able to correctly
363
                # reply.
364
                pass
365
            self.close_request(request)
4731.2.2 by Vincent Ladeuil
Cleanup and refactor the server shutdown.
366
4731.2.7 by Vincent Ladeuil
Refactor compatibility code for python-2.[45].
367
    def server_bind(self):
368
        # The following has been fixed in 2.5 so we need to provide it for
369
        # older python versions.
370
        if sys.version < (2, 5):
371
            self.server_address = self.socket.getsockname()
372
4731.2.13 by Vincent Ladeuil
We're back at full test suite passing under all circumstances.
373
    def serve(self, started):
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
374
        self.serving  = threading.Event()
375
        self.serving.set()
4731.2.2 by Vincent Ladeuil
Cleanup and refactor the server shutdown.
376
        self.is_shut_down.clear()
4731.2.11 by Vincent Ladeuil
More thread leak tracking help.
377
        if 'threads' in tests.selftest_debug_flags:
378
            print 'Starting %r' % (self.server_address,)
4731.2.13 by Vincent Ladeuil
We're back at full test suite passing under all circumstances.
379
        # We are listening and ready to accept connections
380
        started.set()
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
381
        while self.serving.isSet():
4731.2.14 by Vincent Ladeuil
We don't need timeout here.
382
            if 'threads' in tests.selftest_debug_flags:
383
                print 'Accepting on %r' % (self.server_address,)
384
            # Really a connection but the python framework is generic and
385
            # call them requests
386
            self.handle_request()
4731.2.11 by Vincent Ladeuil
More thread leak tracking help.
387
        if 'threads' in tests.selftest_debug_flags:
388
            print 'Closing  %r' % (self.server_address,)
4731.2.2 by Vincent Ladeuil
Cleanup and refactor the server shutdown.
389
        # Let's close the listening socket
390
        self.server_close()
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
391
        if 'threads' in tests.selftest_debug_flags:
392
            print 'Closed   %r' % (self.server_address,)
4731.2.2 by Vincent Ladeuil
Cleanup and refactor the server shutdown.
393
        self.is_shut_down.set()
394
4731.3.2 by Vincent Ladeuil
Reduce patch for review purposes.
395
    def connect_socket(self):
4731.3.3 by Vincent Ladeuil
Fixed as per Andrew's review.
396
        err = socket.error('getaddrinfo returns an empty list')
4731.3.2 by Vincent Ladeuil
Reduce patch for review purposes.
397
        for res in socket.getaddrinfo(*self.server_address):
398
            af, socktype, proto, canonname, sa = res
399
            sock = None
400
            try:
401
                sock = socket.socket(af, socktype, proto)
402
                sock.connect(sa)
403
                return sock
404
4731.3.3 by Vincent Ladeuil
Fixed as per Andrew's review.
405
            except socket.error, err:
406
                # 'err' is now the most recent error
4731.3.2 by Vincent Ladeuil
Reduce patch for review purposes.
407
                if sock is not None:
408
                    sock.close()
4731.3.3 by Vincent Ladeuil
Fixed as per Andrew's review.
409
        raise err
4731.3.2 by Vincent Ladeuil
Reduce patch for review purposes.
410
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
411
    def join_thread(self, thread, timeout=2):
412
        thread.join(timeout)
413
        if thread.isAlive():
414
            # The timeout expired without joining the thread, the thread is
415
            # therefore stucked and that's a failure as far as the test is
416
            # concerned. We used to hang here.
417
            raise AssertionError('thread %s hung' % (thread.name,))
418
5247.3.2 by Vincent Ladeuil
Some notes for defining TestingServerInAThread.
419
    def shutdown_server(self):
4731.2.2 by Vincent Ladeuil
Cleanup and refactor the server shutdown.
420
        """Stops the serve() loop.
421
422
        Blocks until the loop has finished. This must be called while serve()
423
        is running in another thread, or it will deadlock.
424
        """
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
425
        if self.serving is None:
426
            # If the server wasn't properly started, there is nothing to
427
            # shutdown.
4731.2.2 by Vincent Ladeuil
Cleanup and refactor the server shutdown.
428
            return
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
429
        # As soon as we stop serving, no more connection are accepted except
430
        # one to get out of the blocking listen.
431
        self.serving.clear()
4731.2.2 by Vincent Ladeuil
Cleanup and refactor the server shutdown.
432
        # The server is listening for a last connection, let's give it:
4731.2.13 by Vincent Ladeuil
We're back at full test suite passing under all circumstances.
433
        last_conn = None
4731.2.2 by Vincent Ladeuil
Cleanup and refactor the server shutdown.
434
        try:
4731.2.18 by Vincent Ladeuil
Tweak some more but we now hang in a new way on BSD variants :-/
435
            last_conn = self.connect_socket()
4731.2.2 by Vincent Ladeuil
Cleanup and refactor the server shutdown.
436
        except socket.error, e:
437
            # But ignore connection errors as the point is to unblock the
438
            # server thread, it may happen that it's not blocked or even not
439
            # started (when something went wrong during test case setup
440
            # leading to self.setUp() *not* being called but self.tearDown()
441
            # still being called)
442
            pass
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
443
        # We don't have to wait for the server to shut down to start shutting
4731.2.14 by Vincent Ladeuil
We don't need timeout here.
444
        # down the clients, so let's start now.
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
445
        for c in self.clients:
446
            self.shutdown_client(c)
447
        self.clients = []
448
        # Now we wait for the thread running serve() to finish
4731.2.2 by Vincent Ladeuil
Cleanup and refactor the server shutdown.
449
        self.is_shut_down.wait()
4731.2.13 by Vincent Ladeuil
We're back at full test suite passing under all circumstances.
450
        if last_conn is not None:
451
            # Close the last connection without trying to use it. The server
452
            # will not process a single byte on that socket to avoid
453
            # complications (SSL starts with a handshake for example).
454
            last_conn.close()
4731.2.2 by Vincent Ladeuil
Cleanup and refactor the server shutdown.
455
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
456
    def shutdown_client(self, client):
457
        sock, addr = client[:2]
458
        self.shutdown_client_socket(sock)
4731.2.2 by Vincent Ladeuil
Cleanup and refactor the server shutdown.
459
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
460
    def shutdown_client_socket(self, sock):
4731.2.3 by Vincent Ladeuil
Reduce the leaking http tests from ~200 to ~5.
461
        """Properly shutdown a client socket.
462
463
        Under some circumstances (as in bug #383920), we need to force the
464
        shutdown as python delays it until gc occur otherwise and the client
465
        may hang.
466
467
        This should be called only when no other thread is trying to use the
468
        socket.
469
        """
470
        try:
471
            # The request process has been completed, the thread is about to
472
            # die, let's shutdown the socket if we can.
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
473
            sock.shutdown(socket.SHUT_RDWR)
5247.3.2 by Vincent Ladeuil
Some notes for defining TestingServerInAThread.
474
            sock.close()
4731.2.3 by Vincent Ladeuil
Reduce the leaking http tests from ~200 to ~5.
475
        except (socket.error, select.error), e:
476
            if e[0] in (errno.EBADF, errno.ENOTCONN):
477
                # Right, the socket is already down
478
                pass
479
            else:
5247.2.5 by Vincent Ladeuil
Some cleanups.
480
                print 'exception in shutdown_client_socket: %r' % (e,)
4731.2.3 by Vincent Ladeuil
Reduce the leaking http tests from ~200 to ~5.
481
                raise
482
483
5247.3.2 by Vincent Ladeuil
Some notes for defining TestingServerInAThread.
484
# FIXME: TestingHTTPServerMixin shouldn't be first -- vila 20100531
4731.2.2 by Vincent Ladeuil
Cleanup and refactor the server shutdown.
485
class TestingHTTPServer(TestingHTTPServerMixin, SocketServer.TCPServer):
3111.1.3 by Vincent Ladeuil
Rework http test servers classes. Both 1.0 and 1.1 passing tests (1.1 forced manually).
486
3111.1.30 by Vincent Ladeuil
Update NEWS. Some cosmetic changes.
487
    def __init__(self, server_address, request_handler_class,
488
                 test_case_server):
3111.1.22 by Vincent Ladeuil
Rework TestingHTTPServer classes, fix test bug.
489
        TestingHTTPServerMixin.__init__(self, test_case_server)
490
        SocketServer.TCPServer.__init__(self, server_address,
491
                                        request_handler_class)
492
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
493
    def _get_request (self):
494
        return SocketServer.TCPServer.get_request(self)
495
4731.3.1 by Vincent Ladeuil
Fix python-2.4 compatibility.
496
    def server_bind(self):
497
        SocketServer.TCPServer.server_bind(self)
4731.2.7 by Vincent Ladeuil
Refactor compatibility code for python-2.[45].
498
        TestingHTTPServerMixin.server_bind(self)
4731.3.1 by Vincent Ladeuil
Fix python-2.4 compatibility.
499
3111.1.22 by Vincent Ladeuil
Rework TestingHTTPServer classes, fix test bug.
500
5247.3.2 by Vincent Ladeuil
Some notes for defining TestingServerInAThread.
501
# FIXME: TestingHTTPServerMixin shouldn't be first -- vila 20100531
4731.2.2 by Vincent Ladeuil
Cleanup and refactor the server shutdown.
502
class TestingThreadingHTTPServer(TestingHTTPServerMixin,
503
                                 SocketServer.ThreadingTCPServer,
504
                                 ):
3111.1.3 by Vincent Ladeuil
Rework http test servers classes. Both 1.0 and 1.1 passing tests (1.1 forced manually).
505
    """A threading HTTP test server for HTTP 1.1.
506
507
    Since tests can initiate several concurrent connections to the same http
508
    server, we need an independent connection for each of them. We achieve that
509
    by spawning a new thread for each connection.
510
    """
511
3111.1.30 by Vincent Ladeuil
Update NEWS. Some cosmetic changes.
512
    def __init__(self, server_address, request_handler_class,
513
                 test_case_server):
3111.1.22 by Vincent Ladeuil
Rework TestingHTTPServer classes, fix test bug.
514
        TestingHTTPServerMixin.__init__(self, test_case_server)
515
        SocketServer.ThreadingTCPServer.__init__(self, server_address,
516
                                                 request_handler_class)
3111.1.3 by Vincent Ladeuil
Rework http test servers classes. Both 1.0 and 1.1 passing tests (1.1 forced manually).
517
        # Decides how threads will act upon termination of the main
518
        # process. This is prophylactic as we should not leave the threads
519
        # lying around.
3111.1.22 by Vincent Ladeuil
Rework TestingHTTPServer classes, fix test bug.
520
        self.daemon_threads = True
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
521
522
    def _get_request (self):
523
        return SocketServer.ThreadingTCPServer.get_request(self)
524
525
    def process_request_thread(self, started, request, client_address):
4731.2.13 by Vincent Ladeuil
We're back at full test suite passing under all circumstances.
526
        if 'threads' in tests.selftest_debug_flags:
527
            print 'Processing: %s' % (threading.currentThread().name,)
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
528
        started.set()
4731.2.8 by Vincent Ladeuil
Collect and shutdown clients for SmartTCPServer_for_testing.
529
        SocketServer.ThreadingTCPServer.process_request_thread(
530
            self, request, client_address)
531
        # Shutdown the socket as soon as possible, the thread will be joined
532
        # later if needed during server shutdown thread.
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
533
        self.shutdown_client_socket(request)
534
535
    def process_request(self, request, client_address):
536
        """Start a new thread to process the request."""
537
        client = self.clients.pop()
538
        started = threading.Event()
5247.3.1 by Vincent Ladeuil
Threaded http server should use ThreadWithException for the client threads too.
539
        t = test_server.ThreadWithException(
540
            event=started,
541
            target = self.process_request_thread,
542
            args = (started, request, client_address))
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
543
        t.name = '%s -> %s' % (client_address, self.server_address)
5247.3.1 by Vincent Ladeuil
Threaded http server should use ThreadWithException for the client threads too.
544
        if 'threads' in tests.selftest_debug_flags:
545
            print 'Thread for: %s started' % (threading.currentThread().name,)
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
546
        client.append(t)
547
        self.clients.append(client)
548
        if self.daemon_threads:
549
            t.setDaemon (1)
550
        t.start()
551
        started.wait()
552
553
    def shutdown_client(self, client):
554
        TestingHTTPServerMixin.shutdown_client(self, client)
555
        if len(client) == 3:
556
            # The thread has been created only if the request is processed but
5247.3.2 by Vincent Ladeuil
Some notes for defining TestingServerInAThread.
557
            # after the connection is inited. This could happen during server
558
            # shutdown.
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
559
            sock, addr, thread = client
4731.2.18 by Vincent Ladeuil
Tweak some more but we now hang in a new way on BSD variants :-/
560
            if 'threads' in tests.selftest_debug_flags:
561
                print 'Try    joining: %s' % (thread.name,)
562
            self.join_thread(thread)
4512.1.2 by Vincent Ladeuil
lifeless said: try harder :)
563
4731.3.1 by Vincent Ladeuil
Fix python-2.4 compatibility.
564
    def server_bind(self):
565
        SocketServer.ThreadingTCPServer.server_bind(self)
4731.2.7 by Vincent Ladeuil
Refactor compatibility code for python-2.[45].
566
        TestingHTTPServerMixin.server_bind(self)
4731.3.1 by Vincent Ladeuil
Fix python-2.4 compatibility.
567
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
568
3111.1.2 by Vincent Ladeuil
Preparatory cleanup.
569
class HttpServer(transport.Server):
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
570
    """A test server for http transports.
571
572
    Subclasses can provide a specific request handler.
573
    """
574
3111.1.4 by Vincent Ladeuil
Select the server depending on the request handler protocol. Add tests.
575
    # The real servers depending on the protocol
576
    http_server_class = {'HTTP/1.0': TestingHTTPServer,
577
                         'HTTP/1.1': TestingThreadingHTTPServer,
578
                         }
579
2420.1.9 by Vincent Ladeuil
Refactor proxy and auth test classes. Tests failing for digest auth.
580
    # Whether or not we proxy the requests (see
581
    # TestingHTTPRequestHandler.translate_path).
582
    proxy_requests = False
583
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
584
    # used to form the url that connects to this server
585
    _url_protocol = 'http'
586
3111.1.15 by Vincent Ladeuil
Provide a way to specify the protocol version at the server layer.
587
    def __init__(self, request_handler=TestingHTTPRequestHandler,
588
                 protocol_version=None):
589
        """Constructor.
590
591
        :param request_handler: a class that will be instantiated to handle an
592
            http connection (one or several requests).
593
594
        :param protocol_version: if specified, will override the protocol
595
            version of the request handler.
596
        """
3111.1.2 by Vincent Ladeuil
Preparatory cleanup.
597
        transport.Server.__init__(self)
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
598
        self.request_handler = request_handler
2164.2.13 by v.ladeuil+lp at free
Add tests for redirection. Preserve transport decorations.
599
        self.host = 'localhost'
600
        self.port = 0
601
        self._httpd = None
3111.1.15 by Vincent Ladeuil
Provide a way to specify the protocol version at the server layer.
602
        self.protocol_version = protocol_version
3052.3.2 by Vincent Ladeuil
Add tests and fix trivial bugs and other typos.
603
        # Allows tests to verify number of GET requests issued
604
        self.GET_request_nb = 0
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
605
2929.3.19 by Vincent Ladeuil
Fix 1.1 related bugs in HTTP server, add HTTPS passing tests (by temporarily disabling pycurl certificate verification).
606
    def create_httpd(self, serv_cls, rhandler_cls):
607
        return serv_cls((self.host, self.port), self.request_handler, self)
2929.3.12 by Vincent Ladeuil
Implement an https server passing the same tests than http. Except
608
3734.2.8 by Vincent Ladeuil
Catch spurious exceptions (python-2.6) when SocketServer is shut down.
609
    def __repr__(self):
610
        return "%s(%s:%s)" % \
611
            (self.__class__.__name__, self.host, self.port)
612
2004.1.28 by v.ladeuil+lp at free
Merge bzr.dev. Including http modifications by "smart" related code
613
    def _get_httpd(self):
2164.2.13 by v.ladeuil+lp at free
Add tests for redirection. Preserve transport decorations.
614
        if self._httpd is None:
3111.1.4 by Vincent Ladeuil
Select the server depending on the request handler protocol. Add tests.
615
            rhandler = self.request_handler
3111.1.21 by Vincent Ladeuil
Add some comments.
616
            # Depending on the protocol version, we will create the approriate
617
            # server
3111.1.15 by Vincent Ladeuil
Provide a way to specify the protocol version at the server layer.
618
            if self.protocol_version is None:
3111.1.21 by Vincent Ladeuil
Add some comments.
619
                # Use the request handler one
3111.1.15 by Vincent Ladeuil
Provide a way to specify the protocol version at the server layer.
620
                proto_vers = rhandler.protocol_version
621
            else:
3111.1.21 by Vincent Ladeuil
Add some comments.
622
                # Use our own, it will be used to override the request handler
623
                # one too.
3111.1.15 by Vincent Ladeuil
Provide a way to specify the protocol version at the server layer.
624
                proto_vers = self.protocol_version
3111.1.4 by Vincent Ladeuil
Select the server depending on the request handler protocol. Add tests.
625
            # Create the appropriate server for the required protocol
626
            serv_cls = self.http_server_class.get(proto_vers, None)
627
            if serv_cls is None:
628
                raise httplib.UnknownProtocol(proto_vers)
629
            else:
2929.3.19 by Vincent Ladeuil
Fix 1.1 related bugs in HTTP server, add HTTPS passing tests (by temporarily disabling pycurl certificate verification).
630
                self._httpd = self.create_httpd(serv_cls, rhandler)
5247.1.1 by Vincent Ladeuil
Merge previous attempt into current trunk
631
            # Ensure we get the right port and an updated host if needed
632
            self.host, self.port = self._httpd.server_address
2164.2.13 by v.ladeuil+lp at free
Add tests for redirection. Preserve transport decorations.
633
        return self._httpd
2004.1.28 by v.ladeuil+lp at free
Merge bzr.dev. Including http modifications by "smart" related code
634
5247.2.6 by Vincent Ladeuil
Clarify some iable/method names in the test servers.
635
    def run_server(self, started):
3111.1.4 by Vincent Ladeuil
Select the server depending on the request handler protocol. Add tests.
636
        """Server thread main entry point. """
5247.2.4 by Vincent Ladeuil
Add an event to ThreadWithException that can be shared with the calling thread.
637
        server = self._get_httpd()
638
        self._http_base_url = '%s://%s:%s/' % (self._url_protocol,
639
                                               self.host, self.port)
640
        server.serve(started)
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
641
642
    def _get_remote_url(self, path):
643
        path_parts = path.split(os.path.sep)
644
        if os.path.isabs(path):
645
            if path_parts[:len(self._local_path_parts)] != \
646
                   self._local_path_parts:
647
                raise BadWebserverPath(path, self.test_dir)
648
            remote_path = '/'.join(path_parts[len(self._local_path_parts):])
649
        else:
650
            remote_path = '/'.join(path_parts)
651
652
        return self._http_base_url + remote_path
653
654
    def log(self, format, *args):
655
        """Capture Server log output."""
656
        self.logs.append(format % args)
657
4934.3.3 by Martin Pool
Rename Server.setUp to Server.start_server
658
    def start_server(self, backing_transport_server=None):
659
        """See bzrlib.transport.Server.start_server.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
660
2381.1.2 by Robert Collins
Fixup the test changes made for hpss to be clean and self contained.
661
        :param backing_transport_server: The transport that requests over this
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
662
            protocol should be forwarded to. Note that this is currently not
2381.1.2 by Robert Collins
Fixup the test changes made for hpss to be clean and self contained.
663
            supported for HTTP.
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
664
        """
2381.1.2 by Robert Collins
Fixup the test changes made for hpss to be clean and self contained.
665
        # XXX: TODO: make the server back onto vfs_server rather than local
666
        # disk.
4731.2.1 by Vincent Ladeuil
Don't use shutdown() to stop http servers.
667
        if not (backing_transport_server is None
5017.3.23 by Vincent Ladeuil
selftest -s bt.test_bzrdir passing
668
                or isinstance(backing_transport_server,
669
                              test_server.LocalURLServer)):
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
670
            raise AssertionError(
4731.2.1 by Vincent Ladeuil
Don't use shutdown() to stop http servers.
671
                "HTTPServer currently assumes local transport, got %s" %
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
672
                backing_transport_server)
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
673
        self._home_dir = os.getcwdu()
674
        self._local_path_parts = self._home_dir.split(os.path.sep)
3111.1.4 by Vincent Ladeuil
Select the server depending on the request handler protocol. Add tests.
675
        self._http_base_url = None
5247.2.4 by Vincent Ladeuil
Add an event to ThreadWithException that can be shared with the calling thread.
676
        self.logs = []
3111.1.4 by Vincent Ladeuil
Select the server depending on the request handler protocol. Add tests.
677
3111.1.6 by Vincent Ladeuil
Begin refactoring test_http.py into parameterized tests.
678
        # Create the server thread
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
679
        started = threading.Event()
5247.2.4 by Vincent Ladeuil
Add an event to ThreadWithException that can be shared with the calling thread.
680
        self._http_thread = test_server.ThreadWithException(
5247.2.6 by Vincent Ladeuil
Clarify some iable/method names in the test servers.
681
            event=started, target=self.run_server, args=(started,))
2167.3.5 by v.ladeuil+lp at free
Tests for proxies, covering #74759.
682
        self._http_thread.start()
2167.3.6 by v.ladeuil+lp at free
Take John's comments into account and add more tests.
683
        # Wait for the server thread to start (i.e release the lock)
4731.2.12 by Vincent Ladeuil
Start adding a more precise synchronization between the various test threads.
684
        started.wait()
5247.2.4 by Vincent Ladeuil
Add an event to ThreadWithException that can be shared with the calling thread.
685
        if self._httpd is None:
686
            if 'threads' in tests.selftest_debug_flags:
687
                print 'Server %s:% start failed ' % (self.host, self.port)
688
        else:
689
            self._http_thread.name = self._http_base_url
690
            if 'threads' in tests.selftest_debug_flags:
691
                print 'Thread started: %s' % (self._http_thread.name,)
692
693
        # If an exception occured during the server start, it will get raised
694
        self._http_thread.join(timeout=0)
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
695
4934.3.1 by Martin Pool
Rename Server.tearDown to .stop_server
696
    def stop_server(self):
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
697
        """See bzrlib.transport.Server.tearDown."""
5247.2.4 by Vincent Ladeuil
Add an event to ThreadWithException that can be shared with the calling thread.
698
        if self._httpd is not None:
699
            # The server has been started successfully, shut it down now
5247.3.2 by Vincent Ladeuil
Some notes for defining TestingServerInAThread.
700
            self._httpd.shutdown_server()
5247.2.4 by Vincent Ladeuil
Add an event to ThreadWithException that can be shared with the calling thread.
701
            if 'threads' in tests.selftest_debug_flags:
702
                print 'Try    joining: %s' % (self._http_thread.name,)
703
            self._httpd.join_thread(self._http_thread)
704
            if 'threads' in tests.selftest_debug_flags:
705
                print 'Thread  joined: %s' % (self._http_thread.name,)
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
706
707
    def get_url(self):
708
        """See bzrlib.transport.Server.get_url."""
709
        return self._get_remote_url(self._home_dir)
710
711
    def get_bogus_url(self):
712
        """See bzrlib.transport.Server.get_bogus_url."""
713
        # this is chosen to try to prevent trouble with proxies, weird dns,
714
        # etc
2929.3.10 by Vincent Ladeuil
Add a fake https server and test facilities.
715
        return self._url_protocol + '://127.0.0.1:1/'
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
716
717
718
class HttpServer_urllib(HttpServer):
719
    """Subclass of HttpServer that gives http+urllib urls.
720
721
    This is for use in testing: connections to this server will always go
722
    through urllib where possible.
723
    """
724
725
    # urls returned by this server should require the urllib client impl
726
    _url_protocol = 'http+urllib'
727
728
729
class HttpServer_PyCurl(HttpServer):
730
    """Subclass of HttpServer that gives http+pycurl urls.
731
732
    This is for use in testing: connections to this server will always go
733
    through pycurl where possible.
734
    """
735
736
    # We don't care about checking the pycurl availability as
737
    # this server will be required only when pycurl is present
738
739
    # urls returned by this server should require the pycurl client impl
740
    _url_protocol = 'http+pycurl'