/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_transport.py

Merge from bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2004, 2005, 2006 Canonical Ltd
 
2
#
 
3
# This program is free software; you can redistribute it and/or modify
 
4
# it under the terms of the GNU General Public License as published by
 
5
# the Free Software Foundation; either version 2 of the License, or
 
6
# (at your option) any later version.
 
7
#
 
8
# This program is distributed in the hope that it will be useful,
 
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
# GNU General Public License for more details.
 
12
#
 
13
# You should have received a copy of the GNU General Public License
 
14
# along with this program; if not, write to the Free Software
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
 
 
18
import os
 
19
import sys
 
20
import stat
 
21
from cStringIO import StringIO
 
22
 
 
23
import bzrlib
 
24
from bzrlib import urlutils
 
25
from bzrlib.errors import (
 
26
    ConnectionError,
 
27
    DependencyNotPresent,
 
28
    FileExists,
 
29
    NoSuchFile,
 
30
    PathNotChild,
 
31
    TransportNotPossible,
 
32
    UnsupportedProtocol,
 
33
    )
 
34
from bzrlib.tests import TestCase, TestCaseInTempDir
 
35
from bzrlib.transport import (_CoalescedOffset,
 
36
                              _get_protocol_handlers,
 
37
                              _get_transport_modules,
 
38
                              get_transport,
 
39
                              register_lazy_transport,
 
40
                              _set_protocol_handlers,
 
41
                              Transport,
 
42
                              )
 
43
from bzrlib.transport.memory import MemoryTransport
 
44
from bzrlib.transport.local import LocalTransport
 
45
 
 
46
 
 
47
# TODO: Should possibly split transport-specific tests into their own files.
 
48
 
 
49
 
 
50
class TestTransport(TestCase):
 
51
    """Test the non transport-concrete class functionality."""
 
52
 
 
53
    def test__get_set_protocol_handlers(self):
 
54
        handlers = _get_protocol_handlers()
 
55
        self.assertNotEqual({}, handlers)
 
56
        try:
 
57
            _set_protocol_handlers({})
 
58
            self.assertEqual({}, _get_protocol_handlers())
 
59
        finally:
 
60
            _set_protocol_handlers(handlers)
 
61
 
 
62
    def test_get_transport_modules(self):
 
63
        handlers = _get_protocol_handlers()
 
64
        class SampleHandler(object):
 
65
            """I exist, isnt that enough?"""
 
66
        try:
 
67
            my_handlers = {}
 
68
            _set_protocol_handlers(my_handlers)
 
69
            register_lazy_transport('foo', 'bzrlib.tests.test_transport', 'TestTransport.SampleHandler')
 
70
            register_lazy_transport('bar', 'bzrlib.tests.test_transport', 'TestTransport.SampleHandler')
 
71
            self.assertEqual([SampleHandler.__module__],
 
72
                             _get_transport_modules())
 
73
        finally:
 
74
            _set_protocol_handlers(handlers)
 
75
 
 
76
    def test_transport_dependency(self):
 
77
        """Transport with missing dependency causes no error"""
 
78
        saved_handlers = _get_protocol_handlers()
 
79
        try:
 
80
            register_lazy_transport('foo', 'bzrlib.tests.test_transport',
 
81
                    'BadTransportHandler')
 
82
            try:
 
83
                get_transport('foo://fooserver/foo')
 
84
            except UnsupportedProtocol, e:
 
85
                e_str = str(e)
 
86
                self.assertEquals('Unsupported protocol'
 
87
                                  ' for url "foo://fooserver/foo":'
 
88
                                  ' Unable to import library "some_lib":'
 
89
                                  ' testing missing dependency', str(e))
 
90
            else:
 
91
                self.fail('Did not raise UnsupportedProtocol')
 
92
        finally:
 
93
            # restore original values
 
94
            _set_protocol_handlers(saved_handlers)
 
95
            
 
96
    def test_transport_fallback(self):
 
97
        """Transport with missing dependency causes no error"""
 
98
        saved_handlers = _get_protocol_handlers()
 
99
        try:
 
100
            _set_protocol_handlers({})
 
101
            register_lazy_transport('foo', 'bzrlib.tests.test_transport',
 
102
                    'BackupTransportHandler')
 
103
            register_lazy_transport('foo', 'bzrlib.tests.test_transport',
 
104
                    'BadTransportHandler')
 
105
            t = get_transport('foo://fooserver/foo')
 
106
            self.assertTrue(isinstance(t, BackupTransportHandler))
 
107
        finally:
 
108
            _set_protocol_handlers(saved_handlers)
 
109
 
 
110
    def test__combine_paths(self):
 
111
        t = Transport('/')
 
112
        self.assertEqual('/home/sarah/project/foo',
 
113
                         t._combine_paths('/home/sarah', 'project/foo'))
 
114
        self.assertEqual('/etc',
 
115
                         t._combine_paths('/home/sarah', '../../etc'))
 
116
        self.assertEqual('/etc',
 
117
                         t._combine_paths('/home/sarah', '../../../etc'))
 
118
        self.assertEqual('/etc',
 
119
                         t._combine_paths('/home/sarah', '/etc'))
 
120
 
 
121
 
 
122
class TestCoalesceOffsets(TestCase):
 
123
    
 
124
    def check(self, expected, offsets, limit=0, fudge=0):
 
125
        coalesce = Transport._coalesce_offsets
 
126
        exp = [_CoalescedOffset(*x) for x in expected]
 
127
        out = list(coalesce(offsets, limit=limit, fudge_factor=fudge))
 
128
        self.assertEqual(exp, out)
 
129
 
 
130
    def test_coalesce_empty(self):
 
131
        self.check([], [])
 
132
 
 
133
    def test_coalesce_simple(self):
 
134
        self.check([(0, 10, [(0, 10)])], [(0, 10)])
 
135
 
 
136
    def test_coalesce_unrelated(self):
 
137
        self.check([(0, 10, [(0, 10)]),
 
138
                    (20, 10, [(0, 10)]),
 
139
                   ], [(0, 10), (20, 10)])
 
140
            
 
141
    def test_coalesce_unsorted(self):
 
142
        self.check([(20, 10, [(0, 10)]),
 
143
                    (0, 10, [(0, 10)]),
 
144
                   ], [(20, 10), (0, 10)])
 
145
 
 
146
    def test_coalesce_nearby(self):
 
147
        self.check([(0, 20, [(0, 10), (10, 10)])],
 
148
                   [(0, 10), (10, 10)])
 
149
 
 
150
    def test_coalesce_overlapped(self):
 
151
        self.check([(0, 15, [(0, 10), (5, 10)])],
 
152
                   [(0, 10), (5, 10)])
 
153
 
 
154
    def test_coalesce_limit(self):
 
155
        self.check([(10, 50, [(0, 10), (10, 10), (20, 10),
 
156
                              (30, 10), (40, 10)]),
 
157
                    (60, 50, [(0, 10), (10, 10), (20, 10),
 
158
                              (30, 10), (40, 10)]),
 
159
                   ], [(10, 10), (20, 10), (30, 10), (40, 10),
 
160
                       (50, 10), (60, 10), (70, 10), (80, 10),
 
161
                       (90, 10), (100, 10)],
 
162
                    limit=5)
 
163
 
 
164
    def test_coalesce_no_limit(self):
 
165
        self.check([(10, 100, [(0, 10), (10, 10), (20, 10),
 
166
                               (30, 10), (40, 10), (50, 10),
 
167
                               (60, 10), (70, 10), (80, 10),
 
168
                               (90, 10)]),
 
169
                   ], [(10, 10), (20, 10), (30, 10), (40, 10),
 
170
                       (50, 10), (60, 10), (70, 10), (80, 10),
 
171
                       (90, 10), (100, 10)])
 
172
 
 
173
    def test_coalesce_fudge(self):
 
174
        self.check([(10, 30, [(0, 10), (20, 10)]),
 
175
                    (100, 10, [(0, 10),]),
 
176
                   ], [(10, 10), (30, 10), (100, 10)],
 
177
                   fudge=10
 
178
                  )
 
179
 
 
180
 
 
181
class TestMemoryTransport(TestCase):
 
182
 
 
183
    def test_get_transport(self):
 
184
        MemoryTransport()
 
185
 
 
186
    def test_clone(self):
 
187
        transport = MemoryTransport()
 
188
        self.assertTrue(isinstance(transport, MemoryTransport))
 
189
        self.assertEqual("memory:///", transport.clone("/").base)
 
190
 
 
191
    def test_abspath(self):
 
192
        transport = MemoryTransport()
 
193
        self.assertEqual("memory:///relpath", transport.abspath('relpath'))
 
194
 
 
195
    def test_abspath_of_root(self):
 
196
        transport = MemoryTransport()
 
197
        self.assertEqual("memory:///", transport.base)
 
198
        self.assertEqual("memory:///", transport.abspath('/'))
 
199
 
 
200
    def test_abspath_of_relpath_starting_at_root(self):
 
201
        transport = MemoryTransport()
 
202
        self.assertEqual("memory:///foo", transport.abspath('/foo'))
 
203
 
 
204
    def test_append_and_get(self):
 
205
        transport = MemoryTransport()
 
206
        transport.append_bytes('path', 'content')
 
207
        self.assertEqual(transport.get('path').read(), 'content')
 
208
        transport.append_file('path', StringIO('content'))
 
209
        self.assertEqual(transport.get('path').read(), 'contentcontent')
 
210
 
 
211
    def test_put_and_get(self):
 
212
        transport = MemoryTransport()
 
213
        transport.put_file('path', StringIO('content'))
 
214
        self.assertEqual(transport.get('path').read(), 'content')
 
215
        transport.put_bytes('path', 'content')
 
216
        self.assertEqual(transport.get('path').read(), 'content')
 
217
 
 
218
    def test_append_without_dir_fails(self):
 
219
        transport = MemoryTransport()
 
220
        self.assertRaises(NoSuchFile,
 
221
                          transport.append_bytes, 'dir/path', 'content')
 
222
 
 
223
    def test_put_without_dir_fails(self):
 
224
        transport = MemoryTransport()
 
225
        self.assertRaises(NoSuchFile,
 
226
                          transport.put_file, 'dir/path', StringIO('content'))
 
227
 
 
228
    def test_get_missing(self):
 
229
        transport = MemoryTransport()
 
230
        self.assertRaises(NoSuchFile, transport.get, 'foo')
 
231
 
 
232
    def test_has_missing(self):
 
233
        transport = MemoryTransport()
 
234
        self.assertEquals(False, transport.has('foo'))
 
235
 
 
236
    def test_has_present(self):
 
237
        transport = MemoryTransport()
 
238
        transport.append_bytes('foo', 'content')
 
239
        self.assertEquals(True, transport.has('foo'))
 
240
 
 
241
    def test_list_dir(self):
 
242
        transport = MemoryTransport()
 
243
        transport.put_bytes('foo', 'content')
 
244
        transport.mkdir('dir')
 
245
        transport.put_bytes('dir/subfoo', 'content')
 
246
        transport.put_bytes('dirlike', 'content')
 
247
 
 
248
        self.assertEquals(['dir', 'dirlike', 'foo'], sorted(transport.list_dir('.')))
 
249
        self.assertEquals(['subfoo'], sorted(transport.list_dir('dir')))
 
250
 
 
251
    def test_mkdir(self):
 
252
        transport = MemoryTransport()
 
253
        transport.mkdir('dir')
 
254
        transport.append_bytes('dir/path', 'content')
 
255
        self.assertEqual(transport.get('dir/path').read(), 'content')
 
256
 
 
257
    def test_mkdir_missing_parent(self):
 
258
        transport = MemoryTransport()
 
259
        self.assertRaises(NoSuchFile,
 
260
                          transport.mkdir, 'dir/dir')
 
261
 
 
262
    def test_mkdir_twice(self):
 
263
        transport = MemoryTransport()
 
264
        transport.mkdir('dir')
 
265
        self.assertRaises(FileExists, transport.mkdir, 'dir')
 
266
 
 
267
    def test_parameters(self):
 
268
        transport = MemoryTransport()
 
269
        self.assertEqual(True, transport.listable())
 
270
        self.assertEqual(False, transport.should_cache())
 
271
        self.assertEqual(False, transport.is_readonly())
 
272
 
 
273
    def test_iter_files_recursive(self):
 
274
        transport = MemoryTransport()
 
275
        transport.mkdir('dir')
 
276
        transport.put_bytes('dir/foo', 'content')
 
277
        transport.put_bytes('dir/bar', 'content')
 
278
        transport.put_bytes('bar', 'content')
 
279
        paths = set(transport.iter_files_recursive())
 
280
        self.assertEqual(set(['dir/foo', 'dir/bar', 'bar']), paths)
 
281
 
 
282
    def test_stat(self):
 
283
        transport = MemoryTransport()
 
284
        transport.put_bytes('foo', 'content')
 
285
        transport.put_bytes('bar', 'phowar')
 
286
        self.assertEqual(7, transport.stat('foo').st_size)
 
287
        self.assertEqual(6, transport.stat('bar').st_size)
 
288
 
 
289
 
 
290
class ChrootDecoratorTransportTest(TestCase):
 
291
    """Chroot decoration specific tests."""
 
292
 
 
293
    def test_construct(self):
 
294
        from bzrlib.transport import chroot
 
295
        transport = chroot.ChrootTransportDecorator('chroot+memory:///pathA/')
 
296
        self.assertEqual('memory:///pathA/', transport.chroot_url)
 
297
        self.assertEqual('/', transport.chroot_relative)
 
298
        transport = chroot.ChrootTransportDecorator('chroot+memory:///pathA')
 
299
        self.assertEqual('memory:///pathA/', transport.chroot_url)
 
300
        self.assertEqual('/', transport.chroot_relative)
 
301
        transport = chroot.ChrootTransportDecorator(
 
302
            'chroot+memory:///path/B', chroot='memory:///path/')
 
303
        self.assertEqual('memory:///path/', transport.chroot_url)
 
304
        self.assertEqual('/B/', transport.chroot_relative)
 
305
 
 
306
    def test_append_file(self):
 
307
        transport = get_transport('chroot+memory:///foo/bar')
 
308
        self.assertRaises(PathNotChild, transport.append_file, '/foo', None)
 
309
 
 
310
    def test_append_bytes(self):
 
311
        transport = get_transport('chroot+memory:///foo/bar')
 
312
        self.assertRaises(PathNotChild, transport.append_bytes, '/foo', 'bytes')
 
313
 
 
314
    def test_clone(self):
 
315
        transport = get_transport('chroot+memory:///foo/bar')
 
316
        # relpath from root and root path are the same
 
317
        relpath_cloned = transport.clone('foo')
 
318
        abspath_cloned = transport.clone('/foo')
 
319
        self.assertEqual(relpath_cloned.base, abspath_cloned.base)
 
320
        self.assertEqual(relpath_cloned.chroot_url, abspath_cloned.chroot_url)
 
321
        self.assertEqual(relpath_cloned.chroot_relative,
 
322
            abspath_cloned.chroot_relative)
 
323
        transport = transport.clone('subdir')
 
324
        # clone preserves chroot_url and adjusts chroot_relative
 
325
        self.assertEqual('memory:///foo/bar/', transport.chroot_url)
 
326
        self.assertEqual('/subdir/', transport.chroot_relative)
 
327
        transport = transport.clone('/otherdir')
 
328
        # clone preserves chroot_url and adjusts chroot_relative
 
329
        self.assertEqual('memory:///foo/bar/', transport.chroot_url)
 
330
        self.assertEqual('/otherdir/', transport.chroot_relative)
 
331
 
 
332
    def test_delete(self):
 
333
        transport = get_transport('chroot+memory:///foo/bar')
 
334
        self.assertRaises(PathNotChild, transport.delete, '/foo')
 
335
 
 
336
    def test_delete_tree(self):
 
337
        transport = get_transport('chroot+memory:///foo/bar')
 
338
        self.assertRaises(PathNotChild, transport.delete_tree, '/foo')
 
339
 
 
340
    def test_get(self):
 
341
        transport = get_transport('chroot+memory:///foo/bar')
 
342
        self.assertRaises(PathNotChild, transport.get, '/foo')
 
343
 
 
344
    def test_get_bytes(self):
 
345
        transport = get_transport('chroot+memory:///foo/bar')
 
346
        self.assertRaises(PathNotChild, transport.get_bytes, '/foo')
 
347
 
 
348
    def test_has(self):
 
349
        transport = get_transport('chroot+memory:///foo/bar')
 
350
        self.assertRaises(PathNotChild, transport.has, '/foo')
 
351
 
 
352
    def test_list_dir(self):
 
353
        transport = get_transport('chroot+memory:///foo/bar')
 
354
        self.assertRaises(PathNotChild, transport.list_dir, '/foo')
 
355
 
 
356
    def test_lock_read(self):
 
357
        transport = get_transport('chroot+memory:///foo/bar')
 
358
        self.assertRaises(PathNotChild, transport.lock_read, '/foo')
 
359
 
 
360
    def test_lock_write(self):
 
361
        transport = get_transport('chroot+memory:///foo/bar')
 
362
        self.assertRaises(PathNotChild, transport.lock_write, '/foo')
 
363
 
 
364
    def test_mkdir(self):
 
365
        transport = get_transport('chroot+memory:///foo/bar')
 
366
        self.assertRaises(PathNotChild, transport.mkdir, '/foo')
 
367
 
 
368
    def test_put_bytes(self):
 
369
        transport = get_transport('chroot+memory:///foo/bar')
 
370
        self.assertRaises(PathNotChild, transport.put_bytes, '/foo', 'bytes')
 
371
 
 
372
    def test_put_file(self):
 
373
        transport = get_transport('chroot+memory:///foo/bar')
 
374
        self.assertRaises(PathNotChild, transport.put_file, '/foo', None)
 
375
 
 
376
    def test_rename(self):
 
377
        transport = get_transport('chroot+memory:///foo/bar')
 
378
        self.assertRaises(PathNotChild, transport.rename, '/aaa', 'bbb')
 
379
        self.assertRaises(PathNotChild, transport.rename, 'ccc', '/d')
 
380
 
 
381
    def test_rmdir(self):
 
382
        transport = get_transport('chroot+memory:///foo/bar')
 
383
        self.assertRaises(PathNotChild, transport.rmdir, '/foo')
 
384
 
 
385
    def test_stat(self):
 
386
        transport = get_transport('chroot+memory:///foo/bar')
 
387
        self.assertRaises(PathNotChild, transport.stat, '/foo')
 
388
 
 
389
 
 
390
class ReadonlyDecoratorTransportTest(TestCase):
 
391
    """Readonly decoration specific tests."""
 
392
 
 
393
    def test_local_parameters(self):
 
394
        import bzrlib.transport.readonly as readonly
 
395
        # connect to . in readonly mode
 
396
        transport = readonly.ReadonlyTransportDecorator('readonly+.')
 
397
        self.assertEqual(True, transport.listable())
 
398
        self.assertEqual(False, transport.should_cache())
 
399
        self.assertEqual(True, transport.is_readonly())
 
400
 
 
401
    def test_http_parameters(self):
 
402
        from bzrlib.tests.HttpServer import HttpServer
 
403
        import bzrlib.transport.readonly as readonly
 
404
        # connect to . via http which is not listable
 
405
        server = HttpServer()
 
406
        server.setUp()
 
407
        try:
 
408
            transport = get_transport('readonly+' + server.get_url())
 
409
            self.failUnless(isinstance(transport,
 
410
                                       readonly.ReadonlyTransportDecorator))
 
411
            self.assertEqual(False, transport.listable())
 
412
            self.assertEqual(True, transport.should_cache())
 
413
            self.assertEqual(True, transport.is_readonly())
 
414
        finally:
 
415
            server.tearDown()
 
416
 
 
417
 
 
418
class FakeNFSDecoratorTests(TestCaseInTempDir):
 
419
    """NFS decorator specific tests."""
 
420
 
 
421
    def get_nfs_transport(self, url):
 
422
        import bzrlib.transport.fakenfs as fakenfs
 
423
        # connect to url with nfs decoration
 
424
        return fakenfs.FakeNFSTransportDecorator('fakenfs+' + url)
 
425
 
 
426
    def test_local_parameters(self):
 
427
        # the listable, should_cache and is_readonly parameters
 
428
        # are not changed by the fakenfs decorator
 
429
        transport = self.get_nfs_transport('.')
 
430
        self.assertEqual(True, transport.listable())
 
431
        self.assertEqual(False, transport.should_cache())
 
432
        self.assertEqual(False, transport.is_readonly())
 
433
 
 
434
    def test_http_parameters(self):
 
435
        # the listable, should_cache and is_readonly parameters
 
436
        # are not changed by the fakenfs decorator
 
437
        from bzrlib.tests.HttpServer import HttpServer
 
438
        # connect to . via http which is not listable
 
439
        server = HttpServer()
 
440
        server.setUp()
 
441
        try:
 
442
            transport = self.get_nfs_transport(server.get_url())
 
443
            self.assertIsInstance(
 
444
                transport, bzrlib.transport.fakenfs.FakeNFSTransportDecorator)
 
445
            self.assertEqual(False, transport.listable())
 
446
            self.assertEqual(True, transport.should_cache())
 
447
            self.assertEqual(True, transport.is_readonly())
 
448
        finally:
 
449
            server.tearDown()
 
450
 
 
451
    def test_fakenfs_server_default(self):
 
452
        # a FakeNFSServer() should bring up a local relpath server for itself
 
453
        import bzrlib.transport.fakenfs as fakenfs
 
454
        server = fakenfs.FakeNFSServer()
 
455
        server.setUp()
 
456
        try:
 
457
            # the url should be decorated appropriately
 
458
            self.assertStartsWith(server.get_url(), 'fakenfs+')
 
459
            # and we should be able to get a transport for it
 
460
            transport = get_transport(server.get_url())
 
461
            # which must be a FakeNFSTransportDecorator instance.
 
462
            self.assertIsInstance(
 
463
                transport, fakenfs.FakeNFSTransportDecorator)
 
464
        finally:
 
465
            server.tearDown()
 
466
 
 
467
    def test_fakenfs_rename_semantics(self):
 
468
        # a FakeNFS transport must mangle the way rename errors occur to
 
469
        # look like NFS problems.
 
470
        transport = self.get_nfs_transport('.')
 
471
        self.build_tree(['from/', 'from/foo', 'to/', 'to/bar'],
 
472
                        transport=transport)
 
473
        self.assertRaises(bzrlib.errors.ResourceBusy,
 
474
                          transport.rename, 'from', 'to')
 
475
 
 
476
 
 
477
class FakeVFATDecoratorTests(TestCaseInTempDir):
 
478
    """Tests for simulation of VFAT restrictions"""
 
479
 
 
480
    def get_vfat_transport(self, url):
 
481
        """Return vfat-backed transport for test directory"""
 
482
        from bzrlib.transport.fakevfat import FakeVFATTransportDecorator
 
483
        return FakeVFATTransportDecorator('vfat+' + url)
 
484
 
 
485
    def test_transport_creation(self):
 
486
        from bzrlib.transport.fakevfat import FakeVFATTransportDecorator
 
487
        transport = self.get_vfat_transport('.')
 
488
        self.assertIsInstance(transport, FakeVFATTransportDecorator)
 
489
 
 
490
    def test_transport_mkdir(self):
 
491
        transport = self.get_vfat_transport('.')
 
492
        transport.mkdir('HELLO')
 
493
        self.assertTrue(transport.has('hello'))
 
494
        self.assertTrue(transport.has('Hello'))
 
495
 
 
496
    def test_forbidden_chars(self):
 
497
        transport = self.get_vfat_transport('.')
 
498
        self.assertRaises(ValueError, transport.has, "<NU>")
 
499
 
 
500
 
 
501
class BadTransportHandler(Transport):
 
502
    def __init__(self, base_url):
 
503
        raise DependencyNotPresent('some_lib', 'testing missing dependency')
 
504
 
 
505
 
 
506
class BackupTransportHandler(Transport):
 
507
    """Test transport that works as a backup for the BadTransportHandler"""
 
508
    pass
 
509
 
 
510
 
 
511
class TestTransportImplementation(TestCaseInTempDir):
 
512
    """Implementation verification for transports.
 
513
    
 
514
    To verify a transport we need a server factory, which is a callable
 
515
    that accepts no parameters and returns an implementation of
 
516
    bzrlib.transport.Server.
 
517
    
 
518
    That Server is then used to construct transport instances and test
 
519
    the transport via loopback activity.
 
520
 
 
521
    Currently this assumes that the Transport object is connected to the 
 
522
    current working directory.  So that whatever is done 
 
523
    through the transport, should show up in the working 
 
524
    directory, and vice-versa. This is a bug, because its possible to have
 
525
    URL schemes which provide access to something that may not be 
 
526
    result in storage on the local disk, i.e. due to file system limits, or 
 
527
    due to it being a database or some other non-filesystem tool.
 
528
 
 
529
    This also tests to make sure that the functions work with both
 
530
    generators and lists (assuming iter(list) is effectively a generator)
 
531
    """
 
532
    
 
533
    def setUp(self):
 
534
        super(TestTransportImplementation, self).setUp()
 
535
        self._server = self.transport_server()
 
536
        self._server.setUp()
 
537
 
 
538
    def tearDown(self):
 
539
        super(TestTransportImplementation, self).tearDown()
 
540
        self._server.tearDown()
 
541
        
 
542
    def get_transport(self):
 
543
        """Return a connected transport to the local directory."""
 
544
        base_url = self._server.get_url()
 
545
        # try getting the transport via the regular interface:
 
546
        t = get_transport(base_url)
 
547
        if not isinstance(t, self.transport_class):
 
548
            # we did not get the correct transport class type. Override the
 
549
            # regular connection behaviour by direct construction.
 
550
            t = self.transport_class(base_url)
 
551
        return t
 
552
 
 
553
 
 
554
class TestLocalTransports(TestCase):
 
555
 
 
556
    def test_get_transport_from_abspath(self):
 
557
        here = os.path.abspath('.')
 
558
        t = get_transport(here)
 
559
        self.assertIsInstance(t, LocalTransport)
 
560
        self.assertEquals(t.base, urlutils.local_path_to_url(here) + '/')
 
561
 
 
562
    def test_get_transport_from_relpath(self):
 
563
        here = os.path.abspath('.')
 
564
        t = get_transport('.')
 
565
        self.assertIsInstance(t, LocalTransport)
 
566
        self.assertEquals(t.base, urlutils.local_path_to_url('.') + '/')
 
567
 
 
568
    def test_get_transport_from_local_url(self):
 
569
        here = os.path.abspath('.')
 
570
        here_url = urlutils.local_path_to_url(here) + '/'
 
571
        t = get_transport(here_url)
 
572
        self.assertIsInstance(t, LocalTransport)
 
573
        self.assertEquals(t.base, here_url)