202
204
def test_invalid_http_urls(self):
203
205
"""Trap invalid construction of urls"""
204
206
t = self._transport('http://bazaar-vcs.org/bzr/bzr.dev/')
205
self.assertRaises(ValueError, t.abspath, '.bzr/')
206
t = self._transport('http://http://bazaar-vcs.org/bzr/bzr.dev/')
207
207
self.assertRaises((errors.InvalidURL, errors.ConnectionError),
209
'http://http://bazaar-vcs.org/bzr/bzr.dev/')
210
211
def test_http_root_urls(self):
211
212
"""Construction of URLs from server root"""
361
362
self.assertIsInstance(t, HttpTransport_urllib)
364
class TestOffsets(TestCase):
365
"""Test offsets_to_ranges method"""
367
def test_offsets_to_ranges_simple(self):
368
to_range = HttpTransportBase.offsets_to_ranges
369
ranges = to_range([(10, 1)])
370
self.assertEqual([[10, 10]], ranges)
372
ranges = to_range([(0, 1), (1, 1)])
373
self.assertEqual([[0, 1]], ranges)
375
ranges = to_range([(1, 1), (0, 1)])
376
self.assertEqual([[0, 1]], ranges)
378
def test_offset_to_ranges_overlapped(self):
379
to_range = HttpTransportBase.offsets_to_ranges
381
ranges = to_range([(10, 1), (20, 2), (22, 5)])
382
self.assertEqual([[10, 10], [20, 26]], ranges)
384
ranges = to_range([(10, 1), (11, 2), (22, 5)])
385
self.assertEqual([[10, 12], [22, 26]], ranges)
388
365
class TestPost(object):
390
367
def _test_post_body_is_received(self, scheme):
427
404
"""Test range_header method"""
429
406
def check_header(self, value, ranges=[], tail=0):
430
range_header = HttpTransportBase.range_header
431
self.assertEqual(value, range_header(ranges, tail))
407
offsets = [ (start, end - start + 1) for start, end in ranges]
408
coalesce = Transport._coalesce_offsets
409
coalesced = list(coalesce(offsets, limit=0, fudge_factor=0))
410
range_header = HttpTransportBase._range_header
411
self.assertEqual(value, range_header(coalesced, tail))
433
413
def test_range_header_single(self):
434
self.check_header('0-9', ranges=[[0,9]])
435
self.check_header('100-109', ranges=[[100,109]])
414
self.check_header('0-9', ranges=[(0,9)])
415
self.check_header('100-109', ranges=[(100,109)])
437
417
def test_range_header_tail(self):
438
418
self.check_header('-10', tail=10)
734
714
"""Tests range requests refusing server for pycurl implementation"""
717
class TestLimitedRangeRequestServer(object):
718
"""Tests readv requests against server that errors out on too much ranges.
720
This MUST be used by daughter classes that also inherit from
721
TestCaseWithWebserver.
723
We can't inherit directly from TestCaseWithWebserver or the
724
test framework will try to create an instance which cannot
725
run, its implementation being incomplete.
730
def create_transport_readonly_server(self):
731
# Requests with more range specifiers will error out
732
return LimitedRangeHTTPServer(range_limit=self.range_limit)
734
def get_transport(self):
735
return self._transport(self.get_readonly_server().get_url())
738
TestCaseWithWebserver.setUp(self)
739
# We need to manipulate ranges that correspond to real chunks in the
740
# response, so we build a content appropriately.
741
filler = ''.join(['abcdefghij' for _ in range(102)])
742
content = ''.join(['%04d' % v + filler for v in range(16)])
743
self.build_tree_contents([('a', content)],)
745
def test_few_ranges(self):
746
t = self.get_transport()
747
l = list(t.readv('a', ((0, 4), (1024, 4), )))
748
self.assertEqual(l[0], (0, '0000'))
749
self.assertEqual(l[1], (1024, '0001'))
750
self.assertEqual(1, self.get_readonly_server().GET_request_nb)
752
def test_a_lot_of_ranges(self):
753
t = self.get_transport()
754
l = list(t.readv('a', ((0, 4), (1024, 4), (4096, 4), (8192, 4))))
755
self.assertEqual(l[0], (0, '0000'))
756
self.assertEqual(l[1], (1024, '0001'))
757
self.assertEqual(l[2], (4096, '0004'))
758
self.assertEqual(l[3], (8192, '0008'))
759
# The server will refuse to serve the first request (too much ranges),
760
# a second request will succeeds.
761
self.assertEqual(2, self.get_readonly_server().GET_request_nb)
764
class TestLimitedRangeRequestServer_urllib(TestLimitedRangeRequestServer,
765
TestCaseWithWebserver):
766
"""Tests limited range requests server for urllib implementation"""
768
_transport = HttpTransport_urllib
771
class TestLimitedRangeRequestServer_pycurl(TestWithTransport_pycurl,
772
TestLimitedRangeRequestServer,
773
TestCaseWithWebserver):
774
"""Tests limited range requests server for pycurl implementation"""
737
778
class TestHttpProxyWhiteBox(TestCase):
738
779
"""Whitebox test proxy http authorization.
926
967
server = self.get_readonly_server()
927
968
self.transport = self._transport(server.get_url())
929
def _file_contents(self, relpath, ranges, tail_amount=0):
930
code, data = self.transport._get(relpath, ranges)
931
self.assertTrue(code in (200, 206),'_get returns: %d' % code)
932
for start, end in ranges:
934
yield data.read(end - start + 1)
970
def _file_contents(self, relpath, ranges):
971
offsets = [ (start, end - start + 1) for start, end in ranges]
972
coalesce = self.transport._coalesce_offsets
973
coalesced = list(coalesce(offsets, limit=0, fudge_factor=0))
974
code, data = self.transport._get(relpath, coalesced)
975
self.assertTrue(code in (200, 206),'_get returns: %d' % code)
976
for start, end in ranges:
978
yield data.read(end - start + 1)
936
980
def _file_tail(self, relpath, tail_amount):
937
code, data = self.transport._get(relpath, [], tail_amount)
938
self.assertTrue(code in (200, 206),'_get returns: %d' % code)
939
data.seek(-tail_amount + 1, 2)
940
return data.read(tail_amount)
981
code, data = self.transport._get(relpath, [], tail_amount)
982
self.assertTrue(code in (200, 206),'_get returns: %d' % code)
983
data.seek(-tail_amount + 1, 2)
984
return data.read(tail_amount)
942
986
def test_range_header(self):
947
991
self.assertEqual('789', self._file_tail('a', 3))
948
992
# Syntactically invalid range
949
self.assertRaises(errors.InvalidRange,
950
self.transport._get, 'a', [(4, 3)])
993
self.assertListRaises(errors.InvalidRange,
994
self._file_contents, 'a', [(4, 3)])
951
995
# Semantically invalid range
952
self.assertRaises(errors.InvalidRange,
953
self.transport._get, 'a', [(42, 128)])
996
self.assertListRaises(errors.InvalidRange,
997
self._file_contents, 'a', [(42, 128)])
956
1000
class TestRanges_urllib(TestRanges, TestCaseWithWebserver):
1176
1220
self.build_tree_contents([('a', 'contents of a\n'),
1177
1221
('b', 'contents of b\n'),])
1178
1222
self.old_factory = ui.ui_factory
1223
# The following has the unfortunate side-effect of hiding any ouput
1224
# during the tests (including pdb prompts). Feel free to comment them
1225
# for debugging purposes but leave them in place, there are needed to
1226
# run the tests without any console
1179
1227
self.old_stdout = sys.stdout
1180
1228
sys.stdout = StringIOWrapper()
1181
1229
self.addCleanup(self.restoreUIFactory)