~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_http.py

  • Committer: Vincent Ladeuil
  • Date: 2007-12-19 11:29:12 UTC
  • mto: (3146.3.1 179368) (3156.2.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 3158.
  • Revision ID: v.ladeuil+lp@free.fr-20071219112912-fd3wdp4z3tmknf0v
Most refactoring regarding parameterization for urllib/pycurl and custom
request handlers done.

* bzrlib/tests/test_http_implementations.py: 
Transfer more tests from test_http.py and dedicated request
handlers from http_utils.py.

* bzrlib/tests/test_http.py: 
Transfer more tests to test_http_implementations.

* bzrlib/tests/http_utils.py: 
Transfer to http_test_implementations.py all request hadlers that
exercise "bogus" behaviors since they are specific to some tests
and not expected to be reused.

Show diffs side-by-side

added added

removed removed

Lines of Context:
46
46
    StringIOWrapper,
47
47
    )
48
48
from bzrlib.tests.http_utils import (
49
 
    BadProtocolRequestHandler,
50
 
    BadStatusRequestHandler,
51
 
    ForbiddenRequestHandler,
52
49
    HTTPBasicAuthServer,
53
50
    HTTPDigestAuthServer,
54
51
    HTTPServerRedirecting,
55
 
    InvalidStatusRequestHandler,
56
 
    LimitedRangeHTTPServer,
57
 
    NoRangeRequestHandler,
58
52
    ProxyBasicAuthServer,
59
53
    ProxyDigestAuthServer,
60
54
    ProxyServer,
61
 
    SingleRangeRequestHandler,
62
 
    SingleOnlyRangeRequestHandler,
63
55
    TestCaseWithRedirectedWebserver,
64
56
    TestCaseWithTwoWebservers,
65
57
    TestCaseWithWebserver,
66
 
    WallRequestHandler,
67
58
    )
68
59
from bzrlib.transport import (
69
60
    _CoalescedOffset,
170
161
                          f.credentials[0])
171
162
 
172
163
 
173
 
class TestHttpUrls_pycurl(TestWithTransport_pycurl, tests.TestCase):
174
 
    """Test http urls with pycurl"""
175
 
 
176
 
    _server = http_server.HttpServer_PyCurl
177
 
    _qualified_prefix = 'http+pycurl'
 
164
class TestHttps_pycurl(TestWithTransport_pycurl, tests.TestCase):
178
165
 
179
166
    # TODO: This should really be moved into another pycurl
180
167
    # specific test. When https tests will be implemented, take
209
196
        self.assertRaises(errors.DependencyNotPresent, self._transport,
210
197
                          'https://launchpad.net')
211
198
 
212
 
class TestHttpTransportRegistration(tests.TestCase):
213
 
    """Test registrations of various http implementations"""
214
 
 
215
 
    def test_http_registered(self):
216
 
        # urlllib should always be present
217
 
        t = get_transport('http+urllib://bzr.google.com/')
218
 
        self.assertIsInstance(t, Transport)
219
 
        self.assertIsInstance(t, HttpTransport_urllib)
220
 
 
221
 
 
222
199
class TestRangeHeader(tests.TestCase):
223
200
    """Test range_header method"""
224
201
 
247
224
                          tail=50)
248
225
 
249
226
 
250
 
class TestWallServer(object):
251
 
    """Tests exceptions during the connection phase"""
252
 
 
253
 
    def create_transport_readonly_server(self):
254
 
        return http_server.HttpServer(WallRequestHandler)
255
 
 
256
 
    def test_http_has(self):
257
 
        server = self.get_readonly_server()
258
 
        t = self._transport(server.get_url())
259
 
        # Unfortunately httplib (see HTTPResponse._read_status
260
 
        # for details) make no distinction between a closed
261
 
        # socket and badly formatted status line, so we can't
262
 
        # just test for ConnectionError, we have to test
263
 
        # InvalidHttpResponse too.
264
 
        self.assertRaises((errors.ConnectionError, errors.InvalidHttpResponse),
265
 
                          t.has, 'foo/bar')
266
 
 
267
 
    def test_http_get(self):
268
 
        server = self.get_readonly_server()
269
 
        t = self._transport(server.get_url())
270
 
        self.assertRaises((errors.ConnectionError, errors.InvalidHttpResponse),
271
 
                          t.get, 'foo/bar')
272
 
 
273
 
 
274
 
class TestWallServer_urllib(TestWallServer, TestCaseWithWebserver):
275
 
    """Tests "wall" server for urllib implementation"""
276
 
 
277
 
    _transport = HttpTransport_urllib
278
 
 
279
 
 
280
 
class TestWallServer_pycurl(TestWithTransport_pycurl,
281
 
                            TestWallServer,
282
 
                            TestCaseWithWebserver):
283
 
    """Tests "wall" server for pycurl implementation"""
284
 
 
285
 
 
286
 
class TestBadStatusServer(object):
287
 
    """Tests bad status from server."""
288
 
 
289
 
    def create_transport_readonly_server(self):
290
 
        return http_server.HttpServer(BadStatusRequestHandler)
291
 
 
292
 
    def test_http_has(self):
293
 
        server = self.get_readonly_server()
294
 
        t = self._transport(server.get_url())
295
 
        self.assertRaises(errors.InvalidHttpResponse, t.has, 'foo/bar')
296
 
 
297
 
    def test_http_get(self):
298
 
        server = self.get_readonly_server()
299
 
        t = self._transport(server.get_url())
300
 
        self.assertRaises(errors.InvalidHttpResponse, t.get, 'foo/bar')
301
 
 
302
 
 
303
 
class TestBadStatusServer_urllib(TestBadStatusServer, TestCaseWithWebserver):
304
 
    """Tests bad status server for urllib implementation"""
305
 
 
306
 
    _transport = HttpTransport_urllib
307
 
 
308
 
 
309
 
class TestBadStatusServer_pycurl(TestWithTransport_pycurl,
310
 
                                 TestBadStatusServer,
311
 
                                 TestCaseWithWebserver):
312
 
    """Tests bad status server for pycurl implementation"""
313
 
 
314
 
 
315
 
class TestInvalidStatusServer(TestBadStatusServer):
316
 
    """Tests invalid status from server.
317
 
 
318
 
    Both implementations raises the same error as for a bad status.
319
 
    """
320
 
 
321
 
    def create_transport_readonly_server(self):
322
 
        return http_server.HttpServer(InvalidStatusRequestHandler)
323
 
 
324
 
 
325
 
class TestInvalidStatusServer_urllib(TestInvalidStatusServer,
326
 
                                     TestCaseWithWebserver):
327
 
    """Tests invalid status server for urllib implementation"""
328
 
 
329
 
    _transport = HttpTransport_urllib
330
 
 
331
 
 
332
 
class TestInvalidStatusServer_pycurl(TestWithTransport_pycurl,
333
 
                                     TestInvalidStatusServer,
334
 
                                     TestCaseWithWebserver):
335
 
    """Tests invalid status server for pycurl implementation"""
336
 
 
337
 
 
338
 
class TestBadProtocolServer(object):
339
 
    """Tests bad protocol from server."""
340
 
 
341
 
    def create_transport_readonly_server(self):
342
 
        return http_server.HttpServer(BadProtocolRequestHandler)
343
 
 
344
 
    def test_http_has(self):
345
 
        server = self.get_readonly_server()
346
 
        t = self._transport(server.get_url())
347
 
        self.assertRaises(errors.InvalidHttpResponse, t.has, 'foo/bar')
348
 
 
349
 
    def test_http_get(self):
350
 
        server = self.get_readonly_server()
351
 
        t = self._transport(server.get_url())
352
 
        self.assertRaises(errors.InvalidHttpResponse, t.get, 'foo/bar')
353
 
 
354
 
 
355
 
class TestBadProtocolServer_urllib(TestBadProtocolServer,
356
 
                                   TestCaseWithWebserver):
357
 
    """Tests bad protocol server for urllib implementation"""
358
 
 
359
 
    _transport = HttpTransport_urllib
360
 
 
361
 
# curl don't check the protocol version
362
 
#class TestBadProtocolServer_pycurl(TestWithTransport_pycurl,
363
 
#                                   TestBadProtocolServer,
364
 
#                                   TestCaseWithWebserver):
365
 
#    """Tests bad protocol server for pycurl implementation"""
366
 
 
367
 
 
368
 
class TestForbiddenServer(object):
369
 
    """Tests forbidden server"""
370
 
 
371
 
    def create_transport_readonly_server(self):
372
 
        return http_server.HttpServer(ForbiddenRequestHandler)
373
 
 
374
 
    def test_http_has(self):
375
 
        server = self.get_readonly_server()
376
 
        t = self._transport(server.get_url())
377
 
        self.assertRaises(errors.TransportError, t.has, 'foo/bar')
378
 
 
379
 
    def test_http_get(self):
380
 
        server = self.get_readonly_server()
381
 
        t = self._transport(server.get_url())
382
 
        self.assertRaises(errors.TransportError, t.get, 'foo/bar')
383
 
 
384
 
 
385
 
class TestForbiddenServer_urllib(TestForbiddenServer, TestCaseWithWebserver):
386
 
    """Tests forbidden server for urllib implementation"""
387
 
 
388
 
    _transport = HttpTransport_urllib
389
 
 
390
 
 
391
 
class TestForbiddenServer_pycurl(TestWithTransport_pycurl,
392
 
                                 TestForbiddenServer,
393
 
                                 TestCaseWithWebserver):
394
 
    """Tests forbidden server for pycurl implementation"""
395
 
 
396
 
 
397
227
class TestRecordingServer(tests.TestCase):
398
228
 
399
229
    def test_create(self):
425
255
        self.assertEqual('abc', server.received_bytes)
426
256
 
427
257
 
428
 
class TestRangeRequestServer(object):
429
 
    """Tests readv requests against server.
430
 
 
431
 
    This MUST be used by daughter classes that also inherit from
432
 
    TestCaseWithWebserver.
433
 
 
434
 
    We can't inherit directly from TestCaseWithWebserver or the
435
 
    test framework will try to create an instance which cannot
436
 
    run, its implementation being incomplete.
437
 
    """
438
 
 
439
 
    def setUp(self):
440
 
        TestCaseWithWebserver.setUp(self)
441
 
        self.build_tree_contents([('a', '0123456789')],)
442
 
 
443
 
    def test_readv(self):
444
 
        server = self.get_readonly_server()
445
 
        t = self._transport(server.get_url())
446
 
        l = list(t.readv('a', ((0, 1), (1, 1), (3, 2), (9, 1))))
447
 
        self.assertEqual(l[0], (0, '0'))
448
 
        self.assertEqual(l[1], (1, '1'))
449
 
        self.assertEqual(l[2], (3, '34'))
450
 
        self.assertEqual(l[3], (9, '9'))
451
 
 
452
 
    def test_readv_out_of_order(self):
453
 
        server = self.get_readonly_server()
454
 
        t = self._transport(server.get_url())
455
 
        l = list(t.readv('a', ((1, 1), (9, 1), (0, 1), (3, 2))))
456
 
        self.assertEqual(l[0], (1, '1'))
457
 
        self.assertEqual(l[1], (9, '9'))
458
 
        self.assertEqual(l[2], (0, '0'))
459
 
        self.assertEqual(l[3], (3, '34'))
460
 
 
461
 
    def test_readv_invalid_ranges(self):
462
 
        server = self.get_readonly_server()
463
 
        t = self._transport(server.get_url())
464
 
 
465
 
        # This is intentionally reading off the end of the file
466
 
        # since we are sure that it cannot get there
467
 
        self.assertListRaises((errors.InvalidRange, errors.ShortReadvError,),
468
 
                              t.readv, 'a', [(1,1), (8,10)])
469
 
 
470
 
        # This is trying to seek past the end of the file, it should
471
 
        # also raise a special error
472
 
        self.assertListRaises((errors.InvalidRange, errors.ShortReadvError,),
473
 
                              t.readv, 'a', [(12,2)])
474
 
 
475
 
    def test_readv_multiple_get_requests(self):
476
 
        server = self.get_readonly_server()
477
 
        t = self._transport(server.get_url())
478
 
        # force transport to issue multiple requests
479
 
        t._max_readv_combine = 1
480
 
        t._max_get_ranges = 1
481
 
        l = list(t.readv('a', ((0, 1), (1, 1), (3, 2), (9, 1))))
482
 
        self.assertEqual(l[0], (0, '0'))
483
 
        self.assertEqual(l[1], (1, '1'))
484
 
        self.assertEqual(l[2], (3, '34'))
485
 
        self.assertEqual(l[3], (9, '9'))
486
 
        # The server should have issued 4 requests
487
 
        self.assertEqual(4, server.GET_request_nb)
488
 
 
489
 
    def test_readv_get_max_size(self):
490
 
        server = self.get_readonly_server()
491
 
        t = self._transport(server.get_url())
492
 
        # force transport to issue multiple requests by limiting the number of
493
 
        # bytes by request. Note that this apply to coalesced offsets only, a
494
 
        # single range ill keep its size even if bigger than the limit.
495
 
        t._get_max_size = 2
496
 
        l = list(t.readv('a', ((0, 1), (1, 1), (2, 4), (6, 4))))
497
 
        self.assertEqual(l[0], (0, '0'))
498
 
        self.assertEqual(l[1], (1, '1'))
499
 
        self.assertEqual(l[2], (2, '2345'))
500
 
        self.assertEqual(l[3], (6, '6789'))
501
 
        # The server should have issued 3 requests
502
 
        self.assertEqual(3, server.GET_request_nb)
503
 
 
504
 
 
505
 
class TestSingleRangeRequestServer(TestRangeRequestServer):
506
 
    """Test readv against a server which accept only single range requests"""
507
 
 
508
 
    def create_transport_readonly_server(self):
509
 
        return http_server.HttpServer(SingleRangeRequestHandler)
510
 
 
511
 
 
512
 
class TestSingleRangeRequestServer_urllib(TestSingleRangeRequestServer,
513
 
                                          TestCaseWithWebserver):
514
 
    """Tests single range requests accepting server for urllib implementation"""
515
 
 
516
 
    _transport = HttpTransport_urllib
517
 
 
518
 
 
519
 
class TestSingleRangeRequestServer_pycurl(TestWithTransport_pycurl,
520
 
                                          TestSingleRangeRequestServer,
521
 
                                          TestCaseWithWebserver):
522
 
    """Tests single range requests accepting server for pycurl implementation"""
523
 
 
524
 
 
525
 
class TestSingleOnlyRangeRequestServer(TestRangeRequestServer):
526
 
    """Test readv against a server which only accept single range requests"""
527
 
 
528
 
    def create_transport_readonly_server(self):
529
 
        return http_server.HttpServer(SingleOnlyRangeRequestHandler)
530
 
 
531
 
 
532
 
class TestSingleOnlyRangeRequestServer_urllib(TestSingleOnlyRangeRequestServer,
533
 
                                              TestCaseWithWebserver):
534
 
    """Tests single range requests accepting server for urllib implementation"""
535
 
 
536
 
    _transport = HttpTransport_urllib
537
 
 
538
 
 
539
 
class TestSingleOnlyRangeRequestServer_pycurl(TestWithTransport_pycurl,
540
 
                                              TestSingleOnlyRangeRequestServer,
541
 
                                              TestCaseWithWebserver):
542
 
    """Tests single range requests accepting server for pycurl implementation"""
543
 
 
544
 
 
545
 
class TestNoRangeRequestServer(TestRangeRequestServer):
546
 
    """Test readv against a server which do not accept range requests"""
547
 
 
548
 
    def create_transport_readonly_server(self):
549
 
        return http_server.HttpServer(NoRangeRequestHandler)
550
 
 
551
 
 
552
 
class TestNoRangeRequestServer_urllib(TestNoRangeRequestServer,
553
 
                                      TestCaseWithWebserver):
554
 
    """Tests range requests refusing server for urllib implementation"""
555
 
 
556
 
    _transport = HttpTransport_urllib
557
 
 
558
 
 
559
 
class TestNoRangeRequestServer_pycurl(TestWithTransport_pycurl,
560
 
                                      TestNoRangeRequestServer,
561
 
                                      TestCaseWithWebserver):
562
 
    """Tests range requests refusing server for pycurl implementation"""
563
 
 
564
 
 
565
 
class TestLimitedRangeRequestServer(object):
566
 
    """Tests readv requests against server that errors out on too much ranges.
567
 
 
568
 
    This MUST be used by daughter classes that also inherit from
569
 
    TestCaseWithWebserver.
570
 
 
571
 
    We can't inherit directly from TestCaseWithWebserver or the
572
 
    test framework will try to create an instance which cannot
573
 
    run, its implementation being incomplete.
574
 
    """
575
 
 
576
 
    range_limit = 3
577
 
 
578
 
    def create_transport_readonly_server(self):
579
 
        # Requests with more range specifiers will error out
580
 
        return LimitedRangeHTTPServer(range_limit=self.range_limit)
581
 
 
582
 
    def get_transport(self):
583
 
        return self._transport(self.get_readonly_server().get_url())
584
 
 
585
 
    def setUp(self):
586
 
        TestCaseWithWebserver.setUp(self)
587
 
        # We need to manipulate ranges that correspond to real chunks in the
588
 
        # response, so we build a content appropriately.
589
 
        filler = ''.join(['abcdefghij' for x in range(102)])
590
 
        content = ''.join(['%04d' % v + filler for v in range(16)])
591
 
        self.build_tree_contents([('a', content)],)
592
 
 
593
 
    def test_few_ranges(self):
594
 
        t = self.get_transport()
595
 
        l = list(t.readv('a', ((0, 4), (1024, 4), )))
596
 
        self.assertEqual(l[0], (0, '0000'))
597
 
        self.assertEqual(l[1], (1024, '0001'))
598
 
        self.assertEqual(1, self.get_readonly_server().GET_request_nb)
599
 
 
600
 
    def test_more_ranges(self):
601
 
        t = self.get_transport()
602
 
        l = list(t.readv('a', ((0, 4), (1024, 4), (4096, 4), (8192, 4))))
603
 
        self.assertEqual(l[0], (0, '0000'))
604
 
        self.assertEqual(l[1], (1024, '0001'))
605
 
        self.assertEqual(l[2], (4096, '0004'))
606
 
        self.assertEqual(l[3], (8192, '0008'))
607
 
        # The server will refuse to serve the first request (too much ranges),
608
 
        # a second request will succeeds.
609
 
        self.assertEqual(2, self.get_readonly_server().GET_request_nb)
610
 
 
611
 
 
612
 
class TestLimitedRangeRequestServer_urllib(TestLimitedRangeRequestServer,
613
 
                                          TestCaseWithWebserver):
614
 
    """Tests limited range requests server for urllib implementation"""
615
 
 
616
 
    _transport = HttpTransport_urllib
617
 
 
618
 
 
619
 
class TestLimitedRangeRequestServer_pycurl(TestWithTransport_pycurl,
620
 
                                          TestLimitedRangeRequestServer,
621
 
                                          TestCaseWithWebserver):
622
 
    """Tests limited range requests server for pycurl implementation"""
623
 
 
624
 
 
625
 
 
626
258
class TestHttpProxyWhiteBox(tests.TestCase):
627
259
    """Whitebox test proxy http authorization.
628
260