~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_http.py

  • Committer: Alexander Belchenko
  • Date: 2006-12-19 08:26:36 UTC
  • mfrom: (2198 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2204.
  • Revision ID: bialix@ukr.net-20061219082636-xbb55np3wnamva8t
merge bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
# implementation; at the moment we have urllib and pycurl.
19
19
 
20
20
# TODO: Should be renamed to bzrlib.transport.http.tests?
 
21
# TODO: What about renaming to bzrlib.tests.transport.http ?
21
22
 
 
23
import os
22
24
import select
23
25
import socket
24
26
import threading
38
40
from bzrlib.tests.HTTPTestUtil import (
39
41
    BadProtocolRequestHandler,
40
42
    BadStatusRequestHandler,
 
43
    FakeProxyRequestHandler,
41
44
    ForbiddenRequestHandler,
42
45
    InvalidStatusRequestHandler,
43
46
    NoRangeRequestHandler,
44
47
    SingleRangeRequestHandler,
 
48
    TestCaseWithTwoWebservers,
45
49
    TestCaseWithWebserver,
46
50
    WallRequestHandler,
47
51
    )
108
112
        except socket.timeout:
109
113
            # Make sure the client isn't stuck waiting for us to e.g. accept.
110
114
            self._sock.close()
 
115
        except socket.error:
 
116
            # The client may have already closed the socket.
 
117
            pass
111
118
 
112
119
    def tearDown(self):
113
120
        try:
300
307
        self.assertEqual([[10, 12], [22, 26]], ranges)
301
308
 
302
309
 
303
 
class TestPost(TestCase):
 
310
class TestPost(object):
304
311
 
305
312
    def _test_post_body_is_received(self, scheme):
306
313
        server = RecordingServer(expect_body_tail='end-of-body')
321
328
        self.assertTrue(
322
329
            server.received_bytes.endswith('\r\n\r\nabc def end-of-body'))
323
330
 
 
331
 
 
332
class TestPost_urllib(TestCase, TestPost):
 
333
    """TestPost for urllib implementation"""
 
334
 
 
335
    _transport = HttpTransport_urllib
 
336
 
324
337
    def test_post_body_is_received_urllib(self):
325
338
        self._test_post_body_is_received('http+urllib')
326
339
 
 
340
 
 
341
class TestPost_pycurl(TestWithTransport_pycurl, TestCase, TestPost):
 
342
    """TestPost for pycurl implementation"""
 
343
 
327
344
    def test_post_body_is_received_pycurl(self):
328
345
        self._test_post_body_is_received('http+pycurl')
329
346
 
532
549
 
533
550
 
534
551
class TestRangeRequestServer(object):
535
 
    """Test the http connections.
 
552
    """Tests readv requests against server.
536
553
 
537
554
    This MUST be used by daughter classes that also inherit from
538
555
    TestCaseWithWebserver.
546
563
        TestCaseWithWebserver.setUp(self)
547
564
        self.build_tree_contents([('a', '0123456789')],)
548
565
 
549
 
    """Tests readv requests against server"""
550
 
 
551
566
    def test_readv(self):
552
567
        server = self.get_readonly_server()
553
568
        t = self._transport(server.get_url())
566
581
        self.assertEqual(l[2], (0, '0'))
567
582
        self.assertEqual(l[3], (3, '34'))
568
583
 
569
 
    def test_readv_short_read(self):
 
584
    def test_readv_invalid_ranges(self):
570
585
        server = self.get_readonly_server()
571
586
        t = self._transport(server.get_url())
572
587
 
573
588
        # This is intentionally reading off the end of the file
574
589
        # since we are sure that it cannot get there
575
 
        self.assertListRaises((errors.ShortReadvError, AssertionError),
 
590
        self.assertListRaises((errors.InvalidRange, errors.ShortReadvError,),
576
591
                              t.readv, 'a', [(1,1), (8,10)])
577
592
 
578
593
        # This is trying to seek past the end of the file, it should
579
594
        # also raise a special error
580
 
        self.assertListRaises(errors.ShortReadvError,
 
595
        self.assertListRaises((errors.InvalidRange, errors.ShortReadvError,),
581
596
                              t.readv, 'a', [(12,2)])
582
597
 
583
598
 
621
636
    """Tests range requests refusing server for pycurl implementation"""
622
637
 
623
638
 
 
639
class TestProxyHttpServer(object):
 
640
    """Tests proxy server.
 
641
 
 
642
    This MUST be used by daughter classes that also inherit from
 
643
    TestCaseWithTwoWebservers.
 
644
 
 
645
    We can't inherit directly from TestCaseWithTwoWebservers or
 
646
    the test framework will try to create an instance which
 
647
    cannot run, its implementation being incomplete.
 
648
 
 
649
    Be aware that we do not setup a real proxy here. Instead, we
 
650
    check that the *connection* goes through the proxy by serving
 
651
    different content (the faked proxy server append '-proxied'
 
652
    to the file names).
 
653
    """
 
654
 
 
655
    # FIXME: We don't have an https server available, so we don't
 
656
    # test https connections.
 
657
 
 
658
    def setUp(self):
 
659
        TestCaseWithTwoWebservers.setUp(self)
 
660
        self.build_tree_contents([('foo', 'contents of foo\n'),
 
661
                                  ('foo-proxied', 'proxied contents of foo\n')])
 
662
        # Let's setup some attributes for tests
 
663
        self.server = self.get_readonly_server()
 
664
        self.no_proxy_host = 'localhost:%d' % self.server.port
 
665
        # The secondary server is the proxy
 
666
        self.proxy = self.get_secondary_server()
 
667
        self.proxy_url = self.proxy.get_url()
 
668
        self._old_env = {}
 
669
 
 
670
    def create_transport_secondary_server(self):
 
671
        """Creates an http server that will serve files with
 
672
        '-proxied' appended to their names.
 
673
        """
 
674
        return HttpServer(FakeProxyRequestHandler)
 
675
 
 
676
    def _set_and_capture_env_var(self, name, new_value):
 
677
        """Set an environment variable, and reset it when finished."""
 
678
        self._old_env[name] = osutils.set_or_unset_env(name, new_value)
 
679
 
 
680
    def _install_env(self, env):
 
681
        for name, value in env.iteritems():
 
682
            self._set_and_capture_env_var(name, value)
 
683
 
 
684
    def _restore_env(self):
 
685
        for name, value in self._old_env.iteritems():
 
686
            osutils.set_or_unset_env(name, value)
 
687
 
 
688
    def proxied_in_env(self, env):
 
689
        self._install_env(env)
 
690
        url = self.server.get_url()
 
691
        t = self._transport(url)
 
692
        try:
 
693
            self.assertEqual(t.get('foo').read(), 'proxied contents of foo\n')
 
694
        finally:
 
695
            self._restore_env()
 
696
 
 
697
    def not_proxied_in_env(self, env):
 
698
        self._install_env(env)
 
699
        url = self.server.get_url()
 
700
        t = self._transport(url)
 
701
        try:
 
702
            self.assertEqual(t.get('foo').read(), 'contents of foo\n')
 
703
        finally:
 
704
            self._restore_env()
 
705
 
 
706
    def test_http_proxy(self):
 
707
        self.proxied_in_env({'http_proxy': self.proxy_url})
 
708
 
 
709
    def test_HTTP_PROXY(self):
 
710
        self.proxied_in_env({'HTTP_PROXY': self.proxy_url})
 
711
 
 
712
    def test_all_proxy(self):
 
713
        self.proxied_in_env({'all_proxy': self.proxy_url})
 
714
 
 
715
    def test_ALL_PROXY(self):
 
716
        self.proxied_in_env({'ALL_PROXY': self.proxy_url})
 
717
 
 
718
    def test_http_proxy_with_no_proxy(self):
 
719
        self.not_proxied_in_env({'http_proxy': self.proxy_url,
 
720
                                 'no_proxy': self.no_proxy_host})
 
721
 
 
722
    def test_HTTP_PROXY_with_NO_PROXY(self):
 
723
        self.not_proxied_in_env({'HTTP_PROXY': self.proxy_url,
 
724
                                 'NO_PROXY': self.no_proxy_host})
 
725
 
 
726
    def test_all_proxy_with_no_proxy(self):
 
727
        self.not_proxied_in_env({'all_proxy': self.proxy_url,
 
728
                                 'no_proxy': self.no_proxy_host})
 
729
 
 
730
    def test_ALL_PROXY_with_NO_PROXY(self):
 
731
        self.not_proxied_in_env({'ALL_PROXY': self.proxy_url,
 
732
                                 'NO_PROXY': self.no_proxy_host})
 
733
 
 
734
 
 
735
class TestProxyHttpServer_urllib(TestProxyHttpServer,
 
736
                                 TestCaseWithTwoWebservers):
 
737
    """Tests proxy server for urllib implementation"""
 
738
 
 
739
    _transport = HttpTransport_urllib
 
740
 
 
741
 
 
742
class TestProxyHttpServer_pycurl(TestWithTransport_pycurl,
 
743
                                 TestProxyHttpServer,
 
744
                                 TestCaseWithTwoWebservers):
 
745
    """Tests proxy server for pycurl implementation"""
 
746
 
 
747
    def setUp(self):
 
748
        TestProxyHttpServer.setUp(self)
 
749
        # Oh my ! pycurl does not check for the port as part of
 
750
        # no_proxy :-( So we just test the host part
 
751
        self.no_proxy_host = 'localhost'
 
752
 
 
753
    def test_HTTP_PROXY(self):
 
754
        # pycurl do not check HTTP_PROXY for security reasons
 
755
        # (for use in a CGI context that we do not care
 
756
        # about. Should we ?)
 
757
        raise TestSkipped()
 
758
 
 
759
    def test_HTTP_PROXY_with_NO_PROXY(self):
 
760
        raise TestSkipped()
 
761
 
 
762
 
 
763
class TestRanges(object):
 
764
    """Test the Range header in GET methods..
 
765
 
 
766
    This MUST be used by daughter classes that also inherit from
 
767
    TestCaseWithWebserver.
 
768
 
 
769
    We can't inherit directly from TestCaseWithWebserver or the
 
770
    test framework will try to create an instance which cannot
 
771
    run, its implementation being incomplete.
 
772
    """
 
773
 
 
774
    def setUp(self):
 
775
        TestCaseWithWebserver.setUp(self)
 
776
        self.build_tree_contents([('a', '0123456789')],)
 
777
        server = self.get_readonly_server()
 
778
        self.transport = self._transport(server.get_url())
 
779
 
 
780
    def _file_contents(self, relpath, ranges, tail_amount=0):
 
781
         code, data = self.transport._get(relpath, ranges)
 
782
         self.assertTrue(code in (200, 206),'_get returns: %d' % code)
 
783
         for start, end in ranges:
 
784
             data.seek(start)
 
785
             yield data.read(end - start + 1)
 
786
 
 
787
    def _file_tail(self, relpath, tail_amount):
 
788
         code, data = self.transport._get(relpath, [], tail_amount)
 
789
         self.assertTrue(code in (200, 206),'_get returns: %d' % code)
 
790
         data.seek(-tail_amount + 1, 2)
 
791
         return data.read(tail_amount)
 
792
 
 
793
    def test_range_header(self):
 
794
        # Valid ranges
 
795
        map(self.assertEqual,['0', '234'],
 
796
            list(self._file_contents('a', [(0,0), (2,4)])),)
 
797
        # Tail
 
798
        self.assertEqual('789', self._file_tail('a', 3))
 
799
        # Syntactically invalid range
 
800
        self.assertRaises(errors.InvalidRange,
 
801
                          self.transport._get, 'a', [(4, 3)])
 
802
        # Semantically invalid range
 
803
        self.assertRaises(errors.InvalidRange,
 
804
                          self.transport._get, 'a', [(42, 128)])
 
805
 
 
806
 
 
807
class TestRanges_urllib(TestRanges, TestCaseWithWebserver):
 
808
    """Test the Range header in GET methods for urllib implementation"""
 
809
 
 
810
    _transport = HttpTransport_urllib
 
811
 
 
812
 
 
813
class TestRanges_pycurl(TestWithTransport_pycurl,
 
814
                        TestRanges,
 
815
                        TestCaseWithWebserver):
 
816
    """Test the Range header in GET methods for pycurl implementation"""