31
40
from bzrlib.tests import TestCase, TestCaseInTempDir
32
41
from bzrlib.transport import (_CoalescedOffset,
33
42
_get_protocol_handlers,
43
_set_protocol_handlers,
34
44
_get_transport_modules,
37
47
register_lazy_transport,
38
_set_protocol_handlers,
48
register_transport_proto,
49
_clear_protocol_handlers,
52
from bzrlib.transport.chroot import ChrootServer
41
53
from bzrlib.transport.memory import MemoryTransport
42
from bzrlib.transport.local import LocalTransport
54
from bzrlib.transport.local import (LocalTransport,
55
EmulatedWin32LocalTransport)
58
# TODO: Should possibly split transport-specific tests into their own files.
45
61
class TestTransport(TestCase):
48
64
def test__get_set_protocol_handlers(self):
49
65
handlers = _get_protocol_handlers()
50
self.assertNotEqual({}, handlers)
66
self.assertNotEqual([], handlers.keys( ))
52
_set_protocol_handlers({})
53
self.assertEqual({}, _get_protocol_handlers())
68
_clear_protocol_handlers()
69
self.assertEqual([], _get_protocol_handlers().keys())
55
71
_set_protocol_handlers(handlers)
59
75
class SampleHandler(object):
60
76
"""I exist, isnt that enough?"""
63
_set_protocol_handlers(my_handlers)
78
_clear_protocol_handlers()
79
register_transport_proto('foo')
64
80
register_lazy_transport('foo', 'bzrlib.tests.test_transport', 'TestTransport.SampleHandler')
81
register_transport_proto('bar')
65
82
register_lazy_transport('bar', 'bzrlib.tests.test_transport', 'TestTransport.SampleHandler')
66
self.assertEqual([SampleHandler.__module__],
83
self.assertEqual([SampleHandler.__module__, 'bzrlib.transport.chroot'],
67
84
_get_transport_modules())
69
86
_set_protocol_handlers(handlers)
92
110
"""Transport with missing dependency causes no error"""
93
111
saved_handlers = _get_protocol_handlers()
95
_set_protocol_handlers({})
113
_clear_protocol_handlers()
114
register_transport_proto('foo')
96
115
register_lazy_transport('foo', 'bzrlib.tests.test_transport',
97
116
'BackupTransportHandler')
98
117
register_lazy_transport('foo', 'bzrlib.tests.test_transport',
112
131
self.assertRaises(ReadError, a_file.read, 40)
134
def test__combine_paths(self):
136
self.assertEqual('/home/sarah/project/foo',
137
t._combine_paths('/home/sarah', 'project/foo'))
138
self.assertEqual('/etc',
139
t._combine_paths('/home/sarah', '../../etc'))
140
self.assertEqual('/etc',
141
t._combine_paths('/home/sarah', '../../../etc'))
142
self.assertEqual('/etc',
143
t._combine_paths('/home/sarah', '/etc'))
145
def test_local_abspath_non_local_transport(self):
146
# the base implementation should throw
147
t = MemoryTransport()
148
e = self.assertRaises(errors.NotLocalUrl, t.local_abspath, 't')
149
self.assertEqual('memory:///t is not a local path.', str(e))
116
152
class TestCoalesceOffsets(TestCase):
231
268
transport.append_bytes('foo', 'content')
232
269
self.assertEquals(True, transport.has('foo'))
271
def test_list_dir(self):
272
transport = MemoryTransport()
273
transport.put_bytes('foo', 'content')
274
transport.mkdir('dir')
275
transport.put_bytes('dir/subfoo', 'content')
276
transport.put_bytes('dirlike', 'content')
278
self.assertEquals(['dir', 'dirlike', 'foo'], sorted(transport.list_dir('.')))
279
self.assertEquals(['subfoo'], sorted(transport.list_dir('dir')))
234
281
def test_mkdir(self):
235
282
transport = MemoryTransport()
236
283
transport.mkdir('dir')
269
316
self.assertEqual(7, transport.stat('foo').st_size)
270
317
self.assertEqual(6, transport.stat('bar').st_size)
320
class ChrootDecoratorTransportTest(TestCase):
321
"""Chroot decoration specific tests."""
323
def test_abspath(self):
324
# The abspath is always relative to the chroot_url.
325
server = ChrootServer(get_transport('memory:///foo/bar/'))
327
transport = get_transport(server.get_url())
328
self.assertEqual(server.get_url(), transport.abspath('/'))
330
subdir_transport = transport.clone('subdir')
331
self.assertEqual(server.get_url(), subdir_transport.abspath('/'))
334
def test_clone(self):
335
server = ChrootServer(get_transport('memory:///foo/bar/'))
337
transport = get_transport(server.get_url())
338
# relpath from root and root path are the same
339
relpath_cloned = transport.clone('foo')
340
abspath_cloned = transport.clone('/foo')
341
self.assertEqual(server, relpath_cloned.server)
342
self.assertEqual(server, abspath_cloned.server)
345
def test_chroot_url_preserves_chroot(self):
346
"""Calling get_transport on a chroot transport's base should produce a
347
transport with exactly the same behaviour as the original chroot
350
This is so that it is not possible to escape a chroot by doing::
351
url = chroot_transport.base
352
parent_url = urlutils.join(url, '..')
353
new_transport = get_transport(parent_url)
355
server = ChrootServer(get_transport('memory:///path/subpath'))
357
transport = get_transport(server.get_url())
358
new_transport = get_transport(transport.base)
359
self.assertEqual(transport.server, new_transport.server)
360
self.assertEqual(transport.base, new_transport.base)
363
def test_urljoin_preserves_chroot(self):
364
"""Using urlutils.join(url, '..') on a chroot URL should not produce a
365
URL that escapes the intended chroot.
367
This is so that it is not possible to escape a chroot by doing::
368
url = chroot_transport.base
369
parent_url = urlutils.join(url, '..')
370
new_transport = get_transport(parent_url)
372
server = ChrootServer(get_transport('memory:///path/'))
374
transport = get_transport(server.get_url())
376
InvalidURLJoin, urlutils.join, transport.base, '..')
380
class ChrootServerTest(TestCase):
382
def test_construct(self):
383
backing_transport = MemoryTransport()
384
server = ChrootServer(backing_transport)
385
self.assertEqual(backing_transport, server.backing_transport)
387
def test_setUp(self):
388
backing_transport = MemoryTransport()
389
server = ChrootServer(backing_transport)
391
self.assertTrue(server.scheme in _get_protocol_handlers().keys())
393
def test_tearDown(self):
394
backing_transport = MemoryTransport()
395
server = ChrootServer(backing_transport)
398
self.assertFalse(server.scheme in _get_protocol_handlers().keys())
400
def test_get_url(self):
401
backing_transport = MemoryTransport()
402
server = ChrootServer(backing_transport)
404
self.assertEqual('chroot-%d:///' % id(server), server.get_url())
273
408
class ReadonlyDecoratorTransportTest(TestCase):
274
409
"""Readonly decoration specific tests."""
417
552
super(TestTransportImplementation, self).setUp()
418
553
self._server = self.transport_server()
419
554
self._server.setUp()
555
self.addCleanup(self._server.tearDown)
422
super(TestTransportImplementation, self).tearDown()
423
self._server.tearDown()
425
557
def get_transport(self):
426
558
"""Return a connected transport to the local directory."""
427
559
base_url = self._server.get_url()
428
560
# try getting the transport via the regular interface:
429
561
t = get_transport(base_url)
430
if not isinstance(t, self.transport_class):
562
if not isinstance(t, self.transport_class):
431
563
# we did not get the correct transport class type. Override the
432
564
# regular connection behaviour by direct construction.
433
565
t = self.transport_class(base_url)
569
class TestLocalTransports(TestCase):
571
def test_get_transport_from_abspath(self):
572
here = os.path.abspath('.')
573
t = get_transport(here)
574
self.assertIsInstance(t, LocalTransport)
575
self.assertEquals(t.base, urlutils.local_path_to_url(here) + '/')
577
def test_get_transport_from_relpath(self):
578
here = os.path.abspath('.')
579
t = get_transport('.')
580
self.assertIsInstance(t, LocalTransport)
581
self.assertEquals(t.base, urlutils.local_path_to_url('.') + '/')
583
def test_get_transport_from_local_url(self):
584
here = os.path.abspath('.')
585
here_url = urlutils.local_path_to_url(here) + '/'
586
t = get_transport(here_url)
587
self.assertIsInstance(t, LocalTransport)
588
self.assertEquals(t.base, here_url)
590
def test_local_abspath(self):
591
here = os.path.abspath('.')
592
t = get_transport(here)
593
self.assertEquals(t.local_abspath(''), here)
596
class TestWin32LocalTransport(TestCase):
598
def test_unc_clone_to_root(self):
599
# Win32 UNC path like \\HOST\path
600
# clone to root should stop at least at \\HOST part
602
t = EmulatedWin32LocalTransport('file://HOST/path/to/some/dir/')
605
self.assertEquals(t.base, 'file://HOST/')
606
# make sure we reach the root
608
self.assertEquals(t.base, 'file://HOST/')
611
def get_test_permutations():
612
"""Return transport permutations to be used in testing.
614
This module registers some transports, but they're only for testing
615
registration. We don't really want to run all the transport tests against