28
transport as _mod_transport,
31
from bzrlib.directory_service import directories
32
31
from bzrlib.transport import (
42
import bzrlib.transport.trace
43
from bzrlib.tests import (
36
from bzrlib.errors import (DependencyNotPresent,
44
from bzrlib.tests import features, TestCase, TestCaseInTempDir
45
from bzrlib.transport import (_clear_protocol_handlers,
48
_get_protocol_handlers,
49
_set_protocol_handlers,
50
_get_transport_modules,
53
register_lazy_transport,
54
register_transport_proto,
57
from bzrlib.transport.chroot import ChrootServer
58
from bzrlib.transport.local import (LocalTransport,
59
EmulatedWin32LocalTransport)
60
from bzrlib.transport.pathfilter import PathFilteringServer
49
63
# TODO: Should possibly split transport-specific tests into their own files.
52
class TestTransport(tests.TestCase):
66
class TestTransport(TestCase):
53
67
"""Test the non transport-concrete class functionality."""
55
69
def test__get_set_protocol_handlers(self):
56
handlers = transport._get_protocol_handlers()
57
self.assertNotEqual([], handlers.keys())
58
transport._clear_protocol_handlers()
59
self.addCleanup(transport._set_protocol_handlers, handlers)
60
self.assertEqual([], transport._get_protocol_handlers().keys())
70
handlers = _get_protocol_handlers()
71
self.assertNotEqual([], handlers.keys( ))
73
_clear_protocol_handlers()
74
self.assertEqual([], _get_protocol_handlers().keys())
76
_set_protocol_handlers(handlers)
62
78
def test_get_transport_modules(self):
63
handlers = transport._get_protocol_handlers()
64
self.addCleanup(transport._set_protocol_handlers, handlers)
79
handlers = _get_protocol_handlers()
65
80
# don't pollute the current handlers
66
transport._clear_protocol_handlers()
81
_clear_protocol_handlers()
68
82
class SampleHandler(object):
69
83
"""I exist, isnt that enough?"""
70
transport._clear_protocol_handlers()
71
transport.register_transport_proto('foo')
72
transport.register_lazy_transport('foo',
73
'bzrlib.tests.test_transport',
74
'TestTransport.SampleHandler')
75
transport.register_transport_proto('bar')
76
transport.register_lazy_transport('bar',
77
'bzrlib.tests.test_transport',
78
'TestTransport.SampleHandler')
79
self.assertEqual([SampleHandler.__module__,
80
'bzrlib.transport.chroot',
81
'bzrlib.transport.pathfilter'],
82
transport._get_transport_modules())
85
_clear_protocol_handlers()
86
register_transport_proto('foo')
87
register_lazy_transport('foo', 'bzrlib.tests.test_transport',
88
'TestTransport.SampleHandler')
89
register_transport_proto('bar')
90
register_lazy_transport('bar', 'bzrlib.tests.test_transport',
91
'TestTransport.SampleHandler')
92
self.assertEqual([SampleHandler.__module__,
93
'bzrlib.transport.chroot',
94
'bzrlib.transport.pathfilter'],
95
_get_transport_modules())
97
_set_protocol_handlers(handlers)
84
99
def test_transport_dependency(self):
85
100
"""Transport with missing dependency causes no error"""
86
saved_handlers = transport._get_protocol_handlers()
87
self.addCleanup(transport._set_protocol_handlers, saved_handlers)
101
saved_handlers = _get_protocol_handlers()
88
102
# don't pollute the current handlers
89
transport._clear_protocol_handlers()
90
transport.register_transport_proto('foo')
91
transport.register_lazy_transport(
92
'foo', 'bzrlib.tests.test_transport', 'BadTransportHandler')
103
_clear_protocol_handlers()
94
transport.get_transport_from_url('foo://fooserver/foo')
95
except errors.UnsupportedProtocol, e:
97
self.assertEquals('Unsupported protocol'
98
' for url "foo://fooserver/foo":'
99
' Unable to import library "some_lib":'
100
' testing missing dependency', str(e))
102
self.fail('Did not raise UnsupportedProtocol')
105
register_transport_proto('foo')
106
register_lazy_transport('foo', 'bzrlib.tests.test_transport',
107
'BadTransportHandler')
109
get_transport('foo://fooserver/foo')
110
except UnsupportedProtocol, e:
112
self.assertEquals('Unsupported protocol'
113
' for url "foo://fooserver/foo":'
114
' Unable to import library "some_lib":'
115
' testing missing dependency', str(e))
117
self.fail('Did not raise UnsupportedProtocol')
119
# restore original values
120
_set_protocol_handlers(saved_handlers)
104
122
def test_transport_fallback(self):
105
123
"""Transport with missing dependency causes no error"""
106
saved_handlers = transport._get_protocol_handlers()
107
self.addCleanup(transport._set_protocol_handlers, saved_handlers)
108
transport._clear_protocol_handlers()
109
transport.register_transport_proto('foo')
110
transport.register_lazy_transport(
111
'foo', 'bzrlib.tests.test_transport', 'BackupTransportHandler')
112
transport.register_lazy_transport(
113
'foo', 'bzrlib.tests.test_transport', 'BadTransportHandler')
114
t = transport.get_transport_from_url('foo://fooserver/foo')
115
self.assertTrue(isinstance(t, BackupTransportHandler))
124
saved_handlers = _get_protocol_handlers()
126
_clear_protocol_handlers()
127
register_transport_proto('foo')
128
register_lazy_transport('foo', 'bzrlib.tests.test_transport',
129
'BackupTransportHandler')
130
register_lazy_transport('foo', 'bzrlib.tests.test_transport',
131
'BadTransportHandler')
132
t = get_transport('foo://fooserver/foo')
133
self.assertTrue(isinstance(t, BackupTransportHandler))
135
_set_protocol_handlers(saved_handlers)
117
137
def test_ssh_hints(self):
118
138
"""Transport ssh:// should raise an error pointing out bzr+ssh://"""
120
transport.get_transport_from_url('ssh://fooserver/foo')
121
except errors.UnsupportedProtocol, e:
140
get_transport('ssh://fooserver/foo')
141
except UnsupportedProtocol, e:
123
143
self.assertEquals('Unsupported protocol'
124
144
' for url "ssh://fooserver/foo":'
125
' bzr supports bzr+ssh to operate over ssh,'
126
' use "bzr+ssh://fooserver/foo".',
145
' bzr supports bzr+ssh to operate over ssh, use "bzr+ssh://fooserver/foo".',
129
148
self.fail('Did not raise UnsupportedProtocol')
131
150
def test_LateReadError(self):
132
151
"""The LateReadError helper should raise on read()."""
133
a_file = transport.LateReadError('a path')
152
a_file = LateReadError('a path')
136
except errors.ReadError, error:
155
except ReadError, error:
137
156
self.assertEqual('a path', error.path)
138
self.assertRaises(errors.ReadError, a_file.read, 40)
157
self.assertRaises(ReadError, a_file.read, 40)
160
def test__combine_paths(self):
162
self.assertEqual('/home/sarah/project/foo',
163
t._combine_paths('/home/sarah', 'project/foo'))
164
self.assertEqual('/etc',
165
t._combine_paths('/home/sarah', '../../etc'))
166
self.assertEqual('/etc',
167
t._combine_paths('/home/sarah', '../../../etc'))
168
self.assertEqual('/etc',
169
t._combine_paths('/home/sarah', '/etc'))
141
171
def test_local_abspath_non_local_transport(self):
142
172
# the base implementation should throw
143
173
t = memory.MemoryTransport()
201
231
def test_coalesce_fudge(self):
202
232
self.check([(10, 30, [(0, 10), (20, 10)]),
203
(100, 10, [(0, 10)]),
233
(100, 10, [(0, 10),]),
204
234
], [(10, 10), (30, 10), (100, 10)],
207
237
def test_coalesce_max_size(self):
208
238
self.check([(10, 20, [(0, 10), (10, 10)]),
209
239
(30, 50, [(0, 50)]),
210
240
# If one range is above max_size, it gets its own coalesced
212
(100, 80, [(0, 80)]),],
242
(100, 80, [(0, 80),]),],
213
243
[(10, 10), (20, 10), (30, 50), (100, 80)],
216
247
def test_coalesce_no_max_size(self):
217
self.check([(10, 170, [(0, 10), (10, 10), (20, 50), (70, 100)])],
248
self.check([(10, 170, [(0, 10), (10, 10), (20, 50), (70, 100)]),],
218
249
[(10, 10), (20, 10), (30, 50), (80, 100)],
221
252
def test_coalesce_default_limit(self):
222
253
# By default we use a 100MB max size.
223
ten_mb = 10 * 1024 * 1024
224
self.check([(0, 10 * ten_mb, [(i * ten_mb, ten_mb) for i in range(10)]),
254
ten_mb = 10*1024*1024
255
self.check([(0, 10*ten_mb, [(i*ten_mb, ten_mb) for i in range(10)]),
225
256
(10*ten_mb, ten_mb, [(0, ten_mb)])],
226
257
[(i*ten_mb, ten_mb) for i in range(11)])
227
self.check([(0, 11 * ten_mb, [(i * ten_mb, ten_mb) for i in range(11)])],
228
[(i * ten_mb, ten_mb) for i in range(11)],
258
self.check([(0, 11*ten_mb, [(i*ten_mb, ten_mb) for i in range(11)]),],
259
[(i*ten_mb, ten_mb) for i in range(11)],
229
260
max_size=1*1024*1024*1024)
232
class TestMemoryServer(tests.TestCase):
263
class TestMemoryServer(TestCase):
234
265
def test_create_server(self):
235
266
server = memory.MemoryServer()
236
267
server.start_server()
237
268
url = server.get_url()
238
self.assertTrue(url in transport.transport_list_registry)
239
t = transport.get_transport_from_url(url)
269
self.assertTrue(url in _mod_transport.transport_list_registry)
270
t = _mod_transport.get_transport(url)
241
272
server.stop_server()
242
self.assertFalse(url in transport.transport_list_registry)
273
self.assertFalse(url in _mod_transport.transport_list_registry)
243
274
self.assertRaises(errors.UnsupportedProtocol,
244
transport.get_transport, url)
247
class TestMemoryTransport(tests.TestCase):
275
_mod_transport.get_transport, url)
278
class TestMemoryTransport(TestCase):
249
280
def test_get_transport(self):
250
281
memory.MemoryTransport()
252
283
def test_clone(self):
253
t = memory.MemoryTransport()
254
self.assertTrue(isinstance(t, memory.MemoryTransport))
255
self.assertEqual("memory:///", t.clone("/").base)
284
transport = memory.MemoryTransport()
285
self.assertTrue(isinstance(transport, memory.MemoryTransport))
286
self.assertEqual("memory:///", transport.clone("/").base)
257
288
def test_abspath(self):
258
t = memory.MemoryTransport()
259
self.assertEqual("memory:///relpath", t.abspath('relpath'))
289
transport = memory.MemoryTransport()
290
self.assertEqual("memory:///relpath", transport.abspath('relpath'))
261
292
def test_abspath_of_root(self):
262
t = memory.MemoryTransport()
263
self.assertEqual("memory:///", t.base)
264
self.assertEqual("memory:///", t.abspath('/'))
293
transport = memory.MemoryTransport()
294
self.assertEqual("memory:///", transport.base)
295
self.assertEqual("memory:///", transport.abspath('/'))
266
297
def test_abspath_of_relpath_starting_at_root(self):
267
t = memory.MemoryTransport()
268
self.assertEqual("memory:///foo", t.abspath('/foo'))
298
transport = memory.MemoryTransport()
299
self.assertEqual("memory:///foo", transport.abspath('/foo'))
270
301
def test_append_and_get(self):
271
t = memory.MemoryTransport()
272
t.append_bytes('path', 'content')
273
self.assertEqual(t.get('path').read(), 'content')
274
t.append_file('path', StringIO('content'))
275
self.assertEqual(t.get('path').read(), 'contentcontent')
302
transport = memory.MemoryTransport()
303
transport.append_bytes('path', 'content')
304
self.assertEqual(transport.get('path').read(), 'content')
305
transport.append_file('path', StringIO('content'))
306
self.assertEqual(transport.get('path').read(), 'contentcontent')
277
308
def test_put_and_get(self):
278
t = memory.MemoryTransport()
279
t.put_file('path', StringIO('content'))
280
self.assertEqual(t.get('path').read(), 'content')
281
t.put_bytes('path', 'content')
282
self.assertEqual(t.get('path').read(), 'content')
309
transport = memory.MemoryTransport()
310
transport.put_file('path', StringIO('content'))
311
self.assertEqual(transport.get('path').read(), 'content')
312
transport.put_bytes('path', 'content')
313
self.assertEqual(transport.get('path').read(), 'content')
284
315
def test_append_without_dir_fails(self):
285
t = memory.MemoryTransport()
286
self.assertRaises(errors.NoSuchFile,
287
t.append_bytes, 'dir/path', 'content')
316
transport = memory.MemoryTransport()
317
self.assertRaises(NoSuchFile,
318
transport.append_bytes, 'dir/path', 'content')
289
320
def test_put_without_dir_fails(self):
290
t = memory.MemoryTransport()
291
self.assertRaises(errors.NoSuchFile,
292
t.put_file, 'dir/path', StringIO('content'))
321
transport = memory.MemoryTransport()
322
self.assertRaises(NoSuchFile,
323
transport.put_file, 'dir/path', StringIO('content'))
294
325
def test_get_missing(self):
295
326
transport = memory.MemoryTransport()
296
self.assertRaises(errors.NoSuchFile, transport.get, 'foo')
327
self.assertRaises(NoSuchFile, transport.get, 'foo')
298
329
def test_has_missing(self):
299
t = memory.MemoryTransport()
300
self.assertEquals(False, t.has('foo'))
330
transport = memory.MemoryTransport()
331
self.assertEquals(False, transport.has('foo'))
302
333
def test_has_present(self):
303
t = memory.MemoryTransport()
304
t.append_bytes('foo', 'content')
305
self.assertEquals(True, t.has('foo'))
334
transport = memory.MemoryTransport()
335
transport.append_bytes('foo', 'content')
336
self.assertEquals(True, transport.has('foo'))
307
338
def test_list_dir(self):
308
t = memory.MemoryTransport()
309
t.put_bytes('foo', 'content')
311
t.put_bytes('dir/subfoo', 'content')
312
t.put_bytes('dirlike', 'content')
339
transport = memory.MemoryTransport()
340
transport.put_bytes('foo', 'content')
341
transport.mkdir('dir')
342
transport.put_bytes('dir/subfoo', 'content')
343
transport.put_bytes('dirlike', 'content')
314
self.assertEquals(['dir', 'dirlike', 'foo'], sorted(t.list_dir('.')))
315
self.assertEquals(['subfoo'], sorted(t.list_dir('dir')))
345
self.assertEquals(['dir', 'dirlike', 'foo'], sorted(transport.list_dir('.')))
346
self.assertEquals(['subfoo'], sorted(transport.list_dir('dir')))
317
348
def test_mkdir(self):
318
t = memory.MemoryTransport()
320
t.append_bytes('dir/path', 'content')
321
self.assertEqual(t.get('dir/path').read(), 'content')
349
transport = memory.MemoryTransport()
350
transport.mkdir('dir')
351
transport.append_bytes('dir/path', 'content')
352
self.assertEqual(transport.get('dir/path').read(), 'content')
323
354
def test_mkdir_missing_parent(self):
324
t = memory.MemoryTransport()
325
self.assertRaises(errors.NoSuchFile, t.mkdir, 'dir/dir')
355
transport = memory.MemoryTransport()
356
self.assertRaises(NoSuchFile,
357
transport.mkdir, 'dir/dir')
327
359
def test_mkdir_twice(self):
328
t = memory.MemoryTransport()
330
self.assertRaises(errors.FileExists, t.mkdir, 'dir')
360
transport = memory.MemoryTransport()
361
transport.mkdir('dir')
362
self.assertRaises(FileExists, transport.mkdir, 'dir')
332
364
def test_parameters(self):
333
t = memory.MemoryTransport()
334
self.assertEqual(True, t.listable())
335
self.assertEqual(False, t.is_readonly())
365
transport = memory.MemoryTransport()
366
self.assertEqual(True, transport.listable())
367
self.assertEqual(False, transport.is_readonly())
337
369
def test_iter_files_recursive(self):
338
t = memory.MemoryTransport()
340
t.put_bytes('dir/foo', 'content')
341
t.put_bytes('dir/bar', 'content')
342
t.put_bytes('bar', 'content')
343
paths = set(t.iter_files_recursive())
370
transport = memory.MemoryTransport()
371
transport.mkdir('dir')
372
transport.put_bytes('dir/foo', 'content')
373
transport.put_bytes('dir/bar', 'content')
374
transport.put_bytes('bar', 'content')
375
paths = set(transport.iter_files_recursive())
344
376
self.assertEqual(set(['dir/foo', 'dir/bar', 'bar']), paths)
346
378
def test_stat(self):
347
t = memory.MemoryTransport()
348
t.put_bytes('foo', 'content')
349
t.put_bytes('bar', 'phowar')
350
self.assertEqual(7, t.stat('foo').st_size)
351
self.assertEqual(6, t.stat('bar').st_size)
354
class ChrootDecoratorTransportTest(tests.TestCase):
379
transport = memory.MemoryTransport()
380
transport.put_bytes('foo', 'content')
381
transport.put_bytes('bar', 'phowar')
382
self.assertEqual(7, transport.stat('foo').st_size)
383
self.assertEqual(6, transport.stat('bar').st_size)
386
class ChrootDecoratorTransportTest(TestCase):
355
387
"""Chroot decoration specific tests."""
357
389
def test_abspath(self):
358
390
# The abspath is always relative to the chroot_url.
359
server = chroot.ChrootServer(
360
transport.get_transport_from_url('memory:///foo/bar/'))
391
server = ChrootServer(get_transport('memory:///foo/bar/'))
361
392
self.start_server(server)
362
t = transport.get_transport_from_url(server.get_url())
363
self.assertEqual(server.get_url(), t.abspath('/'))
393
transport = get_transport(server.get_url())
394
self.assertEqual(server.get_url(), transport.abspath('/'))
365
subdir_t = t.clone('subdir')
366
self.assertEqual(server.get_url(), subdir_t.abspath('/'))
396
subdir_transport = transport.clone('subdir')
397
self.assertEqual(server.get_url(), subdir_transport.abspath('/'))
368
399
def test_clone(self):
369
server = chroot.ChrootServer(
370
transport.get_transport_from_url('memory:///foo/bar/'))
400
server = ChrootServer(get_transport('memory:///foo/bar/'))
371
401
self.start_server(server)
372
t = transport.get_transport_from_url(server.get_url())
402
transport = get_transport(server.get_url())
373
403
# relpath from root and root path are the same
374
relpath_cloned = t.clone('foo')
375
abspath_cloned = t.clone('/foo')
404
relpath_cloned = transport.clone('foo')
405
abspath_cloned = transport.clone('/foo')
376
406
self.assertEqual(server, relpath_cloned.server)
377
407
self.assertEqual(server, abspath_cloned.server)
401
430
This is so that it is not possible to escape a chroot by doing::
402
431
url = chroot_transport.base
403
432
parent_url = urlutils.join(url, '..')
404
new_t = transport.get_transport_from_url(parent_url)
433
new_transport = get_transport(parent_url)
406
server = chroot.ChrootServer(
407
transport.get_transport_from_url('memory:///path/'))
435
server = ChrootServer(get_transport('memory:///path/'))
408
436
self.start_server(server)
409
t = transport.get_transport_from_url(server.get_url())
437
transport = get_transport(server.get_url())
410
438
self.assertRaises(
411
errors.InvalidURLJoin, urlutils.join, t.base, '..')
414
class TestChrootServer(tests.TestCase):
439
InvalidURLJoin, urlutils.join, transport.base, '..')
442
class ChrootServerTest(TestCase):
416
444
def test_construct(self):
417
445
backing_transport = memory.MemoryTransport()
418
server = chroot.ChrootServer(backing_transport)
446
server = ChrootServer(backing_transport)
419
447
self.assertEqual(backing_transport, server.backing_transport)
421
449
def test_setUp(self):
422
450
backing_transport = memory.MemoryTransport()
423
server = chroot.ChrootServer(backing_transport)
451
server = ChrootServer(backing_transport)
424
452
server.start_server()
425
self.addCleanup(server.stop_server)
426
self.assertTrue(server.scheme
427
in transport._get_protocol_handlers().keys())
454
self.assertTrue(server.scheme in _get_protocol_handlers().keys())
429
458
def test_stop_server(self):
430
459
backing_transport = memory.MemoryTransport()
431
server = chroot.ChrootServer(backing_transport)
460
server = ChrootServer(backing_transport)
432
461
server.start_server()
433
462
server.stop_server()
434
self.assertFalse(server.scheme
435
in transport._get_protocol_handlers().keys())
463
self.assertFalse(server.scheme in _get_protocol_handlers().keys())
437
465
def test_get_url(self):
438
466
backing_transport = memory.MemoryTransport()
439
server = chroot.ChrootServer(backing_transport)
467
server = ChrootServer(backing_transport)
440
468
server.start_server()
441
self.addCleanup(server.stop_server)
442
self.assertEqual('chroot-%d:///' % id(server), server.get_url())
445
class PathFilteringDecoratorTransportTest(tests.TestCase):
470
self.assertEqual('chroot-%d:///' % id(server), server.get_url())
475
class PathFilteringDecoratorTransportTest(TestCase):
446
476
"""Pathfilter decoration specific tests."""
448
478
def test_abspath(self):
449
479
# The abspath is always relative to the base of the backing transport.
450
server = pathfilter.PathFilteringServer(
451
transport.get_transport_from_url('memory:///foo/bar/'),
480
server = PathFilteringServer(get_transport('memory:///foo/bar/'),
453
482
server.start_server()
454
t = transport.get_transport_from_url(server.get_url())
455
self.assertEqual(server.get_url(), t.abspath('/'))
483
transport = get_transport(server.get_url())
484
self.assertEqual(server.get_url(), transport.abspath('/'))
457
subdir_t = t.clone('subdir')
458
self.assertEqual(server.get_url(), subdir_t.abspath('/'))
486
subdir_transport = transport.clone('subdir')
487
self.assertEqual(server.get_url(), subdir_transport.abspath('/'))
459
488
server.stop_server()
461
490
def make_pf_transport(self, filter_func=None):
462
491
"""Make a PathFilteringTransport backed by a MemoryTransport.
464
493
:param filter_func: by default this will be a no-op function. Use this
465
494
parameter to override it."""
466
495
if filter_func is None:
467
496
filter_func = lambda x: x
468
server = pathfilter.PathFilteringServer(
469
transport.get_transport_from_url('memory:///foo/bar/'), filter_func)
497
server = PathFilteringServer(
498
get_transport('memory:///foo/bar/'), filter_func)
470
499
server.start_server()
471
500
self.addCleanup(server.stop_server)
472
return transport.get_transport_from_url(server.get_url())
501
return get_transport(server.get_url())
474
503
def test__filter(self):
475
504
# _filter (with an identity func as filter_func) always returns
476
505
# paths relative to the base of the backing transport.
477
t = self.make_pf_transport()
478
self.assertEqual('foo', t._filter('foo'))
479
self.assertEqual('foo/bar', t._filter('foo/bar'))
480
self.assertEqual('', t._filter('..'))
481
self.assertEqual('', t._filter('/'))
506
transport = self.make_pf_transport()
507
self.assertEqual('foo', transport._filter('foo'))
508
self.assertEqual('foo/bar', transport._filter('foo/bar'))
509
self.assertEqual('', transport._filter('..'))
510
self.assertEqual('', transport._filter('/'))
482
511
# The base of the pathfiltering transport is taken into account too.
483
t = t.clone('subdir1/subdir2')
484
self.assertEqual('subdir1/subdir2/foo', t._filter('foo'))
485
self.assertEqual('subdir1/subdir2/foo/bar', t._filter('foo/bar'))
486
self.assertEqual('subdir1', t._filter('..'))
487
self.assertEqual('', t._filter('/'))
512
transport = transport.clone('subdir1/subdir2')
513
self.assertEqual('subdir1/subdir2/foo', transport._filter('foo'))
515
'subdir1/subdir2/foo/bar', transport._filter('foo/bar'))
516
self.assertEqual('subdir1', transport._filter('..'))
517
self.assertEqual('', transport._filter('/'))
489
519
def test_filter_invocation(self):
492
521
def filter(path):
493
522
filter_log.append(path)
495
t = self.make_pf_transport(filter)
524
transport = self.make_pf_transport(filter)
497
526
self.assertEqual(['abc'], filter_log)
498
527
del filter_log[:]
499
t.clone('abc').has('xyz')
528
transport.clone('abc').has('xyz')
500
529
self.assertEqual(['abc/xyz'], filter_log)
501
530
del filter_log[:]
531
transport.has('/abc')
503
532
self.assertEqual(['abc'], filter_log)
505
534
def test_clone(self):
506
t = self.make_pf_transport()
535
transport = self.make_pf_transport()
507
536
# relpath from root and root path are the same
508
relpath_cloned = t.clone('foo')
509
abspath_cloned = t.clone('/foo')
510
self.assertEqual(t.server, relpath_cloned.server)
511
self.assertEqual(t.server, abspath_cloned.server)
537
relpath_cloned = transport.clone('foo')
538
abspath_cloned = transport.clone('/foo')
539
self.assertEqual(transport.server, relpath_cloned.server)
540
self.assertEqual(transport.server, abspath_cloned.server)
513
542
def test_url_preserves_pathfiltering(self):
514
543
"""Calling get_transport on a pathfiltered transport's base should
677
class TestTransportFromPath(tests.TestCaseInTempDir):
679
def test_with_path(self):
680
t = transport.get_transport_from_path(self.test_dir)
681
self.assertIsInstance(t, local.LocalTransport)
682
self.assertEquals(t.base.rstrip("/"),
683
urlutils.local_path_to_url(self.test_dir))
685
def test_with_url(self):
686
t = transport.get_transport_from_path("file:")
687
self.assertIsInstance(t, local.LocalTransport)
688
self.assertEquals(t.base.rstrip("/"),
689
urlutils.local_path_to_url(os.path.join(self.test_dir, "file:")))
692
class TestTransportFromUrl(tests.TestCaseInTempDir):
694
def test_with_path(self):
695
self.assertRaises(errors.InvalidURL, transport.get_transport_from_url,
698
def test_with_url(self):
699
url = urlutils.local_path_to_url(self.test_dir)
700
t = transport.get_transport_from_url(url)
701
self.assertIsInstance(t, local.LocalTransport)
702
self.assertEquals(t.base.rstrip("/"), url)
704
def test_with_url_and_segment_parameters(self):
705
url = urlutils.local_path_to_url(self.test_dir)+",branch=foo"
706
t = transport.get_transport_from_url(url)
707
self.assertIsInstance(t, local.LocalTransport)
708
self.assertEquals(t.base.rstrip("/"), url)
709
with open(os.path.join(self.test_dir, "afile"), 'w') as f:
711
self.assertTrue(t.has("afile"))
714
class TestLocalTransports(tests.TestCase):
708
class TestLocalTransports(TestCase):
716
710
def test_get_transport_from_abspath(self):
717
711
here = osutils.abspath('.')
718
t = transport.get_transport(here)
719
self.assertIsInstance(t, local.LocalTransport)
712
t = get_transport(here)
713
self.assertIsInstance(t, LocalTransport)
720
714
self.assertEquals(t.base, urlutils.local_path_to_url(here) + '/')
722
716
def test_get_transport_from_relpath(self):
723
717
here = osutils.abspath('.')
724
t = transport.get_transport('.')
725
self.assertIsInstance(t, local.LocalTransport)
718
t = get_transport('.')
719
self.assertIsInstance(t, LocalTransport)
726
720
self.assertEquals(t.base, urlutils.local_path_to_url('.') + '/')
728
722
def test_get_transport_from_local_url(self):
729
723
here = osutils.abspath('.')
730
724
here_url = urlutils.local_path_to_url(here) + '/'
731
t = transport.get_transport(here_url)
732
self.assertIsInstance(t, local.LocalTransport)
725
t = get_transport(here_url)
726
self.assertIsInstance(t, LocalTransport)
733
727
self.assertEquals(t.base, here_url)
735
729
def test_local_abspath(self):
736
730
here = osutils.abspath('.')
737
t = transport.get_transport(here)
731
t = get_transport(here)
738
732
self.assertEquals(t.local_abspath(''), here)
741
class TestLocalTransportWriteStream(tests.TestCaseWithTransport):
743
def test_local_fdatasync_calls_fdatasync(self):
744
"""Check fdatasync on a stream tries to flush the data to the OS.
746
We can't easily observe the external effect but we can at least see
750
fdatasync = getattr(os, 'fdatasync', sentinel)
751
if fdatasync is sentinel:
752
raise tests.TestNotApplicable('fdatasync not supported')
753
t = self.get_transport('.')
754
calls = self.recordCalls(os, 'fdatasync')
755
w = t.open_write_stream('out')
758
with open('out', 'rb') as f:
759
# Should have been flushed.
760
self.assertEquals(f.read(), 'foo')
761
self.assertEquals(len(calls), 1, calls)
764
class TestWin32LocalTransport(tests.TestCase):
735
class TestWin32LocalTransport(TestCase):
766
737
def test_unc_clone_to_root(self):
767
738
# Win32 UNC path like \\HOST\path
768
739
# clone to root should stop at least at \\HOST part
770
t = local.EmulatedWin32LocalTransport('file://HOST/path/to/some/dir/')
741
t = EmulatedWin32LocalTransport('file://HOST/path/to/some/dir/')
771
742
for i in xrange(4):
772
743
t = t.clone('..')
773
744
self.assertEquals(t.base, 'file://HOST/')
776
747
self.assertEquals(t.base, 'file://HOST/')
779
class TestConnectedTransport(tests.TestCase):
750
class TestConnectedTransport(TestCase):
780
751
"""Tests for connected to remote server transports"""
782
753
def test_parse_url(self):
783
t = transport.ConnectedTransport(
784
'http://simple.example.com/home/source')
785
self.assertEquals(t._parsed_url.host, 'simple.example.com')
786
self.assertEquals(t._parsed_url.port, None)
787
self.assertEquals(t._parsed_url.path, '/home/source/')
788
self.assertTrue(t._parsed_url.user is None)
789
self.assertTrue(t._parsed_url.password is None)
754
t = ConnectedTransport('http://simple.example.com/home/source')
755
self.assertEquals(t._host, 'simple.example.com')
756
self.assertEquals(t._port, None)
757
self.assertEquals(t._path, '/home/source/')
758
self.failUnless(t._user is None)
759
self.failUnless(t._password is None)
791
761
self.assertEquals(t.base, 'http://simple.example.com/home/source/')
793
763
def test_parse_url_with_at_in_user(self):
795
t = transport.ConnectedTransport('ftp://user@host.com@www.host.com/')
796
self.assertEquals(t._parsed_url.user, 'user@host.com')
765
t = ConnectedTransport('ftp://user@host.com@www.host.com/')
766
self.assertEquals(t._user, 'user@host.com')
798
768
def test_parse_quoted_url(self):
799
t = transport.ConnectedTransport(
800
'http://ro%62ey:h%40t@ex%41mple.com:2222/path')
801
self.assertEquals(t._parsed_url.host, 'exAmple.com')
802
self.assertEquals(t._parsed_url.port, 2222)
803
self.assertEquals(t._parsed_url.user, 'robey')
804
self.assertEquals(t._parsed_url.password, 'h@t')
805
self.assertEquals(t._parsed_url.path, '/path/')
769
t = ConnectedTransport('http://ro%62ey:h%40t@ex%41mple.com:2222/path')
770
self.assertEquals(t._host, 'exAmple.com')
771
self.assertEquals(t._port, 2222)
772
self.assertEquals(t._user, 'robey')
773
self.assertEquals(t._password, 'h@t')
774
self.assertEquals(t._path, '/path/')
807
776
# Base should not keep track of the password
808
self.assertEquals(t.base, 'http://ro%62ey@ex%41mple.com:2222/path/')
777
self.assertEquals(t.base, 'http://robey@exAmple.com:2222/path/')
810
779
def test_parse_invalid_url(self):
811
780
self.assertRaises(errors.InvalidURL,
812
transport.ConnectedTransport,
813
782
'sftp://lily.org:~janneke/public/bzr/gub')
815
784
def test_relpath(self):
816
t = transport.ConnectedTransport('sftp://user@host.com/abs/path')
785
t = ConnectedTransport('sftp://user@host.com/abs/path')
818
self.assertEquals(t.relpath('sftp://user@host.com/abs/path/sub'),
787
self.assertEquals(t.relpath('sftp://user@host.com/abs/path/sub'), 'sub')
820
788
self.assertRaises(errors.PathNotChild, t.relpath,
821
789
'http://user@host.com/abs/path/sub')
822
790
self.assertRaises(errors.PathNotChild, t.relpath,
861
829
self.assertIs(new_password, c._get_credentials())
864
class TestReusedTransports(tests.TestCase):
832
class TestReusedTransports(TestCase):
865
833
"""Tests for transport reuse"""
867
835
def test_reuse_same_transport(self):
868
836
possible_transports = []
869
t1 = transport.get_transport_from_url('http://foo/',
870
possible_transports=possible_transports)
837
t1 = get_transport('http://foo/',
838
possible_transports=possible_transports)
871
839
self.assertEqual([t1], possible_transports)
872
t2 = transport.get_transport_from_url('http://foo/',
873
possible_transports=[t1])
840
t2 = get_transport('http://foo/', possible_transports=[t1])
874
841
self.assertIs(t1, t2)
876
843
# Also check that final '/' are handled correctly
877
t3 = transport.get_transport_from_url('http://foo/path/')
878
t4 = transport.get_transport_from_url('http://foo/path',
879
possible_transports=[t3])
844
t3 = get_transport('http://foo/path/')
845
t4 = get_transport('http://foo/path', possible_transports=[t3])
880
846
self.assertIs(t3, t4)
882
t5 = transport.get_transport_from_url('http://foo/path')
883
t6 = transport.get_transport_from_url('http://foo/path/',
884
possible_transports=[t5])
848
t5 = get_transport('http://foo/path')
849
t6 = get_transport('http://foo/path/', possible_transports=[t5])
885
850
self.assertIs(t5, t6)
887
852
def test_don_t_reuse_different_transport(self):
888
t1 = transport.get_transport_from_url('http://foo/path')
889
t2 = transport.get_transport_from_url('http://bar/path',
890
possible_transports=[t1])
853
t1 = get_transport('http://foo/path')
854
t2 = get_transport('http://bar/path', possible_transports=[t1])
891
855
self.assertIsNot(t1, t2)
894
class TestTransportTrace(tests.TestCase):
858
class TestTransportTrace(TestCase):
896
def test_decorator(self):
897
t = transport.get_transport_from_url('trace+memory://')
861
transport = get_transport('trace+memory://')
898
862
self.assertIsInstance(
899
t, bzrlib.transport.trace.TransportTraceDecorator)
863
transport, bzrlib.transport.trace.TransportTraceDecorator)
901
865
def test_clone_preserves_activity(self):
902
t = transport.get_transport_from_url('trace+memory://')
904
self.assertTrue(t is not t2)
905
self.assertTrue(t._activity is t2._activity)
866
transport = get_transport('trace+memory://')
867
transport2 = transport.clone('.')
868
self.assertTrue(transport is not transport2)
869
self.assertTrue(transport._activity is transport2._activity)
907
871
# the following specific tests are for the operations that have made use of
908
872
# logging in tests; we could test every single operation but doing that
909
873
# still won't cause a test failure when the top level Transport API
910
874
# changes; so there is little return doing that.
911
875
def test_get(self):
912
t = transport.get_transport_from_url('trace+memory:///')
913
t.put_bytes('foo', 'barish')
876
transport = get_transport('trace+memory:///')
877
transport.put_bytes('foo', 'barish')
915
879
expected_result = []
916
880
# put_bytes records the bytes, not the content to avoid memory
918
882
expected_result.append(('put_bytes', 'foo', 6, None))
919
883
# get records the file name only.
920
884
expected_result.append(('get', 'foo'))
921
self.assertEqual(expected_result, t._activity)
885
self.assertEqual(expected_result, transport._activity)
923
887
def test_readv(self):
924
t = transport.get_transport_from_url('trace+memory:///')
925
t.put_bytes('foo', 'barish')
926
list(t.readv('foo', [(0, 1), (3, 2)],
927
adjust_for_latency=True, upper_limit=6))
888
transport = get_transport('trace+memory:///')
889
transport.put_bytes('foo', 'barish')
890
list(transport.readv('foo', [(0, 1), (3, 2)], adjust_for_latency=True,
928
892
expected_result = []
929
893
# put_bytes records the bytes, not the content to avoid memory
931
895
expected_result.append(('put_bytes', 'foo', 6, None))
932
896
# readv records the supplied offset request
933
897
expected_result.append(('readv', 'foo', [(0, 1), (3, 2)], True, 6))
934
self.assertEqual(expected_result, t._activity)
898
self.assertEqual(expected_result, transport._activity)
937
901
class TestSSHConnections(tests.TestCaseWithTransport):
939
903
def test_bzr_connect_to_bzr_ssh(self):
940
"""get_transport of a bzr+ssh:// behaves correctly.
904
"""User acceptance that get_transport of a bzr+ssh:// behaves correctly.
942
906
bzr+ssh:// should cause bzr to run a remote bzr smart server over SSH.