~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_http.py

  • Committer: mbp at sourcefrog
  • Date: 2005-03-21 22:29:49 UTC
  • Revision ID: mbp@sourcefrog.net-20050321222949-232c2093a6eadd80
fixup doctest for new module structure

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 Canonical
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 socket
23
 
 
24
 
import bzrlib
25
 
from bzrlib.errors import DependencyNotPresent
26
 
from bzrlib.tests import TestCase, TestSkipped
27
 
from bzrlib.transport import Transport
28
 
from bzrlib.transport.http import extract_auth, HttpTransportBase
29
 
from bzrlib.transport.http._urllib import HttpTransport_urllib
30
 
from bzrlib.tests.HTTPTestUtil import TestCaseWithWebserver
31
 
 
32
 
 
33
 
class FakeManager (object):
34
 
 
35
 
    def __init__(self):
36
 
        self.credentials = []
37
 
        
38
 
    def add_password(self, realm, host, username, password):
39
 
        self.credentials.append([realm, host, username, password])
40
 
 
41
 
 
42
 
class TestHttpUrls(TestCase):
43
 
 
44
 
    def test_url_parsing(self):
45
 
        f = FakeManager()
46
 
        url = extract_auth('http://example.com', f)
47
 
        self.assertEquals('http://example.com', url)
48
 
        self.assertEquals(0, len(f.credentials))
49
 
        url = extract_auth('http://user:pass@www.bazaar-vcs.org/bzr/bzr.dev', f)
50
 
        self.assertEquals('http://www.bazaar-vcs.org/bzr/bzr.dev', url)
51
 
        self.assertEquals(1, len(f.credentials))
52
 
        self.assertEquals([None, 'www.bazaar-vcs.org', 'user', 'pass'], f.credentials[0])
53
 
        
54
 
    def test_abs_url(self):
55
 
        """Construction of absolute http URLs"""
56
 
        t = HttpTransport_urllib('http://bazaar-vcs.org/bzr/bzr.dev/')
57
 
        eq = self.assertEqualDiff
58
 
        eq(t.abspath('.'),
59
 
           'http://bazaar-vcs.org/bzr/bzr.dev')
60
 
        eq(t.abspath('foo/bar'), 
61
 
           'http://bazaar-vcs.org/bzr/bzr.dev/foo/bar')
62
 
        eq(t.abspath('.bzr'),
63
 
           'http://bazaar-vcs.org/bzr/bzr.dev/.bzr')
64
 
        eq(t.abspath('.bzr/1//2/./3'),
65
 
           'http://bazaar-vcs.org/bzr/bzr.dev/.bzr/1/2/3')
66
 
 
67
 
    def test_invalid_http_urls(self):
68
 
        """Trap invalid construction of urls"""
69
 
        t = HttpTransport_urllib('http://bazaar-vcs.org/bzr/bzr.dev/')
70
 
        self.assertRaises(ValueError,
71
 
            t.abspath,
72
 
            '.bzr/')
73
 
 
74
 
    def test_http_root_urls(self):
75
 
        """Construction of URLs from server root"""
76
 
        t = HttpTransport_urllib('http://bzr.ozlabs.org/')
77
 
        eq = self.assertEqualDiff
78
 
        eq(t.abspath('.bzr/tree-version'),
79
 
           'http://bzr.ozlabs.org/.bzr/tree-version')
80
 
 
81
 
    def test_http_impl_urls(self):
82
 
        """There are servers which ask for particular clients to connect"""
83
 
        try:
84
 
            from bzrlib.transport.http._pycurl import HttpServer_PyCurl
85
 
            server = HttpServer_PyCurl()
86
 
            try:
87
 
                server.setUp()
88
 
                url = server.get_url()
89
 
                self.assertTrue(url.startswith('http+pycurl://'))
90
 
            finally:
91
 
                server.tearDown()
92
 
        except DependencyNotPresent:
93
 
            raise TestSkipped('pycurl not present')
94
 
 
95
 
 
96
 
class TestHttpMixins(object):
97
 
 
98
 
    def _prep_tree(self):
99
 
        self.build_tree(['xxx', 'foo/', 'foo/bar'], line_endings='binary',
100
 
                        transport=self.get_transport())
101
 
 
102
 
    def test_http_has(self):
103
 
        server = self.get_readonly_server()
104
 
        t = self._transport(server.get_url())
105
 
        self.assertEqual(t.has('foo/bar'), True)
106
 
        self.assertEqual(len(server.logs), 1)
107
 
        self.assertContainsRe(server.logs[0], 
108
 
            r'"HEAD /foo/bar HTTP/1.." (200|302) - "-" "bzr/')
109
 
 
110
 
    def test_http_has_not_found(self):
111
 
        server = self.get_readonly_server()
112
 
        t = self._transport(server.get_url())
113
 
        self.assertEqual(t.has('not-found'), False)
114
 
        self.assertContainsRe(server.logs[1], 
115
 
            r'"HEAD /not-found HTTP/1.." 404 - "-" "bzr/')
116
 
 
117
 
    def test_http_get(self):
118
 
        server = self.get_readonly_server()
119
 
        t = self._transport(server.get_url())
120
 
        fp = t.get('foo/bar')
121
 
        self.assertEqualDiff(
122
 
            fp.read(),
123
 
            'contents of foo/bar\n')
124
 
        self.assertEqual(len(server.logs), 1)
125
 
        self.assertTrue(server.logs[0].find(
126
 
            '"GET /foo/bar HTTP/1.1" 200 - "-" "bzr/%s' % bzrlib.__version__) > -1)
127
 
 
128
 
 
129
 
class TestHttpConnections_urllib(TestCaseWithWebserver, TestHttpMixins):
130
 
 
131
 
    _transport = HttpTransport_urllib
132
 
 
133
 
    def setUp(self):
134
 
        TestCaseWithWebserver.setUp(self)
135
 
        self._prep_tree()
136
 
 
137
 
    def test_has_on_bogus_host(self):
138
 
        import urllib2
139
 
        # Get a random address, so that we can be sure there is no
140
 
        # http handler there.
141
 
        s = socket.socket()
142
 
        s.bind(('localhost', 0))
143
 
        t = self._transport('http://%s:%s/' % s.getsockname())
144
 
        self.assertRaises(urllib2.URLError, t.has, 'foo/bar')
145
 
 
146
 
 
147
 
class TestHttpConnections_pycurl(TestCaseWithWebserver, TestHttpMixins):
148
 
 
149
 
    def _get_pycurl_maybe(self):
150
 
        try:
151
 
            from bzrlib.transport.http._pycurl import PyCurlTransport
152
 
            return PyCurlTransport
153
 
        except DependencyNotPresent:
154
 
            raise TestSkipped('pycurl not present')
155
 
 
156
 
    _transport = property(_get_pycurl_maybe)
157
 
 
158
 
    def setUp(self):
159
 
        TestCaseWithWebserver.setUp(self)
160
 
        self._prep_tree()
161
 
 
162
 
 
163
 
 
164
 
class TestHttpTransportRegistration(TestCase):
165
 
    """Test registrations of various http implementations"""
166
 
 
167
 
    def test_http_registered(self):
168
 
        import bzrlib.transport.http._urllib
169
 
        from bzrlib.transport import get_transport
170
 
        # urlllib should always be present
171
 
        t = get_transport('http+urllib://bzr.google.com/')
172
 
        self.assertIsInstance(t, Transport)
173
 
        self.assertIsInstance(t, bzrlib.transport.http._urllib.HttpTransport_urllib)
174
 
 
175
 
 
176
 
class TestOffsets(TestCase):
177
 
    """Test offsets_to_ranges method"""
178
 
 
179
 
    def test_offsets_to_ranges_simple(self):
180
 
        to_range = HttpTransportBase.offsets_to_ranges
181
 
        ranges = to_range([(10, 1)])
182
 
        self.assertEqual([[10, 10]], ranges)
183
 
 
184
 
        ranges = to_range([(0, 1), (1, 1)])
185
 
        self.assertEqual([[0, 1]], ranges)
186
 
 
187
 
        ranges = to_range([(1, 1), (0, 1)])
188
 
        self.assertEqual([[0, 1]], ranges)
189
 
 
190
 
    def test_offset_to_ranges_overlapped(self):
191
 
        to_range = HttpTransportBase.offsets_to_ranges
192
 
 
193
 
        ranges = to_range([(10, 1), (20, 2), (22, 5)])
194
 
        self.assertEqual([[10, 10], [20, 26]], ranges)
195
 
 
196
 
        ranges = to_range([(10, 1), (11, 2), (22, 5)])
197
 
        self.assertEqual([[10, 12], [22, 26]], ranges)
198
 
 
199
 
 
200
 
class TestRangeHeader(TestCase):
201
 
    """Test range_header method"""
202
 
 
203
 
    def check_header(self, value, ranges=[], tail=0):
204
 
        range_header = HttpTransportBase.range_header
205
 
        self.assertEqual(value, range_header(ranges, tail))
206
 
 
207
 
    def test_range_header_single(self):
208
 
        self.check_header('0-9', ranges=[[0,9]])
209
 
        self.check_header('100-109', ranges=[[100,109]])
210
 
 
211
 
    def test_range_header_tail(self):
212
 
        self.check_header('-10', tail=10)
213
 
        self.check_header('-50', tail=50)
214
 
 
215
 
    def test_range_header_multi(self):
216
 
        self.check_header('0-9,100-200,300-5000',
217
 
                          ranges=[(0,9), (100, 200), (300,5000)])
218
 
 
219
 
    def test_range_header_mixed(self):
220
 
        self.check_header('0-9,300-5000,-50',
221
 
                          ranges=[(0,9), (300,5000)],
222
 
                          tail=50)