24
25
from bzrlib import (
31
from bzrlib.transport import (
40
from bzrlib.tests import (
31
from bzrlib.errors import (DependencyNotPresent,
39
from bzrlib.tests import ParamikoFeature, TestCase, TestCaseInTempDir
40
from bzrlib.transport import (_clear_protocol_handlers,
43
_get_protocol_handlers,
44
_set_protocol_handlers,
45
_get_transport_modules,
48
register_lazy_transport,
49
register_transport_proto,
52
from bzrlib.transport.chroot import ChrootServer
53
from bzrlib.transport.memory import MemoryTransport
54
from bzrlib.transport.local import (LocalTransport,
55
EmulatedWin32LocalTransport)
56
from bzrlib.transport.pathfilter import PathFilteringServer
46
59
# TODO: Should possibly split transport-specific tests into their own files.
49
class TestTransport(tests.TestCase):
62
class TestTransport(TestCase):
50
63
"""Test the non transport-concrete class functionality."""
52
# FIXME: These tests should use addCleanup() and/or overrideAttr() instead
53
# of try/finally -- vila 20100205
55
65
def test__get_set_protocol_handlers(self):
56
handlers = transport._get_protocol_handlers()
66
handlers = _get_protocol_handlers()
57
67
self.assertNotEqual([], handlers.keys( ))
59
transport._clear_protocol_handlers()
60
self.assertEqual([], transport._get_protocol_handlers().keys())
69
_clear_protocol_handlers()
70
self.assertEqual([], _get_protocol_handlers().keys())
62
transport._set_protocol_handlers(handlers)
72
_set_protocol_handlers(handlers)
64
74
def test_get_transport_modules(self):
65
handlers = transport._get_protocol_handlers()
75
handlers = _get_protocol_handlers()
66
76
# don't pollute the current handlers
67
transport._clear_protocol_handlers()
77
_clear_protocol_handlers()
68
78
class SampleHandler(object):
69
79
"""I exist, isnt that enough?"""
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')
81
_clear_protocol_handlers()
82
register_transport_proto('foo')
83
register_lazy_transport('foo', 'bzrlib.tests.test_transport',
84
'TestTransport.SampleHandler')
85
register_transport_proto('bar')
86
register_lazy_transport('bar', 'bzrlib.tests.test_transport',
87
'TestTransport.SampleHandler')
80
88
self.assertEqual([SampleHandler.__module__,
81
89
'bzrlib.transport.chroot',
82
90
'bzrlib.transport.pathfilter'],
83
transport._get_transport_modules())
91
_get_transport_modules())
85
transport._set_protocol_handlers(handlers)
93
_set_protocol_handlers(handlers)
87
95
def test_transport_dependency(self):
88
96
"""Transport with missing dependency causes no error"""
89
saved_handlers = transport._get_protocol_handlers()
97
saved_handlers = _get_protocol_handlers()
90
98
# don't pollute the current handlers
91
transport._clear_protocol_handlers()
99
_clear_protocol_handlers()
93
transport.register_transport_proto('foo')
94
transport.register_lazy_transport(
95
'foo', 'bzrlib.tests.test_transport', 'BadTransportHandler')
101
register_transport_proto('foo')
102
register_lazy_transport('foo', 'bzrlib.tests.test_transport',
103
'BadTransportHandler')
97
transport.get_transport('foo://fooserver/foo')
98
except errors.UnsupportedProtocol, e:
105
get_transport('foo://fooserver/foo')
106
except UnsupportedProtocol, e:
100
108
self.assertEquals('Unsupported protocol'
101
109
' for url "foo://fooserver/foo":'
105
113
self.fail('Did not raise UnsupportedProtocol')
107
115
# restore original values
108
transport._set_protocol_handlers(saved_handlers)
116
_set_protocol_handlers(saved_handlers)
110
118
def test_transport_fallback(self):
111
119
"""Transport with missing dependency causes no error"""
112
saved_handlers = transport._get_protocol_handlers()
120
saved_handlers = _get_protocol_handlers()
114
transport._clear_protocol_handlers()
115
transport.register_transport_proto('foo')
116
transport.register_lazy_transport(
117
'foo', 'bzrlib.tests.test_transport', 'BackupTransportHandler')
118
transport.register_lazy_transport(
119
'foo', 'bzrlib.tests.test_transport', 'BadTransportHandler')
120
t = transport.get_transport('foo://fooserver/foo')
122
_clear_protocol_handlers()
123
register_transport_proto('foo')
124
register_lazy_transport('foo', 'bzrlib.tests.test_transport',
125
'BackupTransportHandler')
126
register_lazy_transport('foo', 'bzrlib.tests.test_transport',
127
'BadTransportHandler')
128
t = get_transport('foo://fooserver/foo')
121
129
self.assertTrue(isinstance(t, BackupTransportHandler))
123
transport._set_protocol_handlers(saved_handlers)
131
_set_protocol_handlers(saved_handlers)
125
133
def test_ssh_hints(self):
126
134
"""Transport ssh:// should raise an error pointing out bzr+ssh://"""
128
transport.get_transport('ssh://fooserver/foo')
129
except errors.UnsupportedProtocol, e:
136
get_transport('ssh://fooserver/foo')
137
except UnsupportedProtocol, e:
131
139
self.assertEquals('Unsupported protocol'
132
140
' for url "ssh://fooserver/foo":'
133
' bzr supports bzr+ssh to operate over ssh,'
134
' use "bzr+ssh://fooserver/foo".',
141
' bzr supports bzr+ssh to operate over ssh, use "bzr+ssh://fooserver/foo".',
137
144
self.fail('Did not raise UnsupportedProtocol')
139
146
def test_LateReadError(self):
140
147
"""The LateReadError helper should raise on read()."""
141
a_file = transport.LateReadError('a path')
148
a_file = LateReadError('a path')
144
except errors.ReadError, error:
151
except ReadError, error:
145
152
self.assertEqual('a path', error.path)
146
self.assertRaises(errors.ReadError, a_file.read, 40)
153
self.assertRaises(ReadError, a_file.read, 40)
149
156
def test__combine_paths(self):
150
t = transport.Transport('/')
151
158
self.assertEqual('/home/sarah/project/foo',
152
159
t._combine_paths('/home/sarah', 'project/foo'))
153
160
self.assertEqual('/etc',
249
256
max_size=1*1024*1024*1024)
252
class TestMemoryServer(tests.TestCase):
254
def test_create_server(self):
255
server = memory.MemoryServer()
256
server.start_server()
257
url = server.get_url()
258
self.assertTrue(url in transport.transport_list_registry)
259
t = transport.get_transport(url)
262
self.assertFalse(url in transport.transport_list_registry)
263
self.assertRaises(errors.UnsupportedProtocol,
264
transport.get_transport, url)
267
class TestMemoryTransport(tests.TestCase):
259
class TestMemoryTransport(TestCase):
269
261
def test_get_transport(self):
270
memory.MemoryTransport()
272
264
def test_clone(self):
273
t = memory.MemoryTransport()
274
self.assertTrue(isinstance(t, memory.MemoryTransport))
275
self.assertEqual("memory:///", t.clone("/").base)
265
transport = MemoryTransport()
266
self.assertTrue(isinstance(transport, MemoryTransport))
267
self.assertEqual("memory:///", transport.clone("/").base)
277
269
def test_abspath(self):
278
t = memory.MemoryTransport()
279
self.assertEqual("memory:///relpath", t.abspath('relpath'))
270
transport = MemoryTransport()
271
self.assertEqual("memory:///relpath", transport.abspath('relpath'))
281
273
def test_abspath_of_root(self):
282
t = memory.MemoryTransport()
283
self.assertEqual("memory:///", t.base)
284
self.assertEqual("memory:///", t.abspath('/'))
274
transport = MemoryTransport()
275
self.assertEqual("memory:///", transport.base)
276
self.assertEqual("memory:///", transport.abspath('/'))
286
278
def test_abspath_of_relpath_starting_at_root(self):
287
t = memory.MemoryTransport()
288
self.assertEqual("memory:///foo", t.abspath('/foo'))
279
transport = MemoryTransport()
280
self.assertEqual("memory:///foo", transport.abspath('/foo'))
290
282
def test_append_and_get(self):
291
t = memory.MemoryTransport()
292
t.append_bytes('path', 'content')
293
self.assertEqual(t.get('path').read(), 'content')
294
t.append_file('path', StringIO('content'))
295
self.assertEqual(t.get('path').read(), 'contentcontent')
283
transport = MemoryTransport()
284
transport.append_bytes('path', 'content')
285
self.assertEqual(transport.get('path').read(), 'content')
286
transport.append_file('path', StringIO('content'))
287
self.assertEqual(transport.get('path').read(), 'contentcontent')
297
289
def test_put_and_get(self):
298
t = memory.MemoryTransport()
299
t.put_file('path', StringIO('content'))
300
self.assertEqual(t.get('path').read(), 'content')
301
t.put_bytes('path', 'content')
302
self.assertEqual(t.get('path').read(), 'content')
290
transport = MemoryTransport()
291
transport.put_file('path', StringIO('content'))
292
self.assertEqual(transport.get('path').read(), 'content')
293
transport.put_bytes('path', 'content')
294
self.assertEqual(transport.get('path').read(), 'content')
304
296
def test_append_without_dir_fails(self):
305
t = memory.MemoryTransport()
306
self.assertRaises(errors.NoSuchFile,
307
t.append_bytes, 'dir/path', 'content')
297
transport = MemoryTransport()
298
self.assertRaises(NoSuchFile,
299
transport.append_bytes, 'dir/path', 'content')
309
301
def test_put_without_dir_fails(self):
310
t = memory.MemoryTransport()
311
self.assertRaises(errors.NoSuchFile,
312
t.put_file, 'dir/path', StringIO('content'))
302
transport = MemoryTransport()
303
self.assertRaises(NoSuchFile,
304
transport.put_file, 'dir/path', StringIO('content'))
314
306
def test_get_missing(self):
315
transport = memory.MemoryTransport()
316
self.assertRaises(errors.NoSuchFile, transport.get, 'foo')
307
transport = MemoryTransport()
308
self.assertRaises(NoSuchFile, transport.get, 'foo')
318
310
def test_has_missing(self):
319
t = memory.MemoryTransport()
320
self.assertEquals(False, t.has('foo'))
311
transport = MemoryTransport()
312
self.assertEquals(False, transport.has('foo'))
322
314
def test_has_present(self):
323
t = memory.MemoryTransport()
324
t.append_bytes('foo', 'content')
325
self.assertEquals(True, t.has('foo'))
315
transport = MemoryTransport()
316
transport.append_bytes('foo', 'content')
317
self.assertEquals(True, transport.has('foo'))
327
319
def test_list_dir(self):
328
t = memory.MemoryTransport()
329
t.put_bytes('foo', 'content')
331
t.put_bytes('dir/subfoo', 'content')
332
t.put_bytes('dirlike', 'content')
320
transport = MemoryTransport()
321
transport.put_bytes('foo', 'content')
322
transport.mkdir('dir')
323
transport.put_bytes('dir/subfoo', 'content')
324
transport.put_bytes('dirlike', 'content')
334
self.assertEquals(['dir', 'dirlike', 'foo'], sorted(t.list_dir('.')))
335
self.assertEquals(['subfoo'], sorted(t.list_dir('dir')))
326
self.assertEquals(['dir', 'dirlike', 'foo'], sorted(transport.list_dir('.')))
327
self.assertEquals(['subfoo'], sorted(transport.list_dir('dir')))
337
329
def test_mkdir(self):
338
t = memory.MemoryTransport()
340
t.append_bytes('dir/path', 'content')
341
self.assertEqual(t.get('dir/path').read(), 'content')
330
transport = MemoryTransport()
331
transport.mkdir('dir')
332
transport.append_bytes('dir/path', 'content')
333
self.assertEqual(transport.get('dir/path').read(), 'content')
343
335
def test_mkdir_missing_parent(self):
344
t = memory.MemoryTransport()
345
self.assertRaises(errors.NoSuchFile, t.mkdir, 'dir/dir')
336
transport = MemoryTransport()
337
self.assertRaises(NoSuchFile,
338
transport.mkdir, 'dir/dir')
347
340
def test_mkdir_twice(self):
348
t = memory.MemoryTransport()
350
self.assertRaises(errors.FileExists, t.mkdir, 'dir')
341
transport = MemoryTransport()
342
transport.mkdir('dir')
343
self.assertRaises(FileExists, transport.mkdir, 'dir')
352
345
def test_parameters(self):
353
t = memory.MemoryTransport()
354
self.assertEqual(True, t.listable())
355
self.assertEqual(False, t.is_readonly())
346
transport = MemoryTransport()
347
self.assertEqual(True, transport.listable())
348
self.assertEqual(False, transport.is_readonly())
357
350
def test_iter_files_recursive(self):
358
t = memory.MemoryTransport()
360
t.put_bytes('dir/foo', 'content')
361
t.put_bytes('dir/bar', 'content')
362
t.put_bytes('bar', 'content')
363
paths = set(t.iter_files_recursive())
351
transport = MemoryTransport()
352
transport.mkdir('dir')
353
transport.put_bytes('dir/foo', 'content')
354
transport.put_bytes('dir/bar', 'content')
355
transport.put_bytes('bar', 'content')
356
paths = set(transport.iter_files_recursive())
364
357
self.assertEqual(set(['dir/foo', 'dir/bar', 'bar']), paths)
366
359
def test_stat(self):
367
t = memory.MemoryTransport()
368
t.put_bytes('foo', 'content')
369
t.put_bytes('bar', 'phowar')
370
self.assertEqual(7, t.stat('foo').st_size)
371
self.assertEqual(6, t.stat('bar').st_size)
374
class ChrootDecoratorTransportTest(tests.TestCase):
360
transport = MemoryTransport()
361
transport.put_bytes('foo', 'content')
362
transport.put_bytes('bar', 'phowar')
363
self.assertEqual(7, transport.stat('foo').st_size)
364
self.assertEqual(6, transport.stat('bar').st_size)
367
class ChrootDecoratorTransportTest(TestCase):
375
368
"""Chroot decoration specific tests."""
377
370
def test_abspath(self):
378
371
# The abspath is always relative to the chroot_url.
379
server = chroot.ChrootServer(
380
transport.get_transport('memory:///foo/bar/'))
372
server = ChrootServer(get_transport('memory:///foo/bar/'))
381
373
self.start_server(server)
382
t = transport.get_transport(server.get_url())
383
self.assertEqual(server.get_url(), t.abspath('/'))
374
transport = get_transport(server.get_url())
375
self.assertEqual(server.get_url(), transport.abspath('/'))
385
subdir_t = t.clone('subdir')
386
self.assertEqual(server.get_url(), subdir_t.abspath('/'))
377
subdir_transport = transport.clone('subdir')
378
self.assertEqual(server.get_url(), subdir_transport.abspath('/'))
388
380
def test_clone(self):
389
server = chroot.ChrootServer(
390
transport.get_transport('memory:///foo/bar/'))
381
server = ChrootServer(get_transport('memory:///foo/bar/'))
391
382
self.start_server(server)
392
t = transport.get_transport(server.get_url())
383
transport = get_transport(server.get_url())
393
384
# relpath from root and root path are the same
394
relpath_cloned = t.clone('foo')
395
abspath_cloned = t.clone('/foo')
385
relpath_cloned = transport.clone('foo')
386
abspath_cloned = transport.clone('/foo')
396
387
self.assertEqual(server, relpath_cloned.server)
397
388
self.assertEqual(server, abspath_cloned.server)
421
411
This is so that it is not possible to escape a chroot by doing::
422
412
url = chroot_transport.base
423
413
parent_url = urlutils.join(url, '..')
424
new_t = transport.get_transport(parent_url)
414
new_transport = get_transport(parent_url)
426
server = chroot.ChrootServer(transport.get_transport('memory:///path/'))
416
server = ChrootServer(get_transport('memory:///path/'))
427
417
self.start_server(server)
428
t = transport.get_transport(server.get_url())
418
transport = get_transport(server.get_url())
429
419
self.assertRaises(
430
errors.InvalidURLJoin, urlutils.join, t.base, '..')
433
class TestChrootServer(tests.TestCase):
420
InvalidURLJoin, urlutils.join, transport.base, '..')
423
class ChrootServerTest(TestCase):
435
425
def test_construct(self):
436
backing_transport = memory.MemoryTransport()
437
server = chroot.ChrootServer(backing_transport)
426
backing_transport = MemoryTransport()
427
server = ChrootServer(backing_transport)
438
428
self.assertEqual(backing_transport, server.backing_transport)
440
430
def test_setUp(self):
441
backing_transport = memory.MemoryTransport()
442
server = chroot.ChrootServer(backing_transport)
443
server.start_server()
431
backing_transport = MemoryTransport()
432
server = ChrootServer(backing_transport)
445
self.assertTrue(server.scheme
446
in transport._get_protocol_handlers().keys())
435
self.assertTrue(server.scheme in _get_protocol_handlers().keys())
450
def test_stop_server(self):
451
backing_transport = memory.MemoryTransport()
452
server = chroot.ChrootServer(backing_transport)
453
server.start_server()
455
self.assertFalse(server.scheme
456
in transport._get_protocol_handlers().keys())
439
def test_tearDown(self):
440
backing_transport = MemoryTransport()
441
server = ChrootServer(backing_transport)
444
self.assertFalse(server.scheme in _get_protocol_handlers().keys())
458
446
def test_get_url(self):
459
backing_transport = memory.MemoryTransport()
460
server = chroot.ChrootServer(backing_transport)
461
server.start_server()
447
backing_transport = MemoryTransport()
448
server = ChrootServer(backing_transport)
463
451
self.assertEqual('chroot-%d:///' % id(server), server.get_url())
468
class PathFilteringDecoratorTransportTest(tests.TestCase):
456
class PathFilteringDecoratorTransportTest(TestCase):
469
457
"""Pathfilter decoration specific tests."""
471
459
def test_abspath(self):
472
460
# The abspath is always relative to the base of the backing transport.
473
server = pathfilter.PathFilteringServer(
474
transport.get_transport('memory:///foo/bar/'),
461
server = PathFilteringServer(get_transport('memory:///foo/bar/'),
476
server.start_server()
477
t = transport.get_transport(server.get_url())
478
self.assertEqual(server.get_url(), t.abspath('/'))
464
transport = get_transport(server.get_url())
465
self.assertEqual(server.get_url(), transport.abspath('/'))
480
subdir_t = t.clone('subdir')
481
self.assertEqual(server.get_url(), subdir_t.abspath('/'))
467
subdir_transport = transport.clone('subdir')
468
self.assertEqual(server.get_url(), subdir_transport.abspath('/'))
484
471
def make_pf_transport(self, filter_func=None):
485
472
"""Make a PathFilteringTransport backed by a MemoryTransport.
488
475
parameter to override it."""
489
476
if filter_func is None:
490
477
filter_func = lambda x: x
491
server = pathfilter.PathFilteringServer(
492
transport.get_transport('memory:///foo/bar/'), filter_func)
493
server.start_server()
494
self.addCleanup(server.stop_server)
495
return transport.get_transport(server.get_url())
478
server = PathFilteringServer(
479
get_transport('memory:///foo/bar/'), filter_func)
481
self.addCleanup(server.tearDown)
482
return get_transport(server.get_url())
497
484
def test__filter(self):
498
485
# _filter (with an identity func as filter_func) always returns
499
486
# paths relative to the base of the backing transport.
500
t = self.make_pf_transport()
501
self.assertEqual('foo', t._filter('foo'))
502
self.assertEqual('foo/bar', t._filter('foo/bar'))
503
self.assertEqual('', t._filter('..'))
504
self.assertEqual('', t._filter('/'))
487
transport = self.make_pf_transport()
488
self.assertEqual('foo', transport._filter('foo'))
489
self.assertEqual('foo/bar', transport._filter('foo/bar'))
490
self.assertEqual('', transport._filter('..'))
491
self.assertEqual('', transport._filter('/'))
505
492
# The base of the pathfiltering transport is taken into account too.
506
t = t.clone('subdir1/subdir2')
507
self.assertEqual('subdir1/subdir2/foo', t._filter('foo'))
508
self.assertEqual('subdir1/subdir2/foo/bar', t._filter('foo/bar'))
509
self.assertEqual('subdir1', t._filter('..'))
510
self.assertEqual('', t._filter('/'))
493
transport = transport.clone('subdir1/subdir2')
494
self.assertEqual('subdir1/subdir2/foo', transport._filter('foo'))
496
'subdir1/subdir2/foo/bar', transport._filter('foo/bar'))
497
self.assertEqual('subdir1', transport._filter('..'))
498
self.assertEqual('', transport._filter('/'))
512
500
def test_filter_invocation(self):
514
502
def filter(path):
515
503
filter_log.append(path)
517
t = self.make_pf_transport(filter)
505
transport = self.make_pf_transport(filter)
519
507
self.assertEqual(['abc'], filter_log)
520
508
del filter_log[:]
521
t.clone('abc').has('xyz')
509
transport.clone('abc').has('xyz')
522
510
self.assertEqual(['abc/xyz'], filter_log)
523
511
del filter_log[:]
512
transport.has('/abc')
525
513
self.assertEqual(['abc'], filter_log)
527
515
def test_clone(self):
528
t = self.make_pf_transport()
516
transport = self.make_pf_transport()
529
517
# relpath from root and root path are the same
530
relpath_cloned = t.clone('foo')
531
abspath_cloned = t.clone('/foo')
532
self.assertEqual(t.server, relpath_cloned.server)
533
self.assertEqual(t.server, abspath_cloned.server)
518
relpath_cloned = transport.clone('foo')
519
abspath_cloned = transport.clone('/foo')
520
self.assertEqual(transport.server, relpath_cloned.server)
521
self.assertEqual(transport.server, abspath_cloned.server)
535
523
def test_url_preserves_pathfiltering(self):
536
524
"""Calling get_transport on a pathfiltered transport's base should
541
529
otherwise) the filtering by doing::
542
530
url = filtered_transport.base
543
531
parent_url = urlutils.join(url, '..')
544
new_t = transport.get_transport(parent_url)
532
new_transport = get_transport(parent_url)
546
t = self.make_pf_transport()
547
new_t = transport.get_transport(t.base)
548
self.assertEqual(t.server, new_t.server)
549
self.assertEqual(t.base, new_t.base)
552
class ReadonlyDecoratorTransportTest(tests.TestCase):
534
transport = self.make_pf_transport()
535
new_transport = get_transport(transport.base)
536
self.assertEqual(transport.server, new_transport.server)
537
self.assertEqual(transport.base, new_transport.base)
540
class ReadonlyDecoratorTransportTest(TestCase):
553
541
"""Readonly decoration specific tests."""
555
543
def test_local_parameters(self):
544
import bzrlib.transport.readonly as readonly
556
545
# connect to . in readonly mode
557
t = readonly.ReadonlyTransportDecorator('readonly+.')
558
self.assertEqual(True, t.listable())
559
self.assertEqual(True, t.is_readonly())
546
transport = readonly.ReadonlyTransportDecorator('readonly+.')
547
self.assertEqual(True, transport.listable())
548
self.assertEqual(True, transport.is_readonly())
561
550
def test_http_parameters(self):
562
551
from bzrlib.tests.http_server import HttpServer
552
import bzrlib.transport.readonly as readonly
563
553
# connect to '.' via http which is not listable
564
554
server = HttpServer()
565
555
self.start_server(server)
566
t = transport.get_transport('readonly+' + server.get_url())
567
self.assertIsInstance(t, readonly.ReadonlyTransportDecorator)
568
self.assertEqual(False, t.listable())
569
self.assertEqual(True, t.is_readonly())
572
class FakeNFSDecoratorTests(tests.TestCaseInTempDir):
556
transport = get_transport('readonly+' + server.get_url())
557
self.failUnless(isinstance(transport,
558
readonly.ReadonlyTransportDecorator))
559
self.assertEqual(False, transport.listable())
560
self.assertEqual(True, transport.is_readonly())
563
class FakeNFSDecoratorTests(TestCaseInTempDir):
573
564
"""NFS decorator specific tests."""
575
566
def get_nfs_transport(self, url):
567
import bzrlib.transport.fakenfs as fakenfs
576
568
# connect to url with nfs decoration
577
569
return fakenfs.FakeNFSTransportDecorator('fakenfs+' + url)
579
571
def test_local_parameters(self):
580
572
# the listable and is_readonly parameters
581
573
# are not changed by the fakenfs decorator
582
t = self.get_nfs_transport('.')
583
self.assertEqual(True, t.listable())
584
self.assertEqual(False, t.is_readonly())
574
transport = self.get_nfs_transport('.')
575
self.assertEqual(True, transport.listable())
576
self.assertEqual(False, transport.is_readonly())
586
578
def test_http_parameters(self):
587
579
# the listable and is_readonly parameters
590
582
# connect to '.' via http which is not listable
591
583
server = HttpServer()
592
584
self.start_server(server)
593
t = self.get_nfs_transport(server.get_url())
594
self.assertIsInstance(t, fakenfs.FakeNFSTransportDecorator)
595
self.assertEqual(False, t.listable())
596
self.assertEqual(True, t.is_readonly())
585
transport = self.get_nfs_transport(server.get_url())
586
self.assertIsInstance(
587
transport, bzrlib.transport.fakenfs.FakeNFSTransportDecorator)
588
self.assertEqual(False, transport.listable())
589
self.assertEqual(True, transport.is_readonly())
598
591
def test_fakenfs_server_default(self):
599
592
# a FakeNFSServer() should bring up a local relpath server for itself
600
server = test_server.FakeNFSServer()
593
import bzrlib.transport.fakenfs as fakenfs
594
server = fakenfs.FakeNFSServer()
601
595
self.start_server(server)
602
596
# the url should be decorated appropriately
603
597
self.assertStartsWith(server.get_url(), 'fakenfs+')
604
598
# and we should be able to get a transport for it
605
t = transport.get_transport(server.get_url())
599
transport = get_transport(server.get_url())
606
600
# which must be a FakeNFSTransportDecorator instance.
607
self.assertIsInstance(t, fakenfs.FakeNFSTransportDecorator)
601
self.assertIsInstance(transport, fakenfs.FakeNFSTransportDecorator)
609
603
def test_fakenfs_rename_semantics(self):
610
604
# a FakeNFS transport must mangle the way rename errors occur to
611
605
# look like NFS problems.
612
t = self.get_nfs_transport('.')
606
transport = self.get_nfs_transport('.')
613
607
self.build_tree(['from/', 'from/foo', 'to/', 'to/bar'],
615
self.assertRaises(errors.ResourceBusy, t.rename, 'from', 'to')
618
class FakeVFATDecoratorTests(tests.TestCaseInTempDir):
609
self.assertRaises(errors.ResourceBusy,
610
transport.rename, 'from', 'to')
613
class FakeVFATDecoratorTests(TestCaseInTempDir):
619
614
"""Tests for simulation of VFAT restrictions"""
621
616
def get_vfat_transport(self, url):
699
class TestLocalTransports(tests.TestCase):
693
class TestLocalTransports(TestCase):
701
695
def test_get_transport_from_abspath(self):
702
696
here = osutils.abspath('.')
703
t = transport.get_transport(here)
704
self.assertIsInstance(t, local.LocalTransport)
697
t = get_transport(here)
698
self.assertIsInstance(t, LocalTransport)
705
699
self.assertEquals(t.base, urlutils.local_path_to_url(here) + '/')
707
701
def test_get_transport_from_relpath(self):
708
702
here = osutils.abspath('.')
709
t = transport.get_transport('.')
710
self.assertIsInstance(t, local.LocalTransport)
703
t = get_transport('.')
704
self.assertIsInstance(t, LocalTransport)
711
705
self.assertEquals(t.base, urlutils.local_path_to_url('.') + '/')
713
707
def test_get_transport_from_local_url(self):
714
708
here = osutils.abspath('.')
715
709
here_url = urlutils.local_path_to_url(here) + '/'
716
t = transport.get_transport(here_url)
717
self.assertIsInstance(t, local.LocalTransport)
710
t = get_transport(here_url)
711
self.assertIsInstance(t, LocalTransport)
718
712
self.assertEquals(t.base, here_url)
720
714
def test_local_abspath(self):
721
715
here = osutils.abspath('.')
722
t = transport.get_transport(here)
716
t = get_transport(here)
723
717
self.assertEquals(t.local_abspath(''), here)
726
class TestLocalTransportWriteStream(tests.TestCaseWithTransport):
728
def test_local_fdatasync_calls_fdatasync(self):
729
"""Check fdatasync on a stream tries to flush the data to the OS.
731
We can't easily observe the external effect but we can at least see
734
t = self.get_transport('.')
735
calls = self.recordCalls(os, 'fdatasync')
736
w = t.open_write_stream('out')
739
with open('out', 'rb') as f:
740
# Should have been flushed.
741
self.assertEquals(f.read(), 'foo')
742
self.assertEquals(len(calls), 1, calls)
745
class TestWin32LocalTransport(tests.TestCase):
720
class TestWin32LocalTransport(TestCase):
747
722
def test_unc_clone_to_root(self):
748
723
# Win32 UNC path like \\HOST\path
749
724
# clone to root should stop at least at \\HOST part
751
t = local.EmulatedWin32LocalTransport('file://HOST/path/to/some/dir/')
726
t = EmulatedWin32LocalTransport('file://HOST/path/to/some/dir/')
752
727
for i in xrange(4):
753
728
t = t.clone('..')
754
729
self.assertEquals(t.base, 'file://HOST/')
841
814
self.assertIs(new_password, c._get_credentials())
844
class TestReusedTransports(tests.TestCase):
817
class TestReusedTransports(TestCase):
845
818
"""Tests for transport reuse"""
847
820
def test_reuse_same_transport(self):
848
821
possible_transports = []
849
t1 = transport.get_transport('http://foo/',
850
possible_transports=possible_transports)
822
t1 = get_transport('http://foo/',
823
possible_transports=possible_transports)
851
824
self.assertEqual([t1], possible_transports)
852
t2 = transport.get_transport('http://foo/',
853
possible_transports=[t1])
825
t2 = get_transport('http://foo/', possible_transports=[t1])
854
826
self.assertIs(t1, t2)
856
828
# Also check that final '/' are handled correctly
857
t3 = transport.get_transport('http://foo/path/')
858
t4 = transport.get_transport('http://foo/path',
859
possible_transports=[t3])
829
t3 = get_transport('http://foo/path/')
830
t4 = get_transport('http://foo/path', possible_transports=[t3])
860
831
self.assertIs(t3, t4)
862
t5 = transport.get_transport('http://foo/path')
863
t6 = transport.get_transport('http://foo/path/',
864
possible_transports=[t5])
833
t5 = get_transport('http://foo/path')
834
t6 = get_transport('http://foo/path/', possible_transports=[t5])
865
835
self.assertIs(t5, t6)
867
837
def test_don_t_reuse_different_transport(self):
868
t1 = transport.get_transport('http://foo/path')
869
t2 = transport.get_transport('http://bar/path',
870
possible_transports=[t1])
838
t1 = get_transport('http://foo/path')
839
t2 = get_transport('http://bar/path', possible_transports=[t1])
871
840
self.assertIsNot(t1, t2)
874
class TestTransportTrace(tests.TestCase):
843
class TestTransportTrace(TestCase):
876
845
def test_get(self):
877
t = transport.get_transport('trace+memory://')
878
self.assertIsInstance(t, bzrlib.transport.trace.TransportTraceDecorator)
846
transport = get_transport('trace+memory://')
847
self.assertIsInstance(
848
transport, bzrlib.transport.trace.TransportTraceDecorator)
880
850
def test_clone_preserves_activity(self):
881
t = transport.get_transport('trace+memory://')
883
self.assertTrue(t is not t2)
884
self.assertTrue(t._activity is t2._activity)
851
transport = get_transport('trace+memory://')
852
transport2 = transport.clone('.')
853
self.assertTrue(transport is not transport2)
854
self.assertTrue(transport._activity is transport2._activity)
886
856
# the following specific tests are for the operations that have made use of
887
857
# logging in tests; we could test every single operation but doing that
888
858
# still won't cause a test failure when the top level Transport API
889
859
# changes; so there is little return doing that.
890
860
def test_get(self):
891
t = transport.get_transport('trace+memory:///')
892
t.put_bytes('foo', 'barish')
861
transport = get_transport('trace+memory:///')
862
transport.put_bytes('foo', 'barish')
894
864
expected_result = []
895
865
# put_bytes records the bytes, not the content to avoid memory
897
867
expected_result.append(('put_bytes', 'foo', 6, None))
898
868
# get records the file name only.
899
869
expected_result.append(('get', 'foo'))
900
self.assertEqual(expected_result, t._activity)
870
self.assertEqual(expected_result, transport._activity)
902
872
def test_readv(self):
903
t = transport.get_transport('trace+memory:///')
904
t.put_bytes('foo', 'barish')
905
list(t.readv('foo', [(0, 1), (3, 2)],
906
adjust_for_latency=True, upper_limit=6))
873
transport = get_transport('trace+memory:///')
874
transport.put_bytes('foo', 'barish')
875
list(transport.readv('foo', [(0, 1), (3, 2)], adjust_for_latency=True,
907
877
expected_result = []
908
878
# put_bytes records the bytes, not the content to avoid memory
910
880
expected_result.append(('put_bytes', 'foo', 6, None))
911
881
# readv records the supplied offset request
912
882
expected_result.append(('readv', 'foo', [(0, 1), (3, 2)], True, 6))
913
self.assertEqual(expected_result, t._activity)
883
self.assertEqual(expected_result, transport._activity)
916
886
class TestSSHConnections(tests.TestCaseWithTransport):