/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2052.3.1 by John Arbash Meinel
Add tests to cleanup the copyright of all source files
1
# Copyright (C) 2005, 2006 Canonical Ltd
1540.3.24 by Martin Pool
Add new protocol 'http+pycurl' that always uses PyCurl.
2
#
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
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.
1540.3.24 by Martin Pool
Add new protocol 'http+pycurl' that always uses PyCurl.
7
#
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
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.
1540.3.24 by Martin Pool
Add new protocol 'http+pycurl' that always uses PyCurl.
12
#
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
16
1540.3.3 by Martin Pool
Review updates of pycurl transport
17
# FIXME: This test should be repeated for each available http client
18
# implementation; at the moment we have urllib and pycurl.
19
1540.3.22 by Martin Pool
[patch] Add TestCase.assertIsInstance
20
# TODO: Should be renamed to bzrlib.transport.http.tests?
21
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
22
import select
2000.2.2 by John Arbash Meinel
Update the urllib.has test.
23
import socket
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
24
import threading
2000.2.2 by John Arbash Meinel
Update the urllib.has test.
25
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
26
import bzrlib
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
27
from bzrlib import errors
2091.1.1 by Martin Pool
Avoid MSG_WAITALL as it doesn't work on Windows
28
from bzrlib import osutils
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
29
from bzrlib.tests import (
30
    TestCase,
31
    TestSkipped,
32
    )
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
33
from bzrlib.tests.HttpServer import (
34
    HttpServer,
35
    HttpServer_PyCurl,
36
    HttpServer_urllib,
37
    )
38
from bzrlib.tests.HTTPTestUtil import (
39
    BadProtocolRequestHandler,
40
    BadStatusRequestHandler,
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
41
    ForbiddenRequestHandler,
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
42
    InvalidStatusRequestHandler,
2004.1.29 by v.ladeuil+lp at free
New tests for http range requests handling.
43
    NoRangeRequestHandler,
44
    SingleRangeRequestHandler,
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
45
    TestCaseWithWebserver,
46
    WallRequestHandler,
47
    )
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
48
from bzrlib.transport import (
49
    get_transport,
50
    Transport,
51
    )
2004.3.3 by vila
Better (but still incomplete) design for bogus servers.
52
from bzrlib.transport.http import (
53
    extract_auth,
54
    HttpTransportBase,
55
    )
1540.3.26 by Martin Pool
[merge] bzr.dev; pycurl not updated for readv yet
56
from bzrlib.transport.http._urllib import HttpTransport_urllib
1185.40.20 by Robey Pointer
allow user:pass@ info in http urls to be used for auth; this should be easily expandable later to use auth config files
57
1786.1.8 by John Arbash Meinel
[merge] Johan Rydberg test updates
58
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
59
class FakeManager(object):
1786.1.8 by John Arbash Meinel
[merge] Johan Rydberg test updates
60
1185.40.20 by Robey Pointer
allow user:pass@ info in http urls to be used for auth; this should be easily expandable later to use auth config files
61
    def __init__(self):
62
        self.credentials = []
2004.3.1 by vila
Test ConnectionError exceptions.
63
1185.40.20 by Robey Pointer
allow user:pass@ info in http urls to be used for auth; this should be easily expandable later to use auth config files
64
    def add_password(self, realm, host, username, password):
65
        self.credentials.append([realm, host, username, password])
66
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
67
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
68
class RecordingServer(object):
69
    """A fake HTTP server.
70
    
71
    It records the bytes sent to it, and replies with a 200.
72
    """
73
74
    def __init__(self, expect_body_tail=None):
2018.2.28 by Andrew Bennetts
Changes in response to review: re-use _base_curl, rather than keeping a seperate _post_curl object; add docstring to test_http.RecordingServer, set is_user_error on some new exceptions.
75
        """Constructor.
76
77
        :type expect_body_tail: str
78
        :param expect_body_tail: a reply won't be sent until this string is
79
            received.
80
        """
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
81
        self._expect_body_tail = expect_body_tail
82
        self.host = None
83
        self.port = None
84
        self.received_bytes = ''
85
86
    def setUp(self):
87
        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
88
        self._sock.bind(('127.0.0.1', 0))
89
        self.host, self.port = self._sock.getsockname()
90
        self._ready = threading.Event()
91
        self._thread = threading.Thread(target=self._accept_read_and_reply)
92
        self._thread.setDaemon(True)
93
        self._thread.start()
94
        self._ready.wait(5)
95
96
    def _accept_read_and_reply(self):
97
        self._sock.listen(1)
98
        self._ready.set()
99
        self._sock.settimeout(5)
100
        try:
101
            conn, address = self._sock.accept()
102
            # On win32, the accepted connection will be non-blocking to start
103
            # with because we're using settimeout.
104
            conn.setblocking(True)
105
            while not self.received_bytes.endswith(self._expect_body_tail):
106
                self.received_bytes += conn.recv(4096)
107
            conn.sendall('HTTP/1.1 200 OK\r\n')
108
        except socket.timeout:
109
            # Make sure the client isn't stuck waiting for us to e.g. accept.
110
            self._sock.close()
111
112
    def tearDown(self):
113
        try:
114
            self._sock.close()
115
        except socket.error:
116
            # We might have already closed it.  We don't care.
117
            pass
118
        self.host = None
119
        self.port = None
120
121
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
122
class TestHttpUrls(TestCase):
1786.1.8 by John Arbash Meinel
[merge] Johan Rydberg test updates
123
2004.1.40 by v.ladeuil+lp at free
Fix the race condition again and correct some small typos to be in
124
    # FIXME: Some of these tests should be done for both
125
    # implementations
126
1185.40.20 by Robey Pointer
allow user:pass@ info in http urls to be used for auth; this should be easily expandable later to use auth config files
127
    def test_url_parsing(self):
128
        f = FakeManager()
129
        url = extract_auth('http://example.com', f)
130
        self.assertEquals('http://example.com', url)
131
        self.assertEquals(0, len(f.credentials))
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
132
        url = extract_auth('http://user:pass@www.bazaar-vcs.org/bzr/bzr.dev', f)
133
        self.assertEquals('http://www.bazaar-vcs.org/bzr/bzr.dev', url)
1185.40.20 by Robey Pointer
allow user:pass@ info in http urls to be used for auth; this should be easily expandable later to use auth config files
134
        self.assertEquals(1, len(f.credentials))
2004.3.1 by vila
Test ConnectionError exceptions.
135
        self.assertEquals([None, 'www.bazaar-vcs.org', 'user', 'pass'],
136
                          f.credentials[0])
137
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
138
    def test_abs_url(self):
139
        """Construction of absolute http URLs"""
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
140
        t = HttpTransport_urllib('http://bazaar-vcs.org/bzr/bzr.dev/')
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
141
        eq = self.assertEqualDiff
142
        eq(t.abspath('.'),
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
143
           'http://bazaar-vcs.org/bzr/bzr.dev')
2004.3.1 by vila
Test ConnectionError exceptions.
144
        eq(t.abspath('foo/bar'),
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
145
           'http://bazaar-vcs.org/bzr/bzr.dev/foo/bar')
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
146
        eq(t.abspath('.bzr'),
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
147
           'http://bazaar-vcs.org/bzr/bzr.dev/.bzr')
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
148
        eq(t.abspath('.bzr/1//2/./3'),
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
149
           'http://bazaar-vcs.org/bzr/bzr.dev/.bzr/1/2/3')
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
150
151
    def test_invalid_http_urls(self):
152
        """Trap invalid construction of urls"""
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
153
        t = HttpTransport_urllib('http://bazaar-vcs.org/bzr/bzr.dev/')
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
154
        self.assertRaises(ValueError,
155
            t.abspath,
156
            '.bzr/')
2004.1.42 by v.ladeuil+lp at free
Fix #70803 by catching the httplib exception.
157
        t = HttpTransport_urllib('http://http://bazaar-vcs.org/bzr/bzr.dev/')
158
        self.assertRaises(errors.InvalidURL, t.has, 'foo/bar')
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
159
160
    def test_http_root_urls(self):
161
        """Construction of URLs from server root"""
1540.3.26 by Martin Pool
[merge] bzr.dev; pycurl not updated for readv yet
162
        t = HttpTransport_urllib('http://bzr.ozlabs.org/')
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
163
        eq = self.assertEqualDiff
164
        eq(t.abspath('.bzr/tree-version'),
165
           'http://bzr.ozlabs.org/.bzr/tree-version')
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
166
1540.3.24 by Martin Pool
Add new protocol 'http+pycurl' that always uses PyCurl.
167
    def test_http_impl_urls(self):
168
        """There are servers which ask for particular clients to connect"""
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
169
        server = HttpServer_PyCurl()
1540.3.24 by Martin Pool
Add new protocol 'http+pycurl' that always uses PyCurl.
170
        try:
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
171
            server.setUp()
172
            url = server.get_url()
173
            self.assertTrue(url.startswith('http+pycurl://'))
174
        finally:
175
            server.tearDown()
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
176
1786.1.8 by John Arbash Meinel
[merge] Johan Rydberg test updates
177
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
178
class TestHttpConnections(object):
179
    """Test the http connections.
180
181
    This MUST be used by daughter classes that also inherit from
182
    TestCaseWithWebserver.
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
183
184
    We can't inherit directly from TestCaseWithWebserver or the
185
    test framework will try to create an instance which cannot
186
    run, its implementation being incomplete.
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
187
    """
188
189
    def setUp(self):
190
        TestCaseWithWebserver.setUp(self)
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
191
        self.build_tree(['xxx', 'foo/', 'foo/bar'], line_endings='binary',
192
                        transport=self.get_transport())
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
193
194
    def test_http_has(self):
1185.50.84 by John Arbash Meinel
[merge] bzr.dev, cleanup conflicts, fixup http tests for new TestCase layout.
195
        server = self.get_readonly_server()
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
196
        t = self._transport(server.get_url())
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
197
        self.assertEqual(t.has('foo/bar'), True)
1185.50.84 by John Arbash Meinel
[merge] bzr.dev, cleanup conflicts, fixup http tests for new TestCase layout.
198
        self.assertEqual(len(server.logs), 1)
2004.3.1 by vila
Test ConnectionError exceptions.
199
        self.assertContainsRe(server.logs[0],
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
200
            r'"HEAD /foo/bar HTTP/1.." (200|302) - "-" "bzr/')
1553.1.5 by James Henstridge
Make HTTP transport has() method do HEAD requests, and update test to
201
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
202
    def test_http_has_not_found(self):
203
        server = self.get_readonly_server()
204
        t = self._transport(server.get_url())
1553.1.5 by James Henstridge
Make HTTP transport has() method do HEAD requests, and update test to
205
        self.assertEqual(t.has('not-found'), False)
2004.3.1 by vila
Test ConnectionError exceptions.
206
        self.assertContainsRe(server.logs[1],
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
207
            r'"HEAD /not-found HTTP/1.." 404 - "-" "bzr/')
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
208
209
    def test_http_get(self):
1185.50.84 by John Arbash Meinel
[merge] bzr.dev, cleanup conflicts, fixup http tests for new TestCase layout.
210
        server = self.get_readonly_server()
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
211
        t = self._transport(server.get_url())
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
212
        fp = t.get('foo/bar')
213
        self.assertEqualDiff(
214
            fp.read(),
1553.1.3 by James Henstridge
Make bzrlib.transport.http.HttpServer output referer and user agent as in
215
            'contents of foo/bar\n')
1185.50.84 by John Arbash Meinel
[merge] bzr.dev, cleanup conflicts, fixup http tests for new TestCase layout.
216
        self.assertEqual(len(server.logs), 1)
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
217
        self.assertTrue(server.logs[0].find(
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
218
            '"GET /foo/bar HTTP/1.1" 200 - "-" "bzr/%s'
219
            % bzrlib.__version__) > -1)
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
220
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
221
    def test_get_smart_medium(self):
222
        # For HTTP, get_smart_medium should return the transport object.
223
        server = self.get_readonly_server()
224
        http_transport = self._transport(server.get_url())
225
        medium = http_transport.get_smart_medium()
2018.2.26 by Andrew Bennetts
Changes prompted by j-a-meinel's review.
226
        self.assertIs(medium, http_transport)
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
227
2000.2.2 by John Arbash Meinel
Update the urllib.has test.
228
    def test_has_on_bogus_host(self):
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
229
        # Get a free address and don't 'accept' on it, so that we
230
        # can be sure there is no http handler there, but set a
231
        # reasonable timeout to not slow down tests too much.
232
        default_timeout = socket.getdefaulttimeout()
233
        try:
234
            socket.setdefaulttimeout(2)
235
            s = socket.socket()
236
            s.bind(('localhost', 0))
237
            t = self._transport('http://%s:%s/' % s.getsockname())
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
238
            self.assertRaises(errors.ConnectionError, t.has, 'foo/bar')
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
239
        finally:
240
            socket.setdefaulttimeout(default_timeout)
241
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
242
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
243
class TestWithTransport_pycurl(object):
244
    """Test case to inherit from if pycurl is present"""
2004.1.40 by v.ladeuil+lp at free
Fix the race condition again and correct some small typos to be in
245
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
246
    def _get_pycurl_maybe(self):
1540.3.29 by Martin Pool
Prevent selftest failure when pycurl is not installed
247
        try:
248
            from bzrlib.transport.http._pycurl import PyCurlTransport
1612.1.1 by Martin Pool
Raise errors correctly on pycurl connection failure
249
            return PyCurlTransport
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
250
        except errors.DependencyNotPresent:
1540.3.29 by Martin Pool
Prevent selftest failure when pycurl is not installed
251
            raise TestSkipped('pycurl not present')
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
252
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
253
    _transport = property(_get_pycurl_maybe)
254
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
255
256
class TestHttpConnections_urllib(TestHttpConnections, TestCaseWithWebserver):
257
    """Test http connections with urllib"""
258
259
    _transport = HttpTransport_urllib
260
261
262
263
class TestHttpConnections_pycurl(TestWithTransport_pycurl,
264
                                 TestHttpConnections,
265
                                 TestCaseWithWebserver):
266
    """Test http connections with pycurl"""
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
267
268
1540.3.23 by Martin Pool
Allow urls like http+pycurl://host/ to use a particular impl
269
class TestHttpTransportRegistration(TestCase):
270
    """Test registrations of various http implementations"""
271
272
    def test_http_registered(self):
273
        # urlllib should always be present
274
        t = get_transport('http+urllib://bzr.google.com/')
275
        self.assertIsInstance(t, Transport)
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
276
        self.assertIsInstance(t, HttpTransport_urllib)
1786.1.23 by John Arbash Meinel
Move offset_to_http_ranges back onto HttpTransportBase, clarify tests.
277
278
279
class TestOffsets(TestCase):
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
280
    """Test offsets_to_ranges method"""
1786.1.23 by John Arbash Meinel
Move offset_to_http_ranges back onto HttpTransportBase, clarify tests.
281
282
    def test_offsets_to_ranges_simple(self):
283
        to_range = HttpTransportBase.offsets_to_ranges
1786.1.39 by John Arbash Meinel
Remove the ability to read negative offsets from readv()
284
        ranges = to_range([(10, 1)])
1786.1.23 by John Arbash Meinel
Move offset_to_http_ranges back onto HttpTransportBase, clarify tests.
285
        self.assertEqual([[10, 10]], ranges)
1786.1.39 by John Arbash Meinel
Remove the ability to read negative offsets from readv()
286
287
        ranges = to_range([(0, 1), (1, 1)])
288
        self.assertEqual([[0, 1]], ranges)
289
290
        ranges = to_range([(1, 1), (0, 1)])
291
        self.assertEqual([[0, 1]], ranges)
1786.1.23 by John Arbash Meinel
Move offset_to_http_ranges back onto HttpTransportBase, clarify tests.
292
293
    def test_offset_to_ranges_overlapped(self):
294
        to_range = HttpTransportBase.offsets_to_ranges
295
1786.1.39 by John Arbash Meinel
Remove the ability to read negative offsets from readv()
296
        ranges = to_range([(10, 1), (20, 2), (22, 5)])
297
        self.assertEqual([[10, 10], [20, 26]], ranges)
298
299
        ranges = to_range([(10, 1), (11, 2), (22, 5)])
300
        self.assertEqual([[10, 12], [22, 26]], ranges)
1786.1.23 by John Arbash Meinel
Move offset_to_http_ranges back onto HttpTransportBase, clarify tests.
301
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
302
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
303
class TestPost(TestCase):
304
305
    def _test_post_body_is_received(self, scheme):
306
        server = RecordingServer(expect_body_tail='end-of-body')
307
        server.setUp()
308
        self.addCleanup(server.tearDown)
309
        url = '%s://%s:%s/' % (scheme, server.host, server.port)
310
        try:
311
            http_transport = get_transport(url)
2004.1.30 by v.ladeuil+lp at free
Fix #62276 and #62029 by providing a more robust http range handling.
312
        except errors.UnsupportedProtocol:
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
313
            raise TestSkipped('%s not available' % scheme)
314
        code, response = http_transport._post('abc def end-of-body')
315
        self.assertTrue(
316
            server.received_bytes.startswith('POST /.bzr/smart HTTP/1.'))
317
        self.assertTrue('content-length: 19\r' in server.received_bytes.lower())
318
        # The transport should not be assuming that the server can accept
319
        # chunked encoding the first time it connects, because HTTP/1.1, so we
320
        # check for the literal string.
321
        self.assertTrue(
322
            server.received_bytes.endswith('\r\n\r\nabc def end-of-body'))
323
324
    def test_post_body_is_received_urllib(self):
325
        self._test_post_body_is_received('http+urllib')
326
327
    def test_post_body_is_received_pycurl(self):
328
        self._test_post_body_is_received('http+pycurl')
329
330
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
331
class TestRangeHeader(TestCase):
332
    """Test range_header method"""
333
334
    def check_header(self, value, ranges=[], tail=0):
335
        range_header = HttpTransportBase.range_header
336
        self.assertEqual(value, range_header(ranges, tail))
337
338
    def test_range_header_single(self):
1786.1.36 by John Arbash Meinel
pycurl expects us to just set the range of bytes, not including bytes=
339
        self.check_header('0-9', ranges=[[0,9]])
340
        self.check_header('100-109', ranges=[[100,109]])
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
341
342
    def test_range_header_tail(self):
1786.1.36 by John Arbash Meinel
pycurl expects us to just set the range of bytes, not including bytes=
343
        self.check_header('-10', tail=10)
344
        self.check_header('-50', tail=50)
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
345
346
    def test_range_header_multi(self):
1786.1.36 by John Arbash Meinel
pycurl expects us to just set the range of bytes, not including bytes=
347
        self.check_header('0-9,100-200,300-5000',
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
348
                          ranges=[(0,9), (100, 200), (300,5000)])
349
350
    def test_range_header_mixed(self):
1786.1.36 by John Arbash Meinel
pycurl expects us to just set the range of bytes, not including bytes=
351
        self.check_header('0-9,300-5000,-50',
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
352
                          ranges=[(0,9), (300,5000)],
353
                          tail=50)
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
354
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
355
356
class TestWallServer(object):
357
    """Tests exceptions during the connection phase"""
358
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
359
    def create_transport_readonly_server(self):
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
360
        return HttpServer(WallRequestHandler)
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
361
362
    def test_http_has(self):
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
363
        server = self.get_readonly_server()
2004.3.1 by vila
Test ConnectionError exceptions.
364
        t = self._transport(server.get_url())
2004.1.40 by v.ladeuil+lp at free
Fix the race condition again and correct some small typos to be in
365
        # Unfortunately httplib (see HTTPResponse._read_status
366
        # for details) make no distinction between a closed
367
        # socket and badly formatted status line, so we can't
368
        # just test for ConnectionError, we have to test
369
        # InvalidHttpResponse too.
370
        self.assertRaises((errors.ConnectionError, errors.InvalidHttpResponse),
371
                          t.has, 'foo/bar')
2004.3.3 by vila
Better (but still incomplete) design for bogus servers.
372
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
373
    def test_http_get(self):
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
374
        server = self.get_readonly_server()
2004.3.3 by vila
Better (but still incomplete) design for bogus servers.
375
        t = self._transport(server.get_url())
2145.1.1 by mbp at sourcefrog
merge urllib keepalive etc
376
        self.assertRaises((errors.ConnectionError, errors.InvalidHttpResponse),
377
                          t.get, 'foo/bar')
2004.3.3 by vila
Better (but still incomplete) design for bogus servers.
378
379
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
380
class TestWallServer_urllib(TestWallServer, TestCaseWithWebserver):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
381
    """Tests "wall" server for urllib implementation"""
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
382
383
    _transport = HttpTransport_urllib
384
385
386
class TestWallServer_pycurl(TestWithTransport_pycurl,
387
                            TestWallServer,
388
                            TestCaseWithWebserver):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
389
    """Tests "wall" server for pycurl implementation"""
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
390
391
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
392
class TestBadStatusServer(object):
393
    """Tests bad status from server."""
394
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
395
    def create_transport_readonly_server(self):
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
396
        return HttpServer(BadStatusRequestHandler)
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
397
398
    def test_http_has(self):
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
399
        server = self.get_readonly_server()
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
400
        t = self._transport(server.get_url())
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
401
        self.assertRaises(errors.InvalidHttpResponse, t.has, 'foo/bar')
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
402
403
    def test_http_get(self):
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
404
        server = self.get_readonly_server()
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
405
        t = self._transport(server.get_url())
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
406
        self.assertRaises(errors.InvalidHttpResponse, t.get, 'foo/bar')
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
407
408
409
class TestBadStatusServer_urllib(TestBadStatusServer, TestCaseWithWebserver):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
410
    """Tests bad status server for urllib implementation"""
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
411
412
    _transport = HttpTransport_urllib
413
414
415
class TestBadStatusServer_pycurl(TestWithTransport_pycurl,
416
                                 TestBadStatusServer,
417
                                 TestCaseWithWebserver):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
418
    """Tests bad status server for pycurl implementation"""
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
419
420
421
class TestInvalidStatusServer(TestBadStatusServer):
422
    """Tests invalid status from server.
423
424
    Both implementations raises the same error as for a bad status.
425
    """
426
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
427
    def create_transport_readonly_server(self):
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
428
        return HttpServer(InvalidStatusRequestHandler)
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
429
430
431
class TestInvalidStatusServer_urllib(TestInvalidStatusServer,
432
                                     TestCaseWithWebserver):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
433
    """Tests invalid status server for urllib implementation"""
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
434
435
    _transport = HttpTransport_urllib
436
437
438
class TestInvalidStatusServer_pycurl(TestWithTransport_pycurl,
439
                                     TestInvalidStatusServer,
440
                                     TestCaseWithWebserver):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
441
    """Tests invalid status server for pycurl implementation"""
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
442
443
444
class TestBadProtocolServer(object):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
445
    """Tests bad protocol from server."""
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
446
447
    def create_transport_readonly_server(self):
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
448
        return HttpServer(BadProtocolRequestHandler)
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
449
450
    def test_http_has(self):
451
        server = self.get_readonly_server()
452
        t = self._transport(server.get_url())
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
453
        self.assertRaises(errors.InvalidHttpResponse, t.has, 'foo/bar')
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
454
455
    def test_http_get(self):
456
        server = self.get_readonly_server()
457
        t = self._transport(server.get_url())
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
458
        self.assertRaises(errors.InvalidHttpResponse, t.get, 'foo/bar')
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
459
460
461
class TestBadProtocolServer_urllib(TestBadProtocolServer,
462
                                   TestCaseWithWebserver):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
463
    """Tests bad protocol server for urllib implementation"""
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
464
465
    _transport = HttpTransport_urllib
466
467
# curl don't check the protocol version
468
#class TestBadProtocolServer_pycurl(TestWithTransport_pycurl,
469
#                                   TestBadProtocolServer,
470
#                                   TestCaseWithWebserver):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
471
#    """Tests bad protocol server for pycurl implementation"""
472
473
474
class TestForbiddenServer(object):
475
    """Tests forbidden server"""
476
477
    def create_transport_readonly_server(self):
478
        return HttpServer(ForbiddenRequestHandler)
479
480
    def test_http_has(self):
481
        server = self.get_readonly_server()
482
        t = self._transport(server.get_url())
483
        self.assertRaises(errors.TransportError, t.has, 'foo/bar')
484
485
    def test_http_get(self):
486
        server = self.get_readonly_server()
487
        t = self._transport(server.get_url())
488
        self.assertRaises(errors.TransportError, t.get, 'foo/bar')
489
490
491
class TestForbiddenServer_urllib(TestForbiddenServer, TestCaseWithWebserver):
492
    """Tests forbidden server for urllib implementation"""
493
494
    _transport = HttpTransport_urllib
495
496
497
class TestForbiddenServer_pycurl(TestWithTransport_pycurl,
498
                                 TestForbiddenServer,
499
                                 TestCaseWithWebserver):
500
    """Tests forbidden server for pycurl implementation"""
501
2004.1.28 by v.ladeuil+lp at free
Merge bzr.dev. Including http modifications by "smart" related code
502
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
503
class TestRecordingServer(TestCase):
504
505
    def test_create(self):
506
        server = RecordingServer(expect_body_tail=None)
507
        self.assertEqual('', server.received_bytes)
508
        self.assertEqual(None, server.host)
509
        self.assertEqual(None, server.port)
510
511
    def test_setUp_and_tearDown(self):
512
        server = RecordingServer(expect_body_tail=None)
513
        server.setUp()
514
        try:
515
            self.assertNotEqual(None, server.host)
516
            self.assertNotEqual(None, server.port)
517
        finally:
518
            server.tearDown()
519
        self.assertEqual(None, server.host)
520
        self.assertEqual(None, server.port)
521
522
    def test_send_receive_bytes(self):
523
        server = RecordingServer(expect_body_tail='c')
524
        server.setUp()
525
        self.addCleanup(server.tearDown)
526
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
527
        sock.connect((server.host, server.port))
528
        sock.sendall('abc')
529
        self.assertEqual('HTTP/1.1 200 OK\r\n',
2091.1.1 by Martin Pool
Avoid MSG_WAITALL as it doesn't work on Windows
530
                         osutils.recv_all(sock, 4096))
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
531
        self.assertEqual('abc', server.received_bytes)
2004.1.29 by v.ladeuil+lp at free
New tests for http range requests handling.
532
533
534
class TestRangeRequestServer(object):
535
    """Test the http connections.
536
537
    This MUST be used by daughter classes that also inherit from
538
    TestCaseWithWebserver.
539
540
    We can't inherit directly from TestCaseWithWebserver or the
541
    test framework will try to create an instance which cannot
542
    run, its implementation being incomplete.
543
    """
544
545
    def setUp(self):
546
        TestCaseWithWebserver.setUp(self)
2004.1.30 by v.ladeuil+lp at free
Fix #62276 and #62029 by providing a more robust http range handling.
547
        self.build_tree_contents([('a', '0123456789')],)
2004.1.29 by v.ladeuil+lp at free
New tests for http range requests handling.
548
549
    """Tests readv requests against server"""
550
551
    def test_readv(self):
552
        server = self.get_readonly_server()
553
        t = self._transport(server.get_url())
2004.1.30 by v.ladeuil+lp at free
Fix #62276 and #62029 by providing a more robust http range handling.
554
        l = list(t.readv('a', ((0, 1), (1, 1), (3, 2), (9, 1))))
2004.1.29 by v.ladeuil+lp at free
New tests for http range requests handling.
555
        self.assertEqual(l[0], (0, '0'))
556
        self.assertEqual(l[1], (1, '1'))
557
        self.assertEqual(l[2], (3, '34'))
558
        self.assertEqual(l[3], (9, '9'))
559
560
    def test_readv_out_of_order(self):
561
        server = self.get_readonly_server()
562
        t = self._transport(server.get_url())
2004.1.30 by v.ladeuil+lp at free
Fix #62276 and #62029 by providing a more robust http range handling.
563
        l = list(t.readv('a', ((1, 1), (9, 1), (0, 1), (3, 2))))
2004.1.29 by v.ladeuil+lp at free
New tests for http range requests handling.
564
        self.assertEqual(l[0], (1, '1'))
565
        self.assertEqual(l[1], (9, '9'))
566
        self.assertEqual(l[2], (0, '0'))
567
        self.assertEqual(l[3], (3, '34'))
568
569
    def test_readv_short_read(self):
570
        server = self.get_readonly_server()
571
        t = self._transport(server.get_url())
572
573
        # This is intentionally reading off the end of the file
574
        # since we are sure that it cannot get there
575
        self.assertListRaises((errors.ShortReadvError, AssertionError),
2004.1.30 by v.ladeuil+lp at free
Fix #62276 and #62029 by providing a more robust http range handling.
576
                              t.readv, 'a', [(1,1), (8,10)])
2004.1.29 by v.ladeuil+lp at free
New tests for http range requests handling.
577
578
        # This is trying to seek past the end of the file, it should
579
        # also raise a special error
580
        self.assertListRaises(errors.ShortReadvError,
2004.1.30 by v.ladeuil+lp at free
Fix #62276 and #62029 by providing a more robust http range handling.
581
                              t.readv, 'a', [(12,2)])
2004.1.29 by v.ladeuil+lp at free
New tests for http range requests handling.
582
583
584
class TestSingleRangeRequestServer(TestRangeRequestServer):
585
    """Test readv against a server which accept only single range requests"""
586
587
    def create_transport_readonly_server(self):
588
        return HttpServer(SingleRangeRequestHandler)
589
590
591
class TestSingleRangeRequestServer_urllib(TestSingleRangeRequestServer,
592
                                          TestCaseWithWebserver):
593
    """Tests single range requests accepting server for urllib implementation"""
594
595
    _transport = HttpTransport_urllib
596
597
598
class TestSingleRangeRequestServer_pycurl(TestWithTransport_pycurl,
599
                                          TestSingleRangeRequestServer,
600
                                          TestCaseWithWebserver):
601
    """Tests single range requests accepting server for pycurl implementation"""
602
603
604
class TestNoRangeRequestServer(TestRangeRequestServer):
605
    """Test readv against a server which do not accept range requests"""
606
607
    def create_transport_readonly_server(self):
608
        return HttpServer(NoRangeRequestHandler)
609
610
611
class TestNoRangeRequestServer_urllib(TestNoRangeRequestServer,
612
                                      TestCaseWithWebserver):
613
    """Tests range requests refusing server for urllib implementation"""
614
615
    _transport = HttpTransport_urllib
616
617
618
class TestNoRangeRequestServer_pycurl(TestWithTransport_pycurl,
619
                               TestNoRangeRequestServer,
620
                               TestCaseWithWebserver):
621
    """Tests range requests refusing server for pycurl implementation"""
622
623