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