/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
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
124
    def test_url_parsing(self):
125
        f = FakeManager()
126
        url = extract_auth('http://example.com', f)
127
        self.assertEquals('http://example.com', url)
128
        self.assertEquals(0, len(f.credentials))
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
129
        url = extract_auth('http://user:pass@www.bazaar-vcs.org/bzr/bzr.dev', f)
130
        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
131
        self.assertEquals(1, len(f.credentials))
2004.3.1 by vila
Test ConnectionError exceptions.
132
        self.assertEquals([None, 'www.bazaar-vcs.org', 'user', 'pass'],
133
                          f.credentials[0])
134
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
135
    def test_abs_url(self):
136
        """Construction of absolute http URLs"""
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
137
        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
138
        eq = self.assertEqualDiff
139
        eq(t.abspath('.'),
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
140
           'http://bazaar-vcs.org/bzr/bzr.dev')
2004.3.1 by vila
Test ConnectionError exceptions.
141
        eq(t.abspath('foo/bar'),
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
142
           'http://bazaar-vcs.org/bzr/bzr.dev/foo/bar')
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
143
        eq(t.abspath('.bzr'),
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
144
           'http://bazaar-vcs.org/bzr/bzr.dev/.bzr')
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
145
        eq(t.abspath('.bzr/1//2/./3'),
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
146
           '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
147
148
    def test_invalid_http_urls(self):
149
        """Trap invalid construction of urls"""
1185.50.94 by John Arbash Meinel
Updated web page url to http://bazaar-vcs.org
150
        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
151
        self.assertRaises(ValueError,
152
            t.abspath,
153
            '.bzr/')
154
155
    def test_http_root_urls(self):
156
        """Construction of URLs from server root"""
1540.3.26 by Martin Pool
[merge] bzr.dev; pycurl not updated for readv yet
157
        t = HttpTransport_urllib('http://bzr.ozlabs.org/')
1185.16.68 by Martin Pool
- http url fixes suggested by Robey Pointer, and tests
158
        eq = self.assertEqualDiff
159
        eq(t.abspath('.bzr/tree-version'),
160
           '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.
161
1540.3.24 by Martin Pool
Add new protocol 'http+pycurl' that always uses PyCurl.
162
    def test_http_impl_urls(self):
163
        """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 :)
164
        server = HttpServer_PyCurl()
1540.3.24 by Martin Pool
Add new protocol 'http+pycurl' that always uses PyCurl.
165
        try:
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
166
            server.setUp()
167
            url = server.get_url()
168
            self.assertTrue(url.startswith('http+pycurl://'))
169
        finally:
170
            server.tearDown()
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
171
1786.1.8 by John Arbash Meinel
[merge] Johan Rydberg test updates
172
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
173
class TestHttpConnections(object):
174
    """Test the http connections.
175
176
    This MUST be used by daughter classes that also inherit from
177
    TestCaseWithWebserver.
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
178
179
    We can't inherit directly from TestCaseWithWebserver or the
180
    test framework will try to create an instance which cannot
181
    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.
182
    """
183
184
    def setUp(self):
185
        TestCaseWithWebserver.setUp(self)
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
186
        self.build_tree(['xxx', 'foo/', 'foo/bar'], line_endings='binary',
187
                        transport=self.get_transport())
1553.1.2 by James Henstridge
Add a test to make sure the user-agent header is being sent correctly.
188
189
    def test_http_has(self):
1185.50.84 by John Arbash Meinel
[merge] bzr.dev, cleanup conflicts, fixup http tests for new TestCase layout.
190
        server = self.get_readonly_server()
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
191
        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.
192
        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.
193
        self.assertEqual(len(server.logs), 1)
2004.3.1 by vila
Test ConnectionError exceptions.
194
        self.assertContainsRe(server.logs[0],
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
195
            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
196
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
197
    def test_http_has_not_found(self):
198
        server = self.get_readonly_server()
199
        t = self._transport(server.get_url())
1553.1.5 by James Henstridge
Make HTTP transport has() method do HEAD requests, and update test to
200
        self.assertEqual(t.has('not-found'), False)
2004.3.1 by vila
Test ConnectionError exceptions.
201
        self.assertContainsRe(server.logs[1],
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
202
            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.
203
204
    def test_http_get(self):
1185.50.84 by John Arbash Meinel
[merge] bzr.dev, cleanup conflicts, fixup http tests for new TestCase layout.
205
        server = self.get_readonly_server()
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
206
        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.
207
        fp = t.get('foo/bar')
208
        self.assertEqualDiff(
209
            fp.read(),
1553.1.3 by James Henstridge
Make bzrlib.transport.http.HttpServer output referer and user agent as in
210
            'contents of foo/bar\n')
1185.50.84 by John Arbash Meinel
[merge] bzr.dev, cleanup conflicts, fixup http tests for new TestCase layout.
211
        self.assertEqual(len(server.logs), 1)
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
212
        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.
213
            '"GET /foo/bar HTTP/1.1" 200 - "-" "bzr/%s'
214
            % bzrlib.__version__) > -1)
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
215
2018.2.3 by Andrew Bennetts
Starting factoring out the smart server client "medium" from the protocol.
216
    def test_get_smart_medium(self):
217
        # For HTTP, get_smart_medium should return the transport object.
218
        server = self.get_readonly_server()
219
        http_transport = self._transport(server.get_url())
220
        medium = http_transport.get_smart_medium()
2018.2.26 by Andrew Bennetts
Changes prompted by j-a-meinel's review.
221
        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
222
2000.2.2 by John Arbash Meinel
Update the urllib.has test.
223
    def test_has_on_bogus_host(self):
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
224
        # Get a free address and don't 'accept' on it, so that we
225
        # can be sure there is no http handler there, but set a
226
        # reasonable timeout to not slow down tests too much.
227
        default_timeout = socket.getdefaulttimeout()
228
        try:
229
            socket.setdefaulttimeout(2)
230
            s = socket.socket()
231
            s.bind(('localhost', 0))
232
            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.
233
            self.assertRaises(errors.ConnectionError, t.has, 'foo/bar')
2004.1.1 by vila
Connection sharing, with redirection. without authentification.
234
        finally:
235
            socket.setdefaulttimeout(default_timeout)
236
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
237
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
238
class TestWithTransport_pycurl(object):
239
    """Test case to inherit from if pycurl is present"""
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
240
    def _get_pycurl_maybe(self):
1540.3.29 by Martin Pool
Prevent selftest failure when pycurl is not installed
241
        try:
242
            from bzrlib.transport.http._pycurl import PyCurlTransport
1612.1.1 by Martin Pool
Raise errors correctly on pycurl connection failure
243
            return PyCurlTransport
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
244
        except errors.DependencyNotPresent:
1540.3.29 by Martin Pool
Prevent selftest failure when pycurl is not installed
245
            raise TestSkipped('pycurl not present')
1540.3.15 by Martin Pool
[merge] large merge to sync with bzr.dev
246
1540.3.33 by Martin Pool
Fix http tests that were failing to run tearDown when setup got a missing dependency
247
    _transport = property(_get_pycurl_maybe)
248
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
249
250
class TestHttpConnections_urllib(TestHttpConnections, TestCaseWithWebserver):
251
    """Test http connections with urllib"""
252
253
    _transport = HttpTransport_urllib
254
255
256
257
class TestHttpConnections_pycurl(TestWithTransport_pycurl,
258
                                 TestHttpConnections,
259
                                 TestCaseWithWebserver):
260
    """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
261
262
1540.3.23 by Martin Pool
Allow urls like http+pycurl://host/ to use a particular impl
263
class TestHttpTransportRegistration(TestCase):
264
    """Test registrations of various http implementations"""
265
266
    def test_http_registered(self):
267
        # urlllib should always be present
268
        t = get_transport('http+urllib://bzr.google.com/')
269
        self.assertIsInstance(t, Transport)
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
270
        self.assertIsInstance(t, HttpTransport_urllib)
1786.1.23 by John Arbash Meinel
Move offset_to_http_ranges back onto HttpTransportBase, clarify tests.
271
272
273
class TestOffsets(TestCase):
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
274
    """Test offsets_to_ranges method"""
1786.1.23 by John Arbash Meinel
Move offset_to_http_ranges back onto HttpTransportBase, clarify tests.
275
276
    def test_offsets_to_ranges_simple(self):
277
        to_range = HttpTransportBase.offsets_to_ranges
1786.1.39 by John Arbash Meinel
Remove the ability to read negative offsets from readv()
278
        ranges = to_range([(10, 1)])
1786.1.23 by John Arbash Meinel
Move offset_to_http_ranges back onto HttpTransportBase, clarify tests.
279
        self.assertEqual([[10, 10]], ranges)
1786.1.39 by John Arbash Meinel
Remove the ability to read negative offsets from readv()
280
281
        ranges = to_range([(0, 1), (1, 1)])
282
        self.assertEqual([[0, 1]], ranges)
283
284
        ranges = to_range([(1, 1), (0, 1)])
285
        self.assertEqual([[0, 1]], ranges)
1786.1.23 by John Arbash Meinel
Move offset_to_http_ranges back onto HttpTransportBase, clarify tests.
286
287
    def test_offset_to_ranges_overlapped(self):
288
        to_range = HttpTransportBase.offsets_to_ranges
289
1786.1.39 by John Arbash Meinel
Remove the ability to read negative offsets from readv()
290
        ranges = to_range([(10, 1), (20, 2), (22, 5)])
291
        self.assertEqual([[10, 10], [20, 26]], ranges)
292
293
        ranges = to_range([(10, 1), (11, 2), (22, 5)])
294
        self.assertEqual([[10, 12], [22, 26]], ranges)
1786.1.23 by John Arbash Meinel
Move offset_to_http_ranges back onto HttpTransportBase, clarify tests.
295
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
296
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
297
class TestPost(TestCase):
298
299
    def _test_post_body_is_received(self, scheme):
300
        server = RecordingServer(expect_body_tail='end-of-body')
301
        server.setUp()
302
        self.addCleanup(server.tearDown)
303
        url = '%s://%s:%s/' % (scheme, server.host, server.port)
304
        try:
305
            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.
306
        except errors.UnsupportedProtocol:
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
307
            raise TestSkipped('%s not available' % scheme)
308
        code, response = http_transport._post('abc def end-of-body')
309
        self.assertTrue(
310
            server.received_bytes.startswith('POST /.bzr/smart HTTP/1.'))
311
        self.assertTrue('content-length: 19\r' in server.received_bytes.lower())
312
        # The transport should not be assuming that the server can accept
313
        # chunked encoding the first time it connects, because HTTP/1.1, so we
314
        # check for the literal string.
315
        self.assertTrue(
316
            server.received_bytes.endswith('\r\n\r\nabc def end-of-body'))
317
318
    def test_post_body_is_received_urllib(self):
319
        self._test_post_body_is_received('http+urllib')
320
321
    def test_post_body_is_received_pycurl(self):
322
        self._test_post_body_is_received('http+pycurl')
323
324
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
325
class TestRangeHeader(TestCase):
326
    """Test range_header method"""
327
328
    def check_header(self, value, ranges=[], tail=0):
329
        range_header = HttpTransportBase.range_header
330
        self.assertEqual(value, range_header(ranges, tail))
331
332
    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=
333
        self.check_header('0-9', ranges=[[0,9]])
334
        self.check_header('100-109', ranges=[[100,109]])
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
335
336
    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=
337
        self.check_header('-10', tail=10)
338
        self.check_header('-50', tail=50)
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
339
340
    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=
341
        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
342
                          ranges=[(0,9), (100, 200), (300,5000)])
343
344
    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=
345
        self.check_header('0-9,300-5000,-50',
1786.1.28 by John Arbash Meinel
Update and add tests for the HttpTransportBase.range_header
346
                          ranges=[(0,9), (300,5000)],
347
                          tail=50)
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
348
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
349
350
class TestWallServer(object):
351
    """Tests exceptions during the connection phase"""
352
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
353
    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 :)
354
        return HttpServer(WallRequestHandler)
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
355
356
    def test_http_has(self):
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
357
        server = self.get_readonly_server()
2004.3.1 by vila
Test ConnectionError exceptions.
358
        t = self._transport(server.get_url())
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
359
        self.assertRaises(errors.ConnectionError, t.has, 'foo/bar')
2004.3.3 by vila
Better (but still incomplete) design for bogus servers.
360
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
361
    def test_http_get(self):
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
362
        server = self.get_readonly_server()
2004.3.3 by vila
Better (but still incomplete) design for bogus servers.
363
        t = self._transport(server.get_url())
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
364
        self.assertRaises(errors.ConnectionError, t.get, 'foo/bar')
2004.3.3 by vila
Better (but still incomplete) design for bogus servers.
365
366
2004.1.15 by v.ladeuil+lp at free
Better design for bogus servers. Both urllib and pycurl pass tests.
367
class TestWallServer_urllib(TestWallServer, TestCaseWithWebserver):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
368
    """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.
369
370
    _transport = HttpTransport_urllib
371
372
373
class TestWallServer_pycurl(TestWithTransport_pycurl,
374
                            TestWallServer,
375
                            TestCaseWithWebserver):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
376
    """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.
377
378
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
379
class TestBadStatusServer(object):
380
    """Tests bad status from server."""
381
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
382
    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 :)
383
        return HttpServer(BadStatusRequestHandler)
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
384
385
    def test_http_has(self):
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
386
        server = self.get_readonly_server()
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
387
        t = self._transport(server.get_url())
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
388
        self.assertRaises(errors.InvalidHttpResponse, t.has, 'foo/bar')
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
389
390
    def test_http_get(self):
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
391
        server = self.get_readonly_server()
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
392
        t = self._transport(server.get_url())
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
393
        self.assertRaises(errors.InvalidHttpResponse, t.get, 'foo/bar')
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
394
395
396
class TestBadStatusServer_urllib(TestBadStatusServer, TestCaseWithWebserver):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
397
    """Tests bad status server for urllib implementation"""
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
398
399
    _transport = HttpTransport_urllib
400
401
402
class TestBadStatusServer_pycurl(TestWithTransport_pycurl,
403
                                 TestBadStatusServer,
404
                                 TestCaseWithWebserver):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
405
    """Tests bad status server for pycurl implementation"""
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
406
407
408
class TestInvalidStatusServer(TestBadStatusServer):
409
    """Tests invalid status from server.
410
411
    Both implementations raises the same error as for a bad status.
412
    """
413
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
414
    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 :)
415
        return HttpServer(InvalidStatusRequestHandler)
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
416
417
418
class TestInvalidStatusServer_urllib(TestInvalidStatusServer,
419
                                     TestCaseWithWebserver):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
420
    """Tests invalid status server for urllib implementation"""
2004.1.16 by v.ladeuil+lp at free
Add tests against erroneous http status lines.
421
422
    _transport = HttpTransport_urllib
423
424
425
class TestInvalidStatusServer_pycurl(TestWithTransport_pycurl,
426
                                     TestInvalidStatusServer,
427
                                     TestCaseWithWebserver):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
428
    """Tests invalid status server for pycurl implementation"""
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
429
430
431
class TestBadProtocolServer(object):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
432
    """Tests bad protocol from server."""
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
433
434
    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 :)
435
        return HttpServer(BadProtocolRequestHandler)
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
436
437
    def test_http_has(self):
438
        server = self.get_readonly_server()
439
        t = self._transport(server.get_url())
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
440
        self.assertRaises(errors.InvalidHttpResponse, t.has, 'foo/bar')
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
441
442
    def test_http_get(self):
443
        server = self.get_readonly_server()
444
        t = self._transport(server.get_url())
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
445
        self.assertRaises(errors.InvalidHttpResponse, t.get, 'foo/bar')
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
446
447
448
class TestBadProtocolServer_urllib(TestBadProtocolServer,
449
                                   TestCaseWithWebserver):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
450
    """Tests bad protocol server for urllib implementation"""
2004.1.19 by v.ladeuil+lp at free
Test protocol version in http responses.
451
452
    _transport = HttpTransport_urllib
453
454
# curl don't check the protocol version
455
#class TestBadProtocolServer_pycurl(TestWithTransport_pycurl,
456
#                                   TestBadProtocolServer,
457
#                                   TestCaseWithWebserver):
2004.1.27 by v.ladeuil+lp at free
Fix bug #57644 by issuing an explicit error message.
458
#    """Tests bad protocol server for pycurl implementation"""
459
460
461
class TestForbiddenServer(object):
462
    """Tests forbidden server"""
463
464
    def create_transport_readonly_server(self):
465
        return HttpServer(ForbiddenRequestHandler)
466
467
    def test_http_has(self):
468
        server = self.get_readonly_server()
469
        t = self._transport(server.get_url())
470
        self.assertRaises(errors.TransportError, t.has, 'foo/bar')
471
472
    def test_http_get(self):
473
        server = self.get_readonly_server()
474
        t = self._transport(server.get_url())
475
        self.assertRaises(errors.TransportError, t.get, 'foo/bar')
476
477
478
class TestForbiddenServer_urllib(TestForbiddenServer, TestCaseWithWebserver):
479
    """Tests forbidden server for urllib implementation"""
480
481
    _transport = HttpTransport_urllib
482
483
484
class TestForbiddenServer_pycurl(TestWithTransport_pycurl,
485
                                 TestForbiddenServer,
486
                                 TestCaseWithWebserver):
487
    """Tests forbidden server for pycurl implementation"""
488
2004.1.28 by v.ladeuil+lp at free
Merge bzr.dev. Including http modifications by "smart" related code
489
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
490
class TestRecordingServer(TestCase):
491
492
    def test_create(self):
493
        server = RecordingServer(expect_body_tail=None)
494
        self.assertEqual('', server.received_bytes)
495
        self.assertEqual(None, server.host)
496
        self.assertEqual(None, server.port)
497
498
    def test_setUp_and_tearDown(self):
499
        server = RecordingServer(expect_body_tail=None)
500
        server.setUp()
501
        try:
502
            self.assertNotEqual(None, server.host)
503
            self.assertNotEqual(None, server.port)
504
        finally:
505
            server.tearDown()
506
        self.assertEqual(None, server.host)
507
        self.assertEqual(None, server.port)
508
509
    def test_send_receive_bytes(self):
510
        server = RecordingServer(expect_body_tail='c')
511
        server.setUp()
512
        self.addCleanup(server.tearDown)
513
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
514
        sock.connect((server.host, server.port))
515
        sock.sendall('abc')
516
        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
517
                         osutils.recv_all(sock, 4096))
2018.2.9 by Andrew Bennetts
(Andrew Bennetts, Robert Collins) Add test_http.RecordingServer, and use it to
518
        self.assertEqual('abc', server.received_bytes)
2004.1.29 by v.ladeuil+lp at free
New tests for http range requests handling.
519
520
521
class TestRangeRequestServer(object):
522
    """Test the http connections.
523
524
    This MUST be used by daughter classes that also inherit from
525
    TestCaseWithWebserver.
526
527
    We can't inherit directly from TestCaseWithWebserver or the
528
    test framework will try to create an instance which cannot
529
    run, its implementation being incomplete.
530
    """
531
532
    def setUp(self):
533
        TestCaseWithWebserver.setUp(self)
2004.1.30 by v.ladeuil+lp at free
Fix #62276 and #62029 by providing a more robust http range handling.
534
        self.build_tree_contents([('a', '0123456789')],)
2004.1.29 by v.ladeuil+lp at free
New tests for http range requests handling.
535
536
    """Tests readv requests against server"""
537
538
    def test_readv(self):
539
        server = self.get_readonly_server()
540
        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.
541
        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.
542
        self.assertEqual(l[0], (0, '0'))
543
        self.assertEqual(l[1], (1, '1'))
544
        self.assertEqual(l[2], (3, '34'))
545
        self.assertEqual(l[3], (9, '9'))
546
547
    def test_readv_out_of_order(self):
548
        server = self.get_readonly_server()
549
        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.
550
        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.
551
        self.assertEqual(l[0], (1, '1'))
552
        self.assertEqual(l[1], (9, '9'))
553
        self.assertEqual(l[2], (0, '0'))
554
        self.assertEqual(l[3], (3, '34'))
555
556
    def test_readv_short_read(self):
557
        server = self.get_readonly_server()
558
        t = self._transport(server.get_url())
559
560
        # This is intentionally reading off the end of the file
561
        # since we are sure that it cannot get there
562
        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.
563
                              t.readv, 'a', [(1,1), (8,10)])
2004.1.29 by v.ladeuil+lp at free
New tests for http range requests handling.
564
565
        # This is trying to seek past the end of the file, it should
566
        # also raise a special error
567
        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.
568
                              t.readv, 'a', [(12,2)])
2004.1.29 by v.ladeuil+lp at free
New tests for http range requests handling.
569
570
571
class TestSingleRangeRequestServer(TestRangeRequestServer):
572
    """Test readv against a server which accept only single range requests"""
573
574
    def create_transport_readonly_server(self):
575
        return HttpServer(SingleRangeRequestHandler)
576
577
578
class TestSingleRangeRequestServer_urllib(TestSingleRangeRequestServer,
579
                                          TestCaseWithWebserver):
580
    """Tests single range requests accepting server for urllib implementation"""
581
582
    _transport = HttpTransport_urllib
583
584
585
class TestSingleRangeRequestServer_pycurl(TestWithTransport_pycurl,
586
                                          TestSingleRangeRequestServer,
587
                                          TestCaseWithWebserver):
588
    """Tests single range requests accepting server for pycurl implementation"""
589
590
591
class TestNoRangeRequestServer(TestRangeRequestServer):
592
    """Test readv against a server which do not accept range requests"""
593
594
    def create_transport_readonly_server(self):
595
        return HttpServer(NoRangeRequestHandler)
596
597
598
class TestNoRangeRequestServer_urllib(TestNoRangeRequestServer,
599
                                      TestCaseWithWebserver):
600
    """Tests range requests refusing server for urllib implementation"""
601
602
    _transport = HttpTransport_urllib
603
604
605
class TestNoRangeRequestServer_pycurl(TestWithTransport_pycurl,
606
                               TestNoRangeRequestServer,
607
                               TestCaseWithWebserver):
608
    """Tests range requests refusing server for pycurl implementation"""
609
610