50
53
class TestTransport(tests.TestCase):
51
54
"""Test the non transport-concrete class functionality."""
53
# FIXME: These tests should use addCleanup() and/or overrideAttr() instead
54
# of try/finally -- vila 20100205
56
56
def test__get_set_protocol_handlers(self):
57
57
handlers = transport._get_protocol_handlers()
58
self.assertNotEqual([], handlers.keys( ))
60
transport._clear_protocol_handlers()
61
self.assertEqual([], transport._get_protocol_handlers().keys())
63
transport._set_protocol_handlers(handlers)
58
self.assertNotEqual([], handlers.keys())
59
transport._clear_protocol_handlers()
60
self.addCleanup(transport._set_protocol_handlers, handlers)
61
self.assertEqual([], transport._get_protocol_handlers().keys())
65
63
def test_get_transport_modules(self):
66
64
handlers = transport._get_protocol_handlers()
65
self.addCleanup(transport._set_protocol_handlers, handlers)
67
66
# don't pollute the current handlers
68
67
transport._clear_protocol_handlers()
69
69
class SampleHandler(object):
70
70
"""I exist, isnt that enough?"""
72
transport._clear_protocol_handlers()
73
transport.register_transport_proto('foo')
74
transport.register_lazy_transport('foo',
75
'bzrlib.tests.test_transport',
76
'TestTransport.SampleHandler')
77
transport.register_transport_proto('bar')
78
transport.register_lazy_transport('bar',
79
'bzrlib.tests.test_transport',
80
'TestTransport.SampleHandler')
81
self.assertEqual([SampleHandler.__module__,
82
'bzrlib.transport.chroot',
83
'bzrlib.transport.pathfilter'],
84
transport._get_transport_modules())
86
transport._set_protocol_handlers(handlers)
71
transport._clear_protocol_handlers()
72
transport.register_transport_proto('foo')
73
transport.register_lazy_transport('foo',
74
'bzrlib.tests.test_transport',
75
'TestTransport.SampleHandler')
76
transport.register_transport_proto('bar')
77
transport.register_lazy_transport('bar',
78
'bzrlib.tests.test_transport',
79
'TestTransport.SampleHandler')
80
self.assertEqual([SampleHandler.__module__,
81
'bzrlib.transport.chroot',
82
'bzrlib.transport.pathfilter'],
83
transport._get_transport_modules())
88
85
def test_transport_dependency(self):
89
86
"""Transport with missing dependency causes no error"""
90
87
saved_handlers = transport._get_protocol_handlers()
88
self.addCleanup(transport._set_protocol_handlers, saved_handlers)
91
89
# don't pollute the current handlers
92
90
transport._clear_protocol_handlers()
91
transport.register_transport_proto('foo')
92
transport.register_lazy_transport(
93
'foo', 'bzrlib.tests.test_transport', 'BadTransportHandler')
94
transport.register_transport_proto('foo')
95
transport.register_lazy_transport(
96
'foo', 'bzrlib.tests.test_transport', 'BadTransportHandler')
98
transport.get_transport('foo://fooserver/foo')
99
except errors.UnsupportedProtocol, e:
101
self.assertEquals('Unsupported protocol'
102
' for url "foo://fooserver/foo":'
103
' Unable to import library "some_lib":'
104
' testing missing dependency', str(e))
106
self.fail('Did not raise UnsupportedProtocol')
108
# restore original values
109
transport._set_protocol_handlers(saved_handlers)
95
transport.get_transport_from_url('foo://fooserver/foo')
96
except errors.UnsupportedProtocol, e:
98
self.assertEqual('Unsupported protocol'
99
' for url "foo://fooserver/foo":'
100
' Unable to import library "some_lib":'
101
' testing missing dependency', str(e))
103
self.fail('Did not raise UnsupportedProtocol')
111
105
def test_transport_fallback(self):
112
106
"""Transport with missing dependency causes no error"""
113
107
saved_handlers = transport._get_protocol_handlers()
115
transport._clear_protocol_handlers()
116
transport.register_transport_proto('foo')
117
transport.register_lazy_transport(
118
'foo', 'bzrlib.tests.test_transport', 'BackupTransportHandler')
119
transport.register_lazy_transport(
120
'foo', 'bzrlib.tests.test_transport', 'BadTransportHandler')
121
t = transport.get_transport('foo://fooserver/foo')
122
self.assertTrue(isinstance(t, BackupTransportHandler))
124
transport._set_protocol_handlers(saved_handlers)
108
self.addCleanup(transport._set_protocol_handlers, saved_handlers)
109
transport._clear_protocol_handlers()
110
transport.register_transport_proto('foo')
111
transport.register_lazy_transport(
112
'foo', 'bzrlib.tests.test_transport', 'BackupTransportHandler')
113
transport.register_lazy_transport(
114
'foo', 'bzrlib.tests.test_transport', 'BadTransportHandler')
115
t = transport.get_transport_from_url('foo://fooserver/foo')
116
self.assertTrue(isinstance(t, BackupTransportHandler))
126
118
def test_ssh_hints(self):
127
119
"""Transport ssh:// should raise an error pointing out bzr+ssh://"""
129
transport.get_transport('ssh://fooserver/foo')
121
transport.get_transport_from_url('ssh://fooserver/foo')
130
122
except errors.UnsupportedProtocol, e:
132
self.assertEquals('Unsupported protocol'
124
self.assertEqual('Unsupported protocol'
133
125
' for url "ssh://fooserver/foo":'
134
126
' bzr supports bzr+ssh to operate over ssh,'
135
127
' use "bzr+ssh://fooserver/foo".',
221
202
def test_coalesce_fudge(self):
222
203
self.check([(10, 30, [(0, 10), (20, 10)]),
223
(100, 10, [(0, 10),]),
204
(100, 10, [(0, 10)]),
224
205
], [(10, 10), (30, 10), (100, 10)],
227
208
def test_coalesce_max_size(self):
228
209
self.check([(10, 20, [(0, 10), (10, 10)]),
229
210
(30, 50, [(0, 50)]),
230
211
# If one range is above max_size, it gets its own coalesced
232
(100, 80, [(0, 80),]),],
213
(100, 80, [(0, 80)]),],
233
214
[(10, 10), (20, 10), (30, 50), (100, 80)],
237
217
def test_coalesce_no_max_size(self):
238
self.check([(10, 170, [(0, 10), (10, 10), (20, 50), (70, 100)]),],
218
self.check([(10, 170, [(0, 10), (10, 10), (20, 50), (70, 100)])],
239
219
[(10, 10), (20, 10), (30, 50), (80, 100)],
242
222
def test_coalesce_default_limit(self):
243
223
# By default we use a 100MB max size.
244
ten_mb = 10*1024*1024
245
self.check([(0, 10*ten_mb, [(i*ten_mb, ten_mb) for i in range(10)]),
224
ten_mb = 10 * 1024 * 1024
225
self.check([(0, 10 * ten_mb, [(i * ten_mb, ten_mb) for i in range(10)]),
246
226
(10*ten_mb, ten_mb, [(0, ten_mb)])],
247
227
[(i*ten_mb, ten_mb) for i in range(11)])
248
self.check([(0, 11*ten_mb, [(i*ten_mb, ten_mb) for i in range(11)]),],
249
[(i*ten_mb, ten_mb) for i in range(11)],
228
self.check([(0, 11 * ten_mb, [(i * ten_mb, ten_mb) for i in range(11)])],
229
[(i * ten_mb, ten_mb) for i in range(11)],
250
230
max_size=1*1024*1024*1024)
460
439
backing_transport = memory.MemoryTransport()
461
440
server = chroot.ChrootServer(backing_transport)
462
441
server.start_server()
464
self.assertEqual('chroot-%d:///' % id(server), server.get_url())
442
self.addCleanup(server.stop_server)
443
self.assertEqual('chroot-%d:///' % id(server), server.get_url())
446
class TestHooks(tests.TestCase):
447
"""Basic tests for transport hooks"""
449
def _get_connected_transport(self):
450
return transport.ConnectedTransport("bogus:nowhere")
452
def test_transporthooks_initialisation(self):
453
"""Check all expected transport hook points are set up"""
454
hookpoint = transport.TransportHooks()
455
self.assertTrue("post_connect" in hookpoint,
456
"post_connect not in %s" % (hookpoint,))
458
def test_post_connect(self):
459
"""Ensure the post_connect hook is called when _set_transport is"""
461
transport.Transport.hooks.install_named_hook("post_connect",
463
t = self._get_connected_transport()
464
self.assertLength(0, calls)
465
t._set_connection("connection", "auth")
466
self.assertEqual(calls, [t])
469
469
class PathFilteringDecoratorTransportTest(tests.TestCase):
701
class TestTransportFromPath(tests.TestCaseInTempDir):
703
def test_with_path(self):
704
t = transport.get_transport_from_path(self.test_dir)
705
self.assertIsInstance(t, local.LocalTransport)
706
self.assertEqual(t.base.rstrip("/"),
707
urlutils.local_path_to_url(self.test_dir))
709
def test_with_url(self):
710
t = transport.get_transport_from_path("file:")
711
self.assertIsInstance(t, local.LocalTransport)
712
self.assertEqual(t.base.rstrip("/"),
713
urlutils.local_path_to_url(os.path.join(self.test_dir, "file:")))
716
class TestTransportFromUrl(tests.TestCaseInTempDir):
718
def test_with_path(self):
719
self.assertRaises(errors.InvalidURL, transport.get_transport_from_url,
722
def test_with_url(self):
723
url = urlutils.local_path_to_url(self.test_dir)
724
t = transport.get_transport_from_url(url)
725
self.assertIsInstance(t, local.LocalTransport)
726
self.assertEqual(t.base.rstrip("/"), url)
728
def test_with_url_and_segment_parameters(self):
729
url = urlutils.local_path_to_url(self.test_dir)+",branch=foo"
730
t = transport.get_transport_from_url(url)
731
self.assertIsInstance(t, local.LocalTransport)
732
self.assertEqual(t.base.rstrip("/"), url)
733
with open(os.path.join(self.test_dir, "afile"), 'w') as f:
735
self.assertTrue(t.has("afile"))
700
738
class TestLocalTransports(tests.TestCase):
702
740
def test_get_transport_from_abspath(self):
703
741
here = osutils.abspath('.')
704
742
t = transport.get_transport(here)
705
743
self.assertIsInstance(t, local.LocalTransport)
706
self.assertEquals(t.base, urlutils.local_path_to_url(here) + '/')
744
self.assertEqual(t.base, urlutils.local_path_to_url(here) + '/')
708
746
def test_get_transport_from_relpath(self):
709
747
here = osutils.abspath('.')
710
748
t = transport.get_transport('.')
711
749
self.assertIsInstance(t, local.LocalTransport)
712
self.assertEquals(t.base, urlutils.local_path_to_url('.') + '/')
750
self.assertEqual(t.base, urlutils.local_path_to_url('.') + '/')
714
752
def test_get_transport_from_local_url(self):
715
753
here = osutils.abspath('.')
716
754
here_url = urlutils.local_path_to_url(here) + '/'
717
755
t = transport.get_transport(here_url)
718
756
self.assertIsInstance(t, local.LocalTransport)
719
self.assertEquals(t.base, here_url)
757
self.assertEqual(t.base, here_url)
721
759
def test_local_abspath(self):
722
760
here = osutils.abspath('.')
723
761
t = transport.get_transport(here)
724
self.assertEquals(t.local_abspath(''), here)
762
self.assertEqual(t.local_abspath(''), here)
727
765
class TestLocalTransportMutation(tests.TestCaseInTempDir):
763
805
with open('out', 'rb') as f:
764
806
# Should have been flushed.
765
self.assertEquals(f.read(), 'foo')
766
self.assertEquals(len(calls), 1, calls)
807
self.assertEqual(f.read(), 'foo')
808
self.assertEqual(len(calls), 1, calls)
810
def test_missing_directory(self):
811
t = self.get_transport('.')
812
self.assertRaises(errors.NoSuchFile, t.open_write_stream, 'dir/foo')
769
815
class TestWin32LocalTransport(tests.TestCase):
771
817
def test_unc_clone_to_root(self):
818
self.requireFeature(features.win32_feature)
772
819
# Win32 UNC path like \\HOST\path
773
820
# clone to root should stop at least at \\HOST part
775
822
t = local.EmulatedWin32LocalTransport('file://HOST/path/to/some/dir/')
776
823
for i in xrange(4):
777
824
t = t.clone('..')
778
self.assertEquals(t.base, 'file://HOST/')
825
self.assertEqual(t.base, 'file://HOST/')
779
826
# make sure we reach the root
780
827
t = t.clone('..')
781
self.assertEquals(t.base, 'file://HOST/')
828
self.assertEqual(t.base, 'file://HOST/')
784
831
class TestConnectedTransport(tests.TestCase):
787
834
def test_parse_url(self):
788
835
t = transport.ConnectedTransport(
789
836
'http://simple.example.com/home/source')
790
self.assertEquals(t._host, 'simple.example.com')
791
self.assertEquals(t._port, None)
792
self.assertEquals(t._path, '/home/source/')
793
self.assertTrue(t._user is None)
794
self.assertTrue(t._password is None)
837
self.assertEqual(t._parsed_url.host, 'simple.example.com')
838
self.assertEqual(t._parsed_url.port, None)
839
self.assertEqual(t._parsed_url.path, '/home/source/')
840
self.assertTrue(t._parsed_url.user is None)
841
self.assertTrue(t._parsed_url.password is None)
796
self.assertEquals(t.base, 'http://simple.example.com/home/source/')
843
self.assertEqual(t.base, 'http://simple.example.com/home/source/')
798
845
def test_parse_url_with_at_in_user(self):
800
847
t = transport.ConnectedTransport('ftp://user@host.com@www.host.com/')
801
self.assertEquals(t._user, 'user@host.com')
848
self.assertEqual(t._parsed_url.user, 'user@host.com')
803
850
def test_parse_quoted_url(self):
804
851
t = transport.ConnectedTransport(
805
852
'http://ro%62ey:h%40t@ex%41mple.com:2222/path')
806
self.assertEquals(t._host, 'exAmple.com')
807
self.assertEquals(t._port, 2222)
808
self.assertEquals(t._user, 'robey')
809
self.assertEquals(t._password, 'h@t')
810
self.assertEquals(t._path, '/path/')
853
self.assertEqual(t._parsed_url.host, 'exAmple.com')
854
self.assertEqual(t._parsed_url.port, 2222)
855
self.assertEqual(t._parsed_url.user, 'robey')
856
self.assertEqual(t._parsed_url.password, 'h@t')
857
self.assertEqual(t._parsed_url.path, '/path/')
812
859
# Base should not keep track of the password
813
self.assertEquals(t.base, 'http://robey@exAmple.com:2222/path/')
860
self.assertEqual(t.base, 'http://ro%62ey@ex%41mple.com:2222/path/')
815
862
def test_parse_invalid_url(self):
816
863
self.assertRaises(errors.InvalidURL,
831
879
'sftp://user@host.com:33/abs/path/sub')
832
880
# Make sure it works when we don't supply a username
833
881
t = transport.ConnectedTransport('sftp://host.com/abs/path')
834
self.assertEquals(t.relpath('sftp://host.com/abs/path/sub'), 'sub')
882
self.assertEqual(t.relpath('sftp://host.com/abs/path/sub'), 'sub')
836
884
# Make sure it works when parts of the path will be url encoded
837
885
t = transport.ConnectedTransport('sftp://host.com/dev/%path')
838
self.assertEquals(t.relpath('sftp://host.com/dev/%path/sub'), 'sub')
886
self.assertEqual(t.relpath('sftp://host.com/dev/%path/sub'), 'sub')
840
888
def test_connection_sharing_propagate_credentials(self):
841
889
t = transport.ConnectedTransport('ftp://user@host.com/abs/path')
842
self.assertEquals('user', t._user)
843
self.assertEquals('host.com', t._host)
890
self.assertEqual('user', t._parsed_url.user)
891
self.assertEqual('host.com', t._parsed_url.host)
844
892
self.assertIs(None, t._get_connection())
845
self.assertIs(None, t._password)
893
self.assertIs(None, t._parsed_url.password)
846
894
c = t.clone('subdir')
847
895
self.assertIs(None, c._get_connection())
848
self.assertIs(None, t._password)
896
self.assertIs(None, t._parsed_url.password)
850
898
# Simulate the user entering a password
851
899
password = 'secret'
871
919
def test_reuse_same_transport(self):
872
920
possible_transports = []
873
t1 = transport.get_transport('http://foo/',
921
t1 = transport.get_transport_from_url('http://foo/',
874
922
possible_transports=possible_transports)
875
923
self.assertEqual([t1], possible_transports)
876
t2 = transport.get_transport('http://foo/',
924
t2 = transport.get_transport_from_url('http://foo/',
877
925
possible_transports=[t1])
878
926
self.assertIs(t1, t2)
880
928
# Also check that final '/' are handled correctly
881
t3 = transport.get_transport('http://foo/path/')
882
t4 = transport.get_transport('http://foo/path',
929
t3 = transport.get_transport_from_url('http://foo/path/')
930
t4 = transport.get_transport_from_url('http://foo/path',
883
931
possible_transports=[t3])
884
932
self.assertIs(t3, t4)
886
t5 = transport.get_transport('http://foo/path')
887
t6 = transport.get_transport('http://foo/path/',
934
t5 = transport.get_transport_from_url('http://foo/path')
935
t6 = transport.get_transport_from_url('http://foo/path/',
888
936
possible_transports=[t5])
889
937
self.assertIs(t5, t6)
891
939
def test_don_t_reuse_different_transport(self):
892
t1 = transport.get_transport('http://foo/path')
893
t2 = transport.get_transport('http://bar/path',
940
t1 = transport.get_transport_from_url('http://foo/path')
941
t2 = transport.get_transport_from_url('http://bar/path',
894
942
possible_transports=[t1])
895
943
self.assertIsNot(t1, t2)
898
946
class TestTransportTrace(tests.TestCase):
901
t = transport.get_transport('trace+memory://')
902
self.assertIsInstance(t, bzrlib.transport.trace.TransportTraceDecorator)
948
def test_decorator(self):
949
t = transport.get_transport_from_url('trace+memory://')
950
self.assertIsInstance(
951
t, bzrlib.transport.trace.TransportTraceDecorator)
904
953
def test_clone_preserves_activity(self):
905
t = transport.get_transport('trace+memory://')
954
t = transport.get_transport_from_url('trace+memory://')
906
955
t2 = t.clone('.')
907
956
self.assertTrue(t is not t2)
908
957
self.assertTrue(t._activity is t2._activity)
1046
1096
def test_truncation(self):
1047
1097
fake_html = "<p>something!\n" * 1000
1048
1098
result = http.unhtml_roughly(fake_html)
1049
self.assertEquals(len(result), 1000)
1099
self.assertEqual(len(result), 1000)
1050
1100
self.assertStartsWith(result, " something!")
1103
class SomeDirectory(object):
1105
def look_up(self, name, url):
1109
class TestLocationToUrl(tests.TestCase):
1111
def get_base_location(self):
1112
path = osutils.abspath('/foo/bar')
1113
if path.startswith('/'):
1114
url = 'file://%s' % (path,)
1116
# On Windows, abspaths start with the drive letter, so we have to
1117
# add in the extra '/'
1118
url = 'file:///%s' % (path,)
1121
def test_regular_url(self):
1122
self.assertEqual("file://foo", location_to_url("file://foo"))
1124
def test_directory(self):
1125
directories.register("bar:", SomeDirectory, "Dummy directory")
1126
self.addCleanup(directories.remove, "bar:")
1127
self.assertEqual("http://bar", location_to_url("bar:"))
1129
def test_unicode_url(self):
1130
self.assertRaises(errors.InvalidURL, location_to_url,
1131
"http://fo/\xc3\xaf".decode("utf-8"))
1133
def test_unicode_path(self):
1134
path, url = self.get_base_location()
1135
location = path + "\xc3\xaf".decode("utf-8")
1137
self.assertEqual(url, location_to_url(location))
1139
def test_path(self):
1140
path, url = self.get_base_location()
1141
self.assertEqual(url, location_to_url(path))
1143
def test_relative_file_url(self):
1144
self.assertEqual(urlutils.local_path_to_url(".") + "/bar",
1145
location_to_url("file:bar"))
1147
def test_absolute_file_url(self):
1148
self.assertEqual("file:///bar", location_to_url("file:/bar"))