87
92
transport.register_lazy_transport(
88
93
'foo', 'bzrlib.tests.test_transport', 'BadTransportHandler')
90
transport.get_transport('foo://fooserver/foo')
95
transport.get_transport_from_url('foo://fooserver/foo')
91
96
except errors.UnsupportedProtocol, e:
93
98
self.assertEquals('Unsupported protocol'
107
112
'foo', 'bzrlib.tests.test_transport', 'BackupTransportHandler')
108
113
transport.register_lazy_transport(
109
114
'foo', 'bzrlib.tests.test_transport', 'BadTransportHandler')
110
t = transport.get_transport('foo://fooserver/foo')
115
t = transport.get_transport_from_url('foo://fooserver/foo')
111
116
self.assertTrue(isinstance(t, BackupTransportHandler))
113
118
def test_ssh_hints(self):
114
119
"""Transport ssh:// should raise an error pointing out bzr+ssh://"""
116
transport.get_transport('ssh://fooserver/foo')
121
transport.get_transport_from_url('ssh://fooserver/foo')
117
122
except errors.UnsupportedProtocol, e:
119
124
self.assertEquals('Unsupported protocol'
134
139
self.assertRaises(errors.ReadError, a_file.read, 40)
137
def test__combine_paths(self):
138
t = transport.Transport('/')
139
self.assertEqual('/home/sarah/project/foo',
140
t._combine_paths('/home/sarah', 'project/foo'))
141
self.assertEqual('/etc',
142
t._combine_paths('/home/sarah', '../../etc'))
143
self.assertEqual('/etc',
144
t._combine_paths('/home/sarah', '../../../etc'))
145
self.assertEqual('/etc',
146
t._combine_paths('/home/sarah', '/etc'))
148
142
def test_local_abspath_non_local_transport(self):
149
143
# the base implementation should throw
150
144
t = memory.MemoryTransport()
364
358
def test_abspath(self):
365
359
# The abspath is always relative to the chroot_url.
366
360
server = chroot.ChrootServer(
367
transport.get_transport('memory:///foo/bar/'))
361
transport.get_transport_from_url('memory:///foo/bar/'))
368
362
self.start_server(server)
369
t = transport.get_transport(server.get_url())
363
t = transport.get_transport_from_url(server.get_url())
370
364
self.assertEqual(server.get_url(), t.abspath('/'))
372
366
subdir_t = t.clone('subdir')
375
369
def test_clone(self):
376
370
server = chroot.ChrootServer(
377
transport.get_transport('memory:///foo/bar/'))
371
transport.get_transport_from_url('memory:///foo/bar/'))
378
372
self.start_server(server)
379
t = transport.get_transport(server.get_url())
373
t = transport.get_transport_from_url(server.get_url())
380
374
# relpath from root and root path are the same
381
375
relpath_cloned = t.clone('foo')
382
376
abspath_cloned = t.clone('/foo')
391
385
This is so that it is not possible to escape a chroot by doing::
392
386
url = chroot_transport.base
393
387
parent_url = urlutils.join(url, '..')
394
new_t = transport.get_transport(parent_url)
388
new_t = transport.get_transport_from_url(parent_url)
396
390
server = chroot.ChrootServer(
397
transport.get_transport('memory:///path/subpath'))
391
transport.get_transport_from_url('memory:///path/subpath'))
398
392
self.start_server(server)
399
t = transport.get_transport(server.get_url())
400
new_t = transport.get_transport(t.base)
393
t = transport.get_transport_from_url(server.get_url())
394
new_t = transport.get_transport_from_url(t.base)
401
395
self.assertEqual(t.server, new_t.server)
402
396
self.assertEqual(t.base, new_t.base)
408
402
This is so that it is not possible to escape a chroot by doing::
409
403
url = chroot_transport.base
410
404
parent_url = urlutils.join(url, '..')
411
new_t = transport.get_transport(parent_url)
405
new_t = transport.get_transport_from_url(parent_url)
413
407
server = chroot.ChrootServer(
414
transport.get_transport('memory:///path/'))
408
transport.get_transport_from_url('memory:///path/'))
415
409
self.start_server(server)
416
t = transport.get_transport(server.get_url())
410
t = transport.get_transport_from_url(server.get_url())
417
411
self.assertRaises(
418
412
errors.InvalidURLJoin, urlutils.join, t.base, '..')
449
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])
452
469
class PathFilteringDecoratorTransportTest(tests.TestCase):
453
470
"""Pathfilter decoration specific tests."""
455
472
def test_abspath(self):
456
473
# The abspath is always relative to the base of the backing transport.
457
474
server = pathfilter.PathFilteringServer(
458
transport.get_transport('memory:///foo/bar/'),
475
transport.get_transport_from_url('memory:///foo/bar/'),
460
477
server.start_server()
461
t = transport.get_transport(server.get_url())
478
t = transport.get_transport_from_url(server.get_url())
462
479
self.assertEqual(server.get_url(), t.abspath('/'))
464
481
subdir_t = t.clone('subdir')
473
490
if filter_func is None:
474
491
filter_func = lambda x: x
475
492
server = pathfilter.PathFilteringServer(
476
transport.get_transport('memory:///foo/bar/'), filter_func)
493
transport.get_transport_from_url('memory:///foo/bar/'), filter_func)
477
494
server.start_server()
478
495
self.addCleanup(server.stop_server)
479
return transport.get_transport(server.get_url())
496
return transport.get_transport_from_url(server.get_url())
481
498
def test__filter(self):
482
499
# _filter (with an identity func as filter_func) always returns
526
543
otherwise) the filtering by doing::
527
544
url = filtered_transport.base
528
545
parent_url = urlutils.join(url, '..')
529
new_t = transport.get_transport(parent_url)
546
new_t = transport.get_transport_from_url(parent_url)
531
548
t = self.make_pf_transport()
532
new_t = transport.get_transport(t.base)
549
new_t = transport.get_transport_from_url(t.base)
533
550
self.assertEqual(t.server, new_t.server)
534
551
self.assertEqual(t.base, new_t.base)
548
565
# connect to '.' via http which is not listable
549
566
server = HttpServer()
550
567
self.start_server(server)
551
t = transport.get_transport('readonly+' + server.get_url())
568
t = transport.get_transport_from_url('readonly+' + server.get_url())
552
569
self.assertIsInstance(t, readonly.ReadonlyTransportDecorator)
553
570
self.assertEqual(False, t.listable())
554
571
self.assertEqual(True, t.is_readonly())
587
604
# the url should be decorated appropriately
588
605
self.assertStartsWith(server.get_url(), 'fakenfs+')
589
606
# and we should be able to get a transport for it
590
t = transport.get_transport(server.get_url())
607
t = transport.get_transport_from_url(server.get_url())
591
608
# which must be a FakeNFSTransportDecorator instance.
592
609
self.assertIsInstance(t, fakenfs.FakeNFSTransportDecorator)
670
687
base_url = self._server.get_url()
671
688
url = self._adjust_url(base_url, relpath)
672
689
# try getting the transport via the regular interface:
673
t = transport.get_transport(url)
690
t = transport.get_transport_from_url(url)
674
691
# vila--20070607 if the following are commented out the test suite
675
692
# still pass. Is this really still needed or was it a forgotten
676
693
# temporary fix ?
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.assertEquals(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.assertEquals(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.assertEquals(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.assertEquals(t.base.rstrip("/"), url)
733
with open(os.path.join(self.test_dir, "afile"), 'w') as f:
735
self.assertTrue(t.has("afile"))
684
738
class TestLocalTransports(tests.TestCase):
686
740
def test_get_transport_from_abspath(self):
708
762
self.assertEquals(t.local_abspath(''), here)
765
class TestLocalTransportMutation(tests.TestCaseInTempDir):
767
def test_local_transport_mkdir(self):
768
here = osutils.abspath('.')
769
t = transport.get_transport(here)
771
self.assertTrue(os.path.exists('test'))
773
def test_local_transport_mkdir_permission_denied(self):
774
# See https://bugs.launchpad.net/bzr/+bug/606537
775
here = osutils.abspath('.')
776
t = transport.get_transport(here)
777
def fake_chmod(path, mode):
778
e = OSError('permission denied')
779
e.errno = errno.EPERM
781
self.overrideAttr(os, 'chmod', fake_chmod)
783
t.mkdir('test2', mode=0707)
784
self.assertTrue(os.path.exists('test'))
785
self.assertTrue(os.path.exists('test2'))
788
class TestLocalTransportWriteStream(tests.TestCaseWithTransport):
790
def test_local_fdatasync_calls_fdatasync(self):
791
"""Check fdatasync on a stream tries to flush the data to the OS.
793
We can't easily observe the external effect but we can at least see
797
fdatasync = getattr(os, 'fdatasync', sentinel)
798
if fdatasync is sentinel:
799
raise tests.TestNotApplicable('fdatasync not supported')
800
t = self.get_transport('.')
801
calls = self.recordCalls(os, 'fdatasync')
802
w = t.open_write_stream('out')
805
with open('out', 'rb') as f:
806
# Should have been flushed.
807
self.assertEquals(f.read(), 'foo')
808
self.assertEquals(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')
711
815
class TestWin32LocalTransport(tests.TestCase):
713
817
def test_unc_clone_to_root(self):
729
833
def test_parse_url(self):
730
834
t = transport.ConnectedTransport(
731
835
'http://simple.example.com/home/source')
732
self.assertEquals(t._host, 'simple.example.com')
733
self.assertEquals(t._port, None)
734
self.assertEquals(t._path, '/home/source/')
735
self.assertTrue(t._user is None)
736
self.assertTrue(t._password is None)
836
self.assertEquals(t._parsed_url.host, 'simple.example.com')
837
self.assertEquals(t._parsed_url.port, None)
838
self.assertEquals(t._parsed_url.path, '/home/source/')
839
self.assertTrue(t._parsed_url.user is None)
840
self.assertTrue(t._parsed_url.password is None)
738
842
self.assertEquals(t.base, 'http://simple.example.com/home/source/')
740
844
def test_parse_url_with_at_in_user(self):
742
846
t = transport.ConnectedTransport('ftp://user@host.com@www.host.com/')
743
self.assertEquals(t._user, 'user@host.com')
847
self.assertEquals(t._parsed_url.user, 'user@host.com')
745
849
def test_parse_quoted_url(self):
746
850
t = transport.ConnectedTransport(
747
851
'http://ro%62ey:h%40t@ex%41mple.com:2222/path')
748
self.assertEquals(t._host, 'exAmple.com')
749
self.assertEquals(t._port, 2222)
750
self.assertEquals(t._user, 'robey')
751
self.assertEquals(t._password, 'h@t')
752
self.assertEquals(t._path, '/path/')
852
self.assertEquals(t._parsed_url.host, 'exAmple.com')
853
self.assertEquals(t._parsed_url.port, 2222)
854
self.assertEquals(t._parsed_url.user, 'robey')
855
self.assertEquals(t._parsed_url.password, 'h@t')
856
self.assertEquals(t._parsed_url.path, '/path/')
754
858
# Base should not keep track of the password
755
self.assertEquals(t.base, 'http://robey@exAmple.com:2222/path/')
859
self.assertEquals(t.base, 'http://ro%62ey@ex%41mple.com:2222/path/')
757
861
def test_parse_invalid_url(self):
758
862
self.assertRaises(errors.InvalidURL,
783
887
def test_connection_sharing_propagate_credentials(self):
784
888
t = transport.ConnectedTransport('ftp://user@host.com/abs/path')
785
self.assertEquals('user', t._user)
786
self.assertEquals('host.com', t._host)
889
self.assertEquals('user', t._parsed_url.user)
890
self.assertEquals('host.com', t._parsed_url.host)
787
891
self.assertIs(None, t._get_connection())
788
self.assertIs(None, t._password)
892
self.assertIs(None, t._parsed_url.password)
789
893
c = t.clone('subdir')
790
894
self.assertIs(None, c._get_connection())
791
self.assertIs(None, t._password)
895
self.assertIs(None, t._parsed_url.password)
793
897
# Simulate the user entering a password
794
898
password = 'secret'
814
918
def test_reuse_same_transport(self):
815
919
possible_transports = []
816
t1 = transport.get_transport('http://foo/',
920
t1 = transport.get_transport_from_url('http://foo/',
817
921
possible_transports=possible_transports)
818
922
self.assertEqual([t1], possible_transports)
819
t2 = transport.get_transport('http://foo/',
923
t2 = transport.get_transport_from_url('http://foo/',
820
924
possible_transports=[t1])
821
925
self.assertIs(t1, t2)
823
927
# Also check that final '/' are handled correctly
824
t3 = transport.get_transport('http://foo/path/')
825
t4 = transport.get_transport('http://foo/path',
928
t3 = transport.get_transport_from_url('http://foo/path/')
929
t4 = transport.get_transport_from_url('http://foo/path',
826
930
possible_transports=[t3])
827
931
self.assertIs(t3, t4)
829
t5 = transport.get_transport('http://foo/path')
830
t6 = transport.get_transport('http://foo/path/',
933
t5 = transport.get_transport_from_url('http://foo/path')
934
t6 = transport.get_transport_from_url('http://foo/path/',
831
935
possible_transports=[t5])
832
936
self.assertIs(t5, t6)
834
938
def test_don_t_reuse_different_transport(self):
835
t1 = transport.get_transport('http://foo/path')
836
t2 = transport.get_transport('http://bar/path',
939
t1 = transport.get_transport_from_url('http://foo/path')
940
t2 = transport.get_transport_from_url('http://bar/path',
837
941
possible_transports=[t1])
838
942
self.assertIsNot(t1, t2)
841
945
class TestTransportTrace(tests.TestCase):
844
t = transport.get_transport('trace+memory://')
947
def test_decorator(self):
948
t = transport.get_transport_from_url('trace+memory://')
845
949
self.assertIsInstance(
846
950
t, bzrlib.transport.trace.TransportTraceDecorator)
848
952
def test_clone_preserves_activity(self):
849
t = transport.get_transport('trace+memory://')
953
t = transport.get_transport_from_url('trace+memory://')
850
954
t2 = t.clone('.')
851
955
self.assertTrue(t is not t2)
852
956
self.assertTrue(t._activity is t2._activity)
868
972
self.assertEqual(expected_result, t._activity)
870
974
def test_readv(self):
871
t = transport.get_transport('trace+memory:///')
975
t = transport.get_transport_from_url('trace+memory:///')
872
976
t.put_bytes('foo', 'barish')
873
977
list(t.readv('foo', [(0, 1), (3, 2)],
874
978
adjust_for_latency=True, upper_limit=6))
993
1097
result = http.unhtml_roughly(fake_html)
994
1098
self.assertEquals(len(result), 1000)
995
1099
self.assertStartsWith(result, " something!")
1102
class SomeDirectory(object):
1104
def look_up(self, name, url):
1108
class TestLocationToUrl(tests.TestCase):
1110
def get_base_location(self):
1111
path = osutils.abspath('/foo/bar')
1112
if path.startswith('/'):
1113
url = 'file://%s' % (path,)
1115
# On Windows, abspaths start with the drive letter, so we have to
1116
# add in the extra '/'
1117
url = 'file:///%s' % (path,)
1120
def test_regular_url(self):
1121
self.assertEquals("file://foo", location_to_url("file://foo"))
1123
def test_directory(self):
1124
directories.register("bar:", SomeDirectory, "Dummy directory")
1125
self.addCleanup(directories.remove, "bar:")
1126
self.assertEquals("http://bar", location_to_url("bar:"))
1128
def test_unicode_url(self):
1129
self.assertRaises(errors.InvalidURL, location_to_url,
1130
"http://fo/\xc3\xaf".decode("utf-8"))
1132
def test_unicode_path(self):
1133
path, url = self.get_base_location()
1134
location = path + "\xc3\xaf".decode("utf-8")
1136
self.assertEquals(url, location_to_url(location))
1138
def test_path(self):
1139
path, url = self.get_base_location()
1140
self.assertEquals(url, location_to_url(path))
1142
def test_relative_file_url(self):
1143
self.assertEquals(urlutils.local_path_to_url(".") + "/bar",
1144
location_to_url("file:bar"))
1146
def test_absolute_file_url(self):
1147
self.assertEquals("file:///bar", location_to_url("file:/bar"))