/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

Move bzrlib.transport.smart to bzrlib.smart

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