~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_http.py

  • Committer: v.ladeuil+lp at free
  • Date: 2006-10-23 11:04:46 UTC
  • mto: (2145.1.1 keepalive)
  • mto: This revision was merged to the branch mainline in revision 2146.
  • Revision ID: v.ladeuil+lp@free.fr-20061023110446-1fddf0ae083c0c1d
Cosmetic fix for bug #57644.

* bzrlib/transport/http/_pycurl.py:
(PyCurlTransport._raise_curl_http_error): Mention url in aerror
message.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
# FIXME: This test should be repeated for each available http client
 
18
# implementation; at the moment we have urllib and pycurl.
 
19
 
 
20
# TODO: Should be renamed to bzrlib.transport.http.tests?
 
21
 
 
22
import select
 
23
import socket
 
24
import threading
 
25
 
 
26
import bzrlib
 
27
from bzrlib import errors
 
28
from bzrlib.tests import (
 
29
    TestCase,
 
30
    TestSkipped,
 
31
    )
 
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,
 
40
    ForbiddenRequestHandler,
 
41
    InvalidStatusRequestHandler,
 
42
    NoRangeRequestHandler,
 
43
    SingleRangeRequestHandler,
 
44
    TestCaseWithWebserver,
 
45
    WallRequestHandler,
 
46
    )
 
47
from bzrlib.transport import (
 
48
    get_transport,
 
49
    Transport,
 
50
    )
 
51
from bzrlib.transport.http import (
 
52
    extract_auth,
 
53
    HttpTransportBase,
 
54
    )
 
55
from bzrlib.transport.http._urllib import HttpTransport_urllib
 
56
 
 
57
 
 
58
class FakeManager(object):
 
59
 
 
60
    def __init__(self):
 
61
        self.credentials = []
 
62
 
 
63
    def add_password(self, realm, host, username, password):
 
64
        self.credentials.append([realm, host, username, password])
 
65
 
 
66
 
 
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):
 
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
        """
 
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
 
 
121
class TestHttpUrls(TestCase):
 
122
 
 
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))
 
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)
 
130
        self.assertEquals(1, len(f.credentials))
 
131
        self.assertEquals([None, 'www.bazaar-vcs.org', 'user', 'pass'],
 
132
                          f.credentials[0])
 
133
 
 
134
    def test_abs_url(self):
 
135
        """Construction of absolute http URLs"""
 
136
        t = HttpTransport_urllib('http://bazaar-vcs.org/bzr/bzr.dev/')
 
137
        eq = self.assertEqualDiff
 
138
        eq(t.abspath('.'),
 
139
           'http://bazaar-vcs.org/bzr/bzr.dev')
 
140
        eq(t.abspath('foo/bar'),
 
141
           'http://bazaar-vcs.org/bzr/bzr.dev/foo/bar')
 
142
        eq(t.abspath('.bzr'),
 
143
           'http://bazaar-vcs.org/bzr/bzr.dev/.bzr')
 
144
        eq(t.abspath('.bzr/1//2/./3'),
 
145
           'http://bazaar-vcs.org/bzr/bzr.dev/.bzr/1/2/3')
 
146
 
 
147
    def test_invalid_http_urls(self):
 
148
        """Trap invalid construction of urls"""
 
149
        t = HttpTransport_urllib('http://bazaar-vcs.org/bzr/bzr.dev/')
 
150
        self.assertRaises(ValueError,
 
151
            t.abspath,
 
152
            '.bzr/')
 
153
 
 
154
    def test_http_root_urls(self):
 
155
        """Construction of URLs from server root"""
 
156
        t = HttpTransport_urllib('http://bzr.ozlabs.org/')
 
157
        eq = self.assertEqualDiff
 
158
        eq(t.abspath('.bzr/tree-version'),
 
159
           'http://bzr.ozlabs.org/.bzr/tree-version')
 
160
 
 
161
    def test_http_impl_urls(self):
 
162
        """There are servers which ask for particular clients to connect"""
 
163
        server = HttpServer_PyCurl()
 
164
        try:
 
165
            server.setUp()
 
166
            url = server.get_url()
 
167
            self.assertTrue(url.startswith('http+pycurl://'))
 
168
        finally:
 
169
            server.tearDown()
 
170
 
 
171
 
 
172
class TestHttpConnections(object):
 
173
    """Test the http connections.
 
174
 
 
175
    This MUST be used by daughter classes that also inherit from
 
176
    TestCaseWithWebserver.
 
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.
 
181
    """
 
182
 
 
183
    def setUp(self):
 
184
        TestCaseWithWebserver.setUp(self)
 
185
        self.build_tree(['xxx', 'foo/', 'foo/bar'], line_endings='binary',
 
186
                        transport=self.get_transport())
 
187
 
 
188
    def test_http_has(self):
 
189
        server = self.get_readonly_server()
 
190
        t = self._transport(server.get_url())
 
191
        self.assertEqual(t.has('foo/bar'), True)
 
192
        self.assertEqual(len(server.logs), 1)
 
193
        self.assertContainsRe(server.logs[0],
 
194
            r'"HEAD /foo/bar HTTP/1.." (200|302) - "-" "bzr/')
 
195
 
 
196
    def test_http_has_not_found(self):
 
197
        server = self.get_readonly_server()
 
198
        t = self._transport(server.get_url())
 
199
        self.assertEqual(t.has('not-found'), False)
 
200
        self.assertContainsRe(server.logs[1],
 
201
            r'"HEAD /not-found HTTP/1.." 404 - "-" "bzr/')
 
202
 
 
203
    def test_http_get(self):
 
204
        server = self.get_readonly_server()
 
205
        t = self._transport(server.get_url())
 
206
        fp = t.get('foo/bar')
 
207
        self.assertEqualDiff(
 
208
            fp.read(),
 
209
            'contents of foo/bar\n')
 
210
        self.assertEqual(len(server.logs), 1)
 
211
        self.assertTrue(server.logs[0].find(
 
212
            '"GET /foo/bar HTTP/1.1" 200 - "-" "bzr/%s'
 
213
            % bzrlib.__version__) > -1)
 
214
 
 
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()
 
220
        self.assertIs(medium, http_transport)
 
221
 
 
222
    def test_has_on_bogus_host(self):
 
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())
 
232
            self.assertRaises(errors.ConnectionError, t.has, 'foo/bar')
 
233
        finally:
 
234
            socket.setdefaulttimeout(default_timeout)
 
235
 
 
236
 
 
237
class TestWithTransport_pycurl(object):
 
238
    """Test case to inherit from if pycurl is present"""
 
239
    def _get_pycurl_maybe(self):
 
240
        try:
 
241
            from bzrlib.transport.http._pycurl import PyCurlTransport
 
242
            return PyCurlTransport
 
243
        except errors.DependencyNotPresent:
 
244
            raise TestSkipped('pycurl not present')
 
245
 
 
246
    _transport = property(_get_pycurl_maybe)
 
247
 
 
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"""
 
260
 
 
261
 
 
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)
 
269
        self.assertIsInstance(t, HttpTransport_urllib)
 
270
 
 
271
 
 
272
class TestOffsets(TestCase):
 
273
    """Test offsets_to_ranges method"""
 
274
 
 
275
    def test_offsets_to_ranges_simple(self):
 
276
        to_range = HttpTransportBase.offsets_to_ranges
 
277
        ranges = to_range([(10, 1)])
 
278
        self.assertEqual([[10, 10]], ranges)
 
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)
 
285
 
 
286
    def test_offset_to_ranges_overlapped(self):
 
287
        to_range = HttpTransportBase.offsets_to_ranges
 
288
 
 
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)
 
294
 
 
295
 
 
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)
 
305
        except errors.UnsupportedProtocol:
 
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
 
 
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):
 
332
        self.check_header('0-9', ranges=[[0,9]])
 
333
        self.check_header('100-109', ranges=[[100,109]])
 
334
 
 
335
    def test_range_header_tail(self):
 
336
        self.check_header('-10', tail=10)
 
337
        self.check_header('-50', tail=50)
 
338
 
 
339
    def test_range_header_multi(self):
 
340
        self.check_header('0-9,100-200,300-5000',
 
341
                          ranges=[(0,9), (100, 200), (300,5000)])
 
342
 
 
343
    def test_range_header_mixed(self):
 
344
        self.check_header('0-9,300-5000,-50',
 
345
                          ranges=[(0,9), (300,5000)],
 
346
                          tail=50)
 
347
 
 
348
 
 
349
class TestWallServer(object):
 
350
    """Tests exceptions during the connection phase"""
 
351
 
 
352
    def create_transport_readonly_server(self):
 
353
        return HttpServer(WallRequestHandler)
 
354
 
 
355
    def test_http_has(self):
 
356
        server = self.get_readonly_server()
 
357
        t = self._transport(server.get_url())
 
358
        self.assertRaises(errors.ConnectionError, t.has, 'foo/bar')
 
359
 
 
360
    def test_http_get(self):
 
361
        server = self.get_readonly_server()
 
362
        t = self._transport(server.get_url())
 
363
        self.assertRaises(errors.ConnectionError, t.get, 'foo/bar')
 
364
 
 
365
 
 
366
class TestWallServer_urllib(TestWallServer, TestCaseWithWebserver):
 
367
    """Tests "wall" server for urllib implementation"""
 
368
 
 
369
    _transport = HttpTransport_urllib
 
370
 
 
371
 
 
372
class TestWallServer_pycurl(TestWithTransport_pycurl,
 
373
                            TestWallServer,
 
374
                            TestCaseWithWebserver):
 
375
    """Tests "wall" server for pycurl implementation"""
 
376
 
 
377
 
 
378
class TestBadStatusServer(object):
 
379
    """Tests bad status from server."""
 
380
 
 
381
    def create_transport_readonly_server(self):
 
382
        return HttpServer(BadStatusRequestHandler)
 
383
 
 
384
    def test_http_has(self):
 
385
        server = self.get_readonly_server()
 
386
        t = self._transport(server.get_url())
 
387
        self.assertRaises(errors.InvalidHttpResponse, t.has, 'foo/bar')
 
388
 
 
389
    def test_http_get(self):
 
390
        server = self.get_readonly_server()
 
391
        t = self._transport(server.get_url())
 
392
        self.assertRaises(errors.InvalidHttpResponse, t.get, 'foo/bar')
 
393
 
 
394
 
 
395
class TestBadStatusServer_urllib(TestBadStatusServer, TestCaseWithWebserver):
 
396
    """Tests bad status server for urllib implementation"""
 
397
 
 
398
    _transport = HttpTransport_urllib
 
399
 
 
400
 
 
401
class TestBadStatusServer_pycurl(TestWithTransport_pycurl,
 
402
                                 TestBadStatusServer,
 
403
                                 TestCaseWithWebserver):
 
404
    """Tests bad status server for pycurl implementation"""
 
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
 
 
413
    def create_transport_readonly_server(self):
 
414
        return HttpServer(InvalidStatusRequestHandler)
 
415
 
 
416
 
 
417
class TestInvalidStatusServer_urllib(TestInvalidStatusServer,
 
418
                                     TestCaseWithWebserver):
 
419
    """Tests invalid status server for urllib implementation"""
 
420
 
 
421
    _transport = HttpTransport_urllib
 
422
 
 
423
 
 
424
class TestInvalidStatusServer_pycurl(TestWithTransport_pycurl,
 
425
                                     TestInvalidStatusServer,
 
426
                                     TestCaseWithWebserver):
 
427
    """Tests invalid status server for pycurl implementation"""
 
428
 
 
429
 
 
430
class TestBadProtocolServer(object):
 
431
    """Tests bad protocol from server."""
 
432
 
 
433
    def create_transport_readonly_server(self):
 
434
        return HttpServer(BadProtocolRequestHandler)
 
435
 
 
436
    def test_http_has(self):
 
437
        server = self.get_readonly_server()
 
438
        t = self._transport(server.get_url())
 
439
        self.assertRaises(errors.InvalidHttpResponse, t.has, 'foo/bar')
 
440
 
 
441
    def test_http_get(self):
 
442
        server = self.get_readonly_server()
 
443
        t = self._transport(server.get_url())
 
444
        self.assertRaises(errors.InvalidHttpResponse, t.get, 'foo/bar')
 
445
 
 
446
 
 
447
class TestBadProtocolServer_urllib(TestBadProtocolServer,
 
448
                                   TestCaseWithWebserver):
 
449
    """Tests bad protocol server for urllib implementation"""
 
450
 
 
451
    _transport = HttpTransport_urllib
 
452
 
 
453
# curl don't check the protocol version
 
454
#class TestBadProtocolServer_pycurl(TestWithTransport_pycurl,
 
455
#                                   TestBadProtocolServer,
 
456
#                                   TestCaseWithWebserver):
 
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
 
 
488
 
 
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)
 
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)
 
533
        self.build_tree_contents([('a', '0123456789')],)
 
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())
 
540
        l = list(t.readv('a', ((0, 1), (1, 1), (3, 2), (9, 1))))
 
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())
 
549
        l = list(t.readv('a', ((1, 1), (9, 1), (0, 1), (3, 2))))
 
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),
 
562
                              t.readv, 'a', [(1,1), (8,10)])
 
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,
 
567
                              t.readv, 'a', [(12,2)])
 
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