/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

Implement a remote Repository.has_revision method.

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
 
 
298
        transport = chroot.ChrootTransportDecorator(
 
299
            'chroot+memory:///path/B', chroot='memory:///path/')
 
300
        self.assertEqual('memory:///path/', transport.chroot_url)
 
301
 
 
302
    def test_append_file(self):
 
303
        transport = get_transport('chroot+file:///foo/bar')
 
304
        self.assertRaises(PathNotChild, transport.append_file, '/foo', None)
 
305
 
 
306
    def test_append_bytes(self):
 
307
        transport = get_transport('chroot+file:///foo/bar')
 
308
        self.assertRaises(PathNotChild, transport.append_bytes, '/foo', 'bytes')
 
309
 
 
310
    def test_clone(self):
 
311
        transport = get_transport('chroot+file:///foo/bar')
 
312
        self.assertRaises(PathNotChild, transport.clone, '/foo')
 
313
 
 
314
    def test_delete(self):
 
315
        transport = get_transport('chroot+file:///foo/bar')
 
316
        self.assertRaises(PathNotChild, transport.delete, '/foo')
 
317
 
 
318
    def test_delete_tree(self):
 
319
        transport = get_transport('chroot+file:///foo/bar')
 
320
        self.assertRaises(PathNotChild, transport.delete_tree, '/foo')
 
321
 
 
322
    def test_get(self):
 
323
        transport = get_transport('chroot+file:///foo/bar')
 
324
        self.assertRaises(PathNotChild, transport.get, '/foo')
 
325
 
 
326
    def test_get_bytes(self):
 
327
        transport = get_transport('chroot+file:///foo/bar')
 
328
        self.assertRaises(PathNotChild, transport.get_bytes, '/foo')
 
329
 
 
330
    def test_has(self):
 
331
        transport = get_transport('chroot+file:///foo/bar')
 
332
        self.assertRaises(PathNotChild, transport.has, '/foo')
 
333
 
 
334
    def test_list_dir(self):
 
335
        transport = get_transport('chroot+file:///foo/bar')
 
336
        self.assertRaises(PathNotChild, transport.list_dir, '/foo')
 
337
 
 
338
    def test_lock_read(self):
 
339
        transport = get_transport('chroot+file:///foo/bar')
 
340
        self.assertRaises(PathNotChild, transport.lock_read, '/foo')
 
341
 
 
342
    def test_lock_write(self):
 
343
        transport = get_transport('chroot+file:///foo/bar')
 
344
        self.assertRaises(PathNotChild, transport.lock_write, '/foo')
 
345
 
 
346
    def test_mkdir(self):
 
347
        transport = get_transport('chroot+file:///foo/bar')
 
348
        self.assertRaises(PathNotChild, transport.mkdir, '/foo')
 
349
 
 
350
    def test_put_bytes(self):
 
351
        transport = get_transport('chroot+file:///foo/bar')
 
352
        self.assertRaises(PathNotChild, transport.put_bytes, '/foo', 'bytes')
 
353
 
 
354
    def test_put_file(self):
 
355
        transport = get_transport('chroot+file:///foo/bar')
 
356
        self.assertRaises(PathNotChild, transport.put_file, '/foo', None)
 
357
 
 
358
    def test_rename(self):
 
359
        transport = get_transport('chroot+file:///foo/bar')
 
360
        self.assertRaises(PathNotChild, transport.rename, '/aaa', 'bbb')
 
361
        self.assertRaises(PathNotChild, transport.rename, 'ccc', '/d')
 
362
 
 
363
    def test_rmdir(self):
 
364
        transport = get_transport('chroot+file:///foo/bar')
 
365
        self.assertRaises(PathNotChild, transport.rmdir, '/foo')
 
366
 
 
367
    def test_stat(self):
 
368
        transport = get_transport('chroot+file:///foo/bar')
 
369
        self.assertRaises(PathNotChild, transport.stat, '/foo')
 
370
 
 
371
        
 
372
class ReadonlyDecoratorTransportTest(TestCase):
 
373
    """Readonly decoration specific tests."""
 
374
 
 
375
    def test_local_parameters(self):
 
376
        import bzrlib.transport.readonly as readonly
 
377
        # connect to . in readonly mode
 
378
        transport = readonly.ReadonlyTransportDecorator('readonly+.')
 
379
        self.assertEqual(True, transport.listable())
 
380
        self.assertEqual(False, transport.should_cache())
 
381
        self.assertEqual(True, transport.is_readonly())
 
382
 
 
383
    def test_http_parameters(self):
 
384
        from bzrlib.tests.HttpServer import HttpServer
 
385
        import bzrlib.transport.readonly as readonly
 
386
        # connect to . via http which is not listable
 
387
        server = HttpServer()
 
388
        server.setUp()
 
389
        try:
 
390
            transport = get_transport('readonly+' + server.get_url())
 
391
            self.failUnless(isinstance(transport,
 
392
                                       readonly.ReadonlyTransportDecorator))
 
393
            self.assertEqual(False, transport.listable())
 
394
            self.assertEqual(True, transport.should_cache())
 
395
            self.assertEqual(True, transport.is_readonly())
 
396
        finally:
 
397
            server.tearDown()
 
398
 
 
399
 
 
400
class FakeNFSDecoratorTests(TestCaseInTempDir):
 
401
    """NFS decorator specific tests."""
 
402
 
 
403
    def get_nfs_transport(self, url):
 
404
        import bzrlib.transport.fakenfs as fakenfs
 
405
        # connect to url with nfs decoration
 
406
        return fakenfs.FakeNFSTransportDecorator('fakenfs+' + url)
 
407
 
 
408
    def test_local_parameters(self):
 
409
        # the listable, should_cache and is_readonly parameters
 
410
        # are not changed by the fakenfs decorator
 
411
        transport = self.get_nfs_transport('.')
 
412
        self.assertEqual(True, transport.listable())
 
413
        self.assertEqual(False, transport.should_cache())
 
414
        self.assertEqual(False, transport.is_readonly())
 
415
 
 
416
    def test_http_parameters(self):
 
417
        # the listable, should_cache and is_readonly parameters
 
418
        # are not changed by the fakenfs decorator
 
419
        from bzrlib.tests.HttpServer import HttpServer
 
420
        # connect to . via http which is not listable
 
421
        server = HttpServer()
 
422
        server.setUp()
 
423
        try:
 
424
            transport = self.get_nfs_transport(server.get_url())
 
425
            self.assertIsInstance(
 
426
                transport, bzrlib.transport.fakenfs.FakeNFSTransportDecorator)
 
427
            self.assertEqual(False, transport.listable())
 
428
            self.assertEqual(True, transport.should_cache())
 
429
            self.assertEqual(True, transport.is_readonly())
 
430
        finally:
 
431
            server.tearDown()
 
432
 
 
433
    def test_fakenfs_server_default(self):
 
434
        # a FakeNFSServer() should bring up a local relpath server for itself
 
435
        import bzrlib.transport.fakenfs as fakenfs
 
436
        server = fakenfs.FakeNFSServer()
 
437
        server.setUp()
 
438
        try:
 
439
            # the url should be decorated appropriately
 
440
            self.assertStartsWith(server.get_url(), 'fakenfs+')
 
441
            # and we should be able to get a transport for it
 
442
            transport = get_transport(server.get_url())
 
443
            # which must be a FakeNFSTransportDecorator instance.
 
444
            self.assertIsInstance(
 
445
                transport, fakenfs.FakeNFSTransportDecorator)
 
446
        finally:
 
447
            server.tearDown()
 
448
 
 
449
    def test_fakenfs_rename_semantics(self):
 
450
        # a FakeNFS transport must mangle the way rename errors occur to
 
451
        # look like NFS problems.
 
452
        transport = self.get_nfs_transport('.')
 
453
        self.build_tree(['from/', 'from/foo', 'to/', 'to/bar'],
 
454
                        transport=transport)
 
455
        self.assertRaises(bzrlib.errors.ResourceBusy,
 
456
                          transport.rename, 'from', 'to')
 
457
 
 
458
 
 
459
class FakeVFATDecoratorTests(TestCaseInTempDir):
 
460
    """Tests for simulation of VFAT restrictions"""
 
461
 
 
462
    def get_vfat_transport(self, url):
 
463
        """Return vfat-backed transport for test directory"""
 
464
        from bzrlib.transport.fakevfat import FakeVFATTransportDecorator
 
465
        return FakeVFATTransportDecorator('vfat+' + url)
 
466
 
 
467
    def test_transport_creation(self):
 
468
        from bzrlib.transport.fakevfat import FakeVFATTransportDecorator
 
469
        transport = self.get_vfat_transport('.')
 
470
        self.assertIsInstance(transport, FakeVFATTransportDecorator)
 
471
 
 
472
    def test_transport_mkdir(self):
 
473
        transport = self.get_vfat_transport('.')
 
474
        transport.mkdir('HELLO')
 
475
        self.assertTrue(transport.has('hello'))
 
476
        self.assertTrue(transport.has('Hello'))
 
477
 
 
478
    def test_forbidden_chars(self):
 
479
        transport = self.get_vfat_transport('.')
 
480
        self.assertRaises(ValueError, transport.has, "<NU>")
 
481
 
 
482
 
 
483
class BadTransportHandler(Transport):
 
484
    def __init__(self, base_url):
 
485
        raise DependencyNotPresent('some_lib', 'testing missing dependency')
 
486
 
 
487
 
 
488
class BackupTransportHandler(Transport):
 
489
    """Test transport that works as a backup for the BadTransportHandler"""
 
490
    pass
 
491
 
 
492
 
 
493
class TestTransportImplementation(TestCaseInTempDir):
 
494
    """Implementation verification for transports.
 
495
    
 
496
    To verify a transport we need a server factory, which is a callable
 
497
    that accepts no parameters and returns an implementation of
 
498
    bzrlib.transport.Server.
 
499
    
 
500
    That Server is then used to construct transport instances and test
 
501
    the transport via loopback activity.
 
502
 
 
503
    Currently this assumes that the Transport object is connected to the 
 
504
    current working directory.  So that whatever is done 
 
505
    through the transport, should show up in the working 
 
506
    directory, and vice-versa. This is a bug, because its possible to have
 
507
    URL schemes which provide access to something that may not be 
 
508
    result in storage on the local disk, i.e. due to file system limits, or 
 
509
    due to it being a database or some other non-filesystem tool.
 
510
 
 
511
    This also tests to make sure that the functions work with both
 
512
    generators and lists (assuming iter(list) is effectively a generator)
 
513
    """
 
514
    
 
515
    def setUp(self):
 
516
        super(TestTransportImplementation, self).setUp()
 
517
        self._server = self.transport_server()
 
518
        self._server.setUp()
 
519
 
 
520
    def tearDown(self):
 
521
        super(TestTransportImplementation, self).tearDown()
 
522
        self._server.tearDown()
 
523
        
 
524
    def get_transport(self):
 
525
        """Return a connected transport to the local directory."""
 
526
        base_url = self._server.get_url()
 
527
        # try getting the transport via the regular interface:
 
528
        t = get_transport(base_url)
 
529
        if not isinstance(t, self.transport_class):
 
530
            # we did not get the correct transport class type. Override the
 
531
            # regular connection behaviour by direct construction.
 
532
            t = self.transport_class(base_url)
 
533
        return t
 
534
 
 
535
 
 
536
class TestLocalTransports(TestCase):
 
537
 
 
538
    def test_get_transport_from_abspath(self):
 
539
        here = os.path.abspath('.')
 
540
        t = get_transport(here)
 
541
        self.assertIsInstance(t, LocalTransport)
 
542
        self.assertEquals(t.base, urlutils.local_path_to_url(here) + '/')
 
543
 
 
544
    def test_get_transport_from_relpath(self):
 
545
        here = os.path.abspath('.')
 
546
        t = get_transport('.')
 
547
        self.assertIsInstance(t, LocalTransport)
 
548
        self.assertEquals(t.base, urlutils.local_path_to_url('.') + '/')
 
549
 
 
550
    def test_get_transport_from_local_url(self):
 
551
        here = os.path.abspath('.')
 
552
        here_url = urlutils.local_path_to_url(here) + '/'
 
553
        t = get_transport(here_url)
 
554
        self.assertIsInstance(t, LocalTransport)
 
555
        self.assertEquals(t.base, here_url)