~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_transport.py

  • Committer: Keir Mierle
  • Date: 2006-11-23 18:56:25 UTC
  • mto: (2168.1.1 jam-integration)
  • mto: This revision was merged to the branch mainline in revision 2171.
  • Revision ID: keir@cs.utoronto.ca-20061123185625-ndto53ylcb8zo1y6
Fix spacing error and add tests for status --short command flag.

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