~bzr-pqm/bzr/bzr.dev

2018.18.12 by Martin Pool
small test cleanups
1
# Copyright (C) 2004, 2005, 2006, 2007 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
907.1.48 by John Arbash Meinel
Updated LocalTransport by passing it through the transport_test suite, and got it to pass.
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
907.1.48 by John Arbash Meinel
Updated LocalTransport by passing it through the transport_test suite, and got it to pass.
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.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
907.1.48 by John Arbash Meinel
Updated LocalTransport by passing it through the transport_test suite, and got it to pass.
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
907.1.48 by John Arbash Meinel
Updated LocalTransport by passing it through the transport_test suite, and got it to pass.
16
17
1185.11.22 by John Arbash Meinel
Major refactoring of testtransport.
18
from cStringIO import StringIO
1442.1.44 by Robert Collins
Many transport related tweaks:
19
2018.18.12 by Martin Pool
small test cleanups
20
import bzrlib
2018.18.4 by Martin Pool
Change Transport.local_abspath to raise NotLocalUrl, and test.
21
from bzrlib import (
22
    errors,
2804.4.1 by Alexander Belchenko
some win32-specific fixes for selftest
23
    osutils,
2018.18.4 by Martin Pool
Change Transport.local_abspath to raise NotLocalUrl, and test.
24
    urlutils,
25
    )
2892.1.1 by Andrew Bennetts
Fix bug 146715: bzr+ssh:// and sftp:// should not assume port-not-specified means port 22
26
from bzrlib.errors import (DependencyNotPresent,
2379.2.1 by Robert Collins
Rewritten chroot transport that prevents accidental chroot escapes when
27
                           FileExists,
28
                           InvalidURLJoin,
29
                           NoSuchFile,
30
                           PathNotChild,
2052.6.1 by Robert Collins
``Transport.get`` has had its interface made more clear for ease of use.
31
                           ReadError,
1843.1.1 by John Arbash Meinel
Update get_transport to raise a nicer error which includes dependency info
32
                           UnsupportedProtocol,
1540.3.8 by Martin Pool
Some support for falling back between transport implementations.
33
                           )
1558.10.2 by Robert Collins
Refactor the FakeNFS support into a TransportDecorator.
34
from bzrlib.tests import TestCase, TestCaseInTempDir
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
35
from bzrlib.transport import (_clear_protocol_handlers,
36
                              _CoalescedOffset,
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
37
                              ConnectedTransport,
1864.5.9 by John Arbash Meinel
Switch to returning an object to make the api more understandable.
38
                              _get_protocol_handlers,
2241.2.2 by ghigo
Create the TransportList class
39
                              _set_protocol_handlers,
1530.1.11 by Robert Collins
Push the transport permutations list into each transport module allowing for automatic testing of new modules that are registered as transports.
40
                              _get_transport_modules,
1534.4.9 by Robert Collins
Add a readonly decorator for transports.
41
                              get_transport,
2052.6.1 by Robert Collins
``Transport.get`` has had its interface made more clear for ease of use.
42
                              LateReadError,
1530.1.11 by Robert Collins
Push the transport permutations list into each transport module allowing for automatic testing of new modules that are registered as transports.
43
                              register_lazy_transport,
2241.2.2 by ghigo
Create the TransportList class
44
                              register_transport_proto,
1540.3.8 by Martin Pool
Some support for falling back between transport implementations.
45
                              Transport,
1530.1.11 by Robert Collins
Push the transport permutations list into each transport module allowing for automatic testing of new modules that are registered as transports.
46
                              )
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
47
from bzrlib.transport.chroot import ChrootServer
1540.3.6 by Martin Pool
[merge] update from bzr.dev
48
from bzrlib.transport.memory import MemoryTransport
2245.6.1 by Alexander Belchenko
win32 UNC path: recursive cloning UNC path to root stops on //HOST, not on //
49
from bzrlib.transport.local import (LocalTransport,
2245.6.2 by Alexander Belchenko
Fix name of emulated Win32LocalTransport as Robert suggested.
50
                                    EmulatedWin32LocalTransport)
1951.2.1 by Martin Pool
Change to using LocalURLServer for testing.
51
52
53
# TODO: Should possibly split transport-specific tests into their own files.
1185.58.2 by John Arbash Meinel
Added mode to the appropriate transport functions, and tests to make sure they work.
54
55
1185.58.3 by John Arbash Meinel
code cleanup
56
class TestTransport(TestCase):
57
    """Test the non transport-concrete class functionality."""
58
2241.3.1 by ghigo
uncomment test test__get_set_protocol_handlers
59
    def test__get_set_protocol_handlers(self):
60
        handlers = _get_protocol_handlers()
61
        self.assertNotEqual([], handlers.keys( ))
62
        try:
63
            _clear_protocol_handlers()
64
            self.assertEqual([], _get_protocol_handlers().keys())
65
        finally:
66
            _set_protocol_handlers(handlers)
1530.1.11 by Robert Collins
Push the transport permutations list into each transport module allowing for automatic testing of new modules that are registered as transports.
67
68
    def test_get_transport_modules(self):
69
        handlers = _get_protocol_handlers()
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
70
        # don't pollute the current handlers
71
        _clear_protocol_handlers()
1530.1.11 by Robert Collins
Push the transport permutations list into each transport module allowing for automatic testing of new modules that are registered as transports.
72
        class SampleHandler(object):
73
            """I exist, isnt that enough?"""
74
        try:
2241.2.2 by ghigo
Create the TransportList class
75
            _clear_protocol_handlers()
76
            register_transport_proto('foo')
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
77
            register_lazy_transport('foo', 'bzrlib.tests.test_transport',
78
                                    'TestTransport.SampleHandler')
2241.2.2 by ghigo
Create the TransportList class
79
            register_transport_proto('bar')
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
80
            register_lazy_transport('bar', 'bzrlib.tests.test_transport',
81
                                    'TestTransport.SampleHandler')
82
            self.assertEqual([SampleHandler.__module__,
83
                              'bzrlib.transport.chroot'],
1530.1.11 by Robert Collins
Push the transport permutations list into each transport module allowing for automatic testing of new modules that are registered as transports.
84
                             _get_transport_modules())
85
        finally:
86
            _set_protocol_handlers(handlers)
1540.3.8 by Martin Pool
Some support for falling back between transport implementations.
87
88
    def test_transport_dependency(self):
89
        """Transport with missing dependency causes no error"""
90
        saved_handlers = _get_protocol_handlers()
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
91
        # don't pollute the current handlers
92
        _clear_protocol_handlers()
1540.3.8 by Martin Pool
Some support for falling back between transport implementations.
93
        try:
2241.2.2 by ghigo
Create the TransportList class
94
            register_transport_proto('foo')
1540.3.8 by Martin Pool
Some support for falling back between transport implementations.
95
            register_lazy_transport('foo', 'bzrlib.tests.test_transport',
96
                    'BadTransportHandler')
1843.1.1 by John Arbash Meinel
Update get_transport to raise a nicer error which includes dependency info
97
            try:
98
                get_transport('foo://fooserver/foo')
99
            except UnsupportedProtocol, e:
100
                e_str = str(e)
101
                self.assertEquals('Unsupported protocol'
102
                                  ' for url "foo://fooserver/foo":'
103
                                  ' Unable to import library "some_lib":'
104
                                  ' testing missing dependency', str(e))
105
            else:
106
                self.fail('Did not raise UnsupportedProtocol')
1540.3.8 by Martin Pool
Some support for falling back between transport implementations.
107
        finally:
1540.3.10 by Martin Pool
[broken] keep hooking pycurl into test framework
108
            # restore original values
109
            _set_protocol_handlers(saved_handlers)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
110
1540.3.10 by Martin Pool
[broken] keep hooking pycurl into test framework
111
    def test_transport_fallback(self):
112
        """Transport with missing dependency causes no error"""
113
        saved_handlers = _get_protocol_handlers()
114
        try:
2241.2.2 by ghigo
Create the TransportList class
115
            _clear_protocol_handlers()
116
            register_transport_proto('foo')
1540.3.10 by Martin Pool
[broken] keep hooking pycurl into test framework
117
            register_lazy_transport('foo', 'bzrlib.tests.test_transport',
118
                    'BackupTransportHandler')
119
            register_lazy_transport('foo', 'bzrlib.tests.test_transport',
120
                    'BadTransportHandler')
121
            t = get_transport('foo://fooserver/foo')
122
            self.assertTrue(isinstance(t, BackupTransportHandler))
123
        finally:
1540.3.8 by Martin Pool
Some support for falling back between transport implementations.
124
            _set_protocol_handlers(saved_handlers)
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
125
4011.4.1 by Jelmer Vernooij
Point out bzr+ssh:// to the user when they use ssh://.
126
    def test_ssh_hints(self):
127
        """Transport ssh:// should raise an error pointing out bzr+ssh://"""
128
        try:
129
            get_transport('ssh://fooserver/foo')
130
        except UnsupportedProtocol, e:
131
            e_str = str(e)
132
            self.assertEquals('Unsupported protocol'
133
                              ' for url "ssh://fooserver/foo":'
4032.1.4 by John Arbash Meinel
Found 2 more files with trailing whitespace.
134
                              ' bzr supports bzr+ssh to operate over ssh, use "bzr+ssh://fooserver/foo".',
4011.4.1 by Jelmer Vernooij
Point out bzr+ssh:// to the user when they use ssh://.
135
                              str(e))
136
        else:
137
            self.fail('Did not raise UnsupportedProtocol')
138
2052.6.1 by Robert Collins
``Transport.get`` has had its interface made more clear for ease of use.
139
    def test_LateReadError(self):
140
        """The LateReadError helper should raise on read()."""
141
        a_file = LateReadError('a path')
142
        try:
143
            a_file.read()
144
        except ReadError, error:
145
            self.assertEqual('a path', error.path)
146
        self.assertRaises(ReadError, a_file.read, 40)
147
        a_file.close()
148
1996.3.20 by John Arbash Meinel
[merge] bzr.dev 2063
149
    def test__combine_paths(self):
150
        t = Transport('/')
151
        self.assertEqual('/home/sarah/project/foo',
152
                         t._combine_paths('/home/sarah', 'project/foo'))
153
        self.assertEqual('/etc',
154
                         t._combine_paths('/home/sarah', '../../etc'))
2070.3.2 by Andrew Bennetts
Merge from bzr.dev
155
        self.assertEqual('/etc',
156
                         t._combine_paths('/home/sarah', '../../../etc'))
157
        self.assertEqual('/etc',
158
                         t._combine_paths('/home/sarah', '/etc'))
1996.3.20 by John Arbash Meinel
[merge] bzr.dev 2063
159
2018.18.4 by Martin Pool
Change Transport.local_abspath to raise NotLocalUrl, and test.
160
    def test_local_abspath_non_local_transport(self):
161
        # the base implementation should throw
162
        t = MemoryTransport()
163
        e = self.assertRaises(errors.NotLocalUrl, t.local_abspath, 't')
164
        self.assertEqual('memory:///t is not a local path.', str(e))
165
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
166
167
class TestCoalesceOffsets(TestCase):
3059.2.17 by Vincent Ladeuil
Limit GET requests by body size instead of number of ranges.
168
169
    def check(self, expected, offsets, limit=0, max_size=0, fudge=0):
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
170
        coalesce = Transport._coalesce_offsets
1864.5.9 by John Arbash Meinel
Switch to returning an object to make the api more understandable.
171
        exp = [_CoalescedOffset(*x) for x in expected]
3059.2.17 by Vincent Ladeuil
Limit GET requests by body size instead of number of ranges.
172
        out = list(coalesce(offsets, limit=limit, fudge_factor=fudge,
173
                            max_size=max_size))
1864.5.9 by John Arbash Meinel
Switch to returning an object to make the api more understandable.
174
        self.assertEqual(exp, out)
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
175
176
    def test_coalesce_empty(self):
177
        self.check([], [])
178
179
    def test_coalesce_simple(self):
180
        self.check([(0, 10, [(0, 10)])], [(0, 10)])
181
182
    def test_coalesce_unrelated(self):
183
        self.check([(0, 10, [(0, 10)]),
184
                    (20, 10, [(0, 10)]),
185
                   ], [(0, 10), (20, 10)])
3059.2.17 by Vincent Ladeuil
Limit GET requests by body size instead of number of ranges.
186
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
187
    def test_coalesce_unsorted(self):
188
        self.check([(20, 10, [(0, 10)]),
189
                    (0, 10, [(0, 10)]),
190
                   ], [(20, 10), (0, 10)])
191
192
    def test_coalesce_nearby(self):
193
        self.check([(0, 20, [(0, 10), (10, 10)])],
194
                   [(0, 10), (10, 10)])
195
196
    def test_coalesce_overlapped(self):
3686.1.9 by John Arbash Meinel
Overlapping ranges are not allowed anymore.
197
        self.assertRaises(ValueError,
198
            self.check, [(0, 15, [(0, 10), (5, 10)])],
199
                        [(0, 10), (5, 10)])
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
200
201
    def test_coalesce_limit(self):
202
        self.check([(10, 50, [(0, 10), (10, 10), (20, 10),
203
                              (30, 10), (40, 10)]),
204
                    (60, 50, [(0, 10), (10, 10), (20, 10),
205
                              (30, 10), (40, 10)]),
206
                   ], [(10, 10), (20, 10), (30, 10), (40, 10),
207
                       (50, 10), (60, 10), (70, 10), (80, 10),
208
                       (90, 10), (100, 10)],
209
                    limit=5)
210
211
    def test_coalesce_no_limit(self):
212
        self.check([(10, 100, [(0, 10), (10, 10), (20, 10),
213
                               (30, 10), (40, 10), (50, 10),
214
                               (60, 10), (70, 10), (80, 10),
215
                               (90, 10)]),
216
                   ], [(10, 10), (20, 10), (30, 10), (40, 10),
217
                       (50, 10), (60, 10), (70, 10), (80, 10),
218
                       (90, 10), (100, 10)])
219
1864.5.3 by John Arbash Meinel
Allow collapsing ranges even if they are just 'close'
220
    def test_coalesce_fudge(self):
221
        self.check([(10, 30, [(0, 10), (20, 10)]),
222
                    (100, 10, [(0, 10),]),
223
                   ], [(10, 10), (30, 10), (100, 10)],
224
                   fudge=10
225
                  )
3059.2.17 by Vincent Ladeuil
Limit GET requests by body size instead of number of ranges.
226
    def test_coalesce_max_size(self):
227
        self.check([(10, 20, [(0, 10), (10, 10)]),
228
                    (30, 50, [(0, 50)]),
229
                    # If one range is above max_size, it gets its own coalesced
230
                    # offset
231
                    (100, 80, [(0, 80),]),],
232
                   [(10, 10), (20, 10), (30, 50), (100, 80)],
233
                   max_size=50
234
                  )
235
236
    def test_coalesce_no_max_size(self):
237
        self.check([(10, 170, [(0, 10), (10, 10), (20, 50), (70, 100)]),],
238
                   [(10, 10), (20, 10), (30, 50), (80, 100)],
239
                  )
1864.5.3 by John Arbash Meinel
Allow collapsing ranges even if they are just 'close'
240
3876.1.2 by John Arbash Meinel
Add a test case that checks the 100MB limit.
241
    def test_coalesce_default_limit(self):
242
        # By default we use a 100MB max size.
243
        ten_mb = 10*1024*1024
244
        self.check([(0, 10*ten_mb, [(i*ten_mb, ten_mb) for i in range(10)]),
245
                    (10*ten_mb, ten_mb, [(0, ten_mb)])],
246
                   [(i*ten_mb, ten_mb) for i in range(11)])
247
        self.check([(0, 11*ten_mb, [(i*ten_mb, ten_mb) for i in range(11)]),],
248
                   [(i*ten_mb, ten_mb) for i in range(11)],
249
                   max_size=1*1024*1024*1024)
250
1540.3.3 by Martin Pool
Review updates of pycurl transport
251
1442.1.44 by Robert Collins
Many transport related tweaks:
252
class TestMemoryTransport(TestCase):
253
254
    def test_get_transport(self):
1540.3.6 by Martin Pool
[merge] update from bzr.dev
255
        MemoryTransport()
1442.1.44 by Robert Collins
Many transport related tweaks:
256
257
    def test_clone(self):
1540.3.6 by Martin Pool
[merge] update from bzr.dev
258
        transport = MemoryTransport()
259
        self.assertTrue(isinstance(transport, MemoryTransport))
1910.15.3 by Andrew Bennetts
Make memory transport pass tests.
260
        self.assertEqual("memory:///", transport.clone("/").base)
1442.1.44 by Robert Collins
Many transport related tweaks:
261
262
    def test_abspath(self):
1540.3.6 by Martin Pool
[merge] update from bzr.dev
263
        transport = MemoryTransport()
1685.1.42 by John Arbash Meinel
A couple more fixes to make sure memory:/// works correctly.
264
        self.assertEqual("memory:///relpath", transport.abspath('relpath'))
1442.1.44 by Robert Collins
Many transport related tweaks:
265
1910.15.1 by Andrew Bennetts
More tests for abspath and clone behaviour
266
    def test_abspath_of_root(self):
267
        transport = MemoryTransport()
268
        self.assertEqual("memory:///", transport.base)
269
        self.assertEqual("memory:///", transport.abspath('/'))
270
2070.3.1 by Andrew Bennetts
Fix memory_transport.abspath('/foo')
271
    def test_abspath_of_relpath_starting_at_root(self):
1540.3.6 by Martin Pool
[merge] update from bzr.dev
272
        transport = MemoryTransport()
2070.3.1 by Andrew Bennetts
Fix memory_transport.abspath('/foo')
273
        self.assertEqual("memory:///foo", transport.abspath('/foo'))
1442.1.44 by Robert Collins
Many transport related tweaks:
274
275
    def test_append_and_get(self):
1540.3.6 by Martin Pool
[merge] update from bzr.dev
276
        transport = MemoryTransport()
1955.3.16 by John Arbash Meinel
Switch over to Transport.append_bytes or append_files
277
        transport.append_bytes('path', 'content')
1442.1.44 by Robert Collins
Many transport related tweaks:
278
        self.assertEqual(transport.get('path').read(), 'content')
1955.3.16 by John Arbash Meinel
Switch over to Transport.append_bytes or append_files
279
        transport.append_file('path', StringIO('content'))
1442.1.44 by Robert Collins
Many transport related tweaks:
280
        self.assertEqual(transport.get('path').read(), 'contentcontent')
281
282
    def test_put_and_get(self):
1540.3.6 by Martin Pool
[merge] update from bzr.dev
283
        transport = MemoryTransport()
1955.3.7 by John Arbash Meinel
Fix the deprecation warnings in the transport tests themselves
284
        transport.put_file('path', StringIO('content'))
1442.1.44 by Robert Collins
Many transport related tweaks:
285
        self.assertEqual(transport.get('path').read(), 'content')
1955.3.7 by John Arbash Meinel
Fix the deprecation warnings in the transport tests themselves
286
        transport.put_bytes('path', 'content')
1442.1.44 by Robert Collins
Many transport related tweaks:
287
        self.assertEqual(transport.get('path').read(), 'content')
288
289
    def test_append_without_dir_fails(self):
1540.3.6 by Martin Pool
[merge] update from bzr.dev
290
        transport = MemoryTransport()
1442.1.44 by Robert Collins
Many transport related tweaks:
291
        self.assertRaises(NoSuchFile,
1955.3.16 by John Arbash Meinel
Switch over to Transport.append_bytes or append_files
292
                          transport.append_bytes, 'dir/path', 'content')
1442.1.44 by Robert Collins
Many transport related tweaks:
293
294
    def test_put_without_dir_fails(self):
1540.3.6 by Martin Pool
[merge] update from bzr.dev
295
        transport = MemoryTransport()
1442.1.44 by Robert Collins
Many transport related tweaks:
296
        self.assertRaises(NoSuchFile,
1955.3.7 by John Arbash Meinel
Fix the deprecation warnings in the transport tests themselves
297
                          transport.put_file, 'dir/path', StringIO('content'))
1442.1.44 by Robert Collins
Many transport related tweaks:
298
299
    def test_get_missing(self):
1540.3.6 by Martin Pool
[merge] update from bzr.dev
300
        transport = MemoryTransport()
1442.1.44 by Robert Collins
Many transport related tweaks:
301
        self.assertRaises(NoSuchFile, transport.get, 'foo')
302
303
    def test_has_missing(self):
1540.3.6 by Martin Pool
[merge] update from bzr.dev
304
        transport = MemoryTransport()
1442.1.44 by Robert Collins
Many transport related tweaks:
305
        self.assertEquals(False, transport.has('foo'))
306
307
    def test_has_present(self):
1540.3.6 by Martin Pool
[merge] update from bzr.dev
308
        transport = MemoryTransport()
1955.3.16 by John Arbash Meinel
Switch over to Transport.append_bytes or append_files
309
        transport.append_bytes('foo', 'content')
1442.1.44 by Robert Collins
Many transport related tweaks:
310
        self.assertEquals(True, transport.has('foo'))
311
2120.3.1 by John Arbash Meinel
Fix MemoryTransport.list_dir() implementation, and update tests
312
    def test_list_dir(self):
313
        transport = MemoryTransport()
314
        transport.put_bytes('foo', 'content')
315
        transport.mkdir('dir')
316
        transport.put_bytes('dir/subfoo', 'content')
317
        transport.put_bytes('dirlike', 'content')
318
319
        self.assertEquals(['dir', 'dirlike', 'foo'], sorted(transport.list_dir('.')))
320
        self.assertEquals(['subfoo'], sorted(transport.list_dir('dir')))
321
1442.1.44 by Robert Collins
Many transport related tweaks:
322
    def test_mkdir(self):
1540.3.6 by Martin Pool
[merge] update from bzr.dev
323
        transport = MemoryTransport()
1442.1.44 by Robert Collins
Many transport related tweaks:
324
        transport.mkdir('dir')
1955.3.16 by John Arbash Meinel
Switch over to Transport.append_bytes or append_files
325
        transport.append_bytes('dir/path', 'content')
1442.1.44 by Robert Collins
Many transport related tweaks:
326
        self.assertEqual(transport.get('dir/path').read(), 'content')
327
328
    def test_mkdir_missing_parent(self):
1540.3.6 by Martin Pool
[merge] update from bzr.dev
329
        transport = MemoryTransport()
1442.1.44 by Robert Collins
Many transport related tweaks:
330
        self.assertRaises(NoSuchFile,
331
                          transport.mkdir, 'dir/dir')
332
333
    def test_mkdir_twice(self):
1540.3.6 by Martin Pool
[merge] update from bzr.dev
334
        transport = MemoryTransport()
1442.1.44 by Robert Collins
Many transport related tweaks:
335
        transport.mkdir('dir')
336
        self.assertRaises(FileExists, transport.mkdir, 'dir')
1530.1.5 by Robert Collins
Reinstate Memory parameter tests.
337
338
    def test_parameters(self):
1540.3.6 by Martin Pool
[merge] update from bzr.dev
339
        transport = MemoryTransport()
1530.1.5 by Robert Collins
Reinstate Memory parameter tests.
340
        self.assertEqual(True, transport.listable())
341
        self.assertEqual(False, transport.is_readonly())
1442.1.44 by Robert Collins
Many transport related tweaks:
342
343
    def test_iter_files_recursive(self):
1540.3.6 by Martin Pool
[merge] update from bzr.dev
344
        transport = MemoryTransport()
1442.1.44 by Robert Collins
Many transport related tweaks:
345
        transport.mkdir('dir')
1955.3.7 by John Arbash Meinel
Fix the deprecation warnings in the transport tests themselves
346
        transport.put_bytes('dir/foo', 'content')
347
        transport.put_bytes('dir/bar', 'content')
348
        transport.put_bytes('bar', 'content')
1442.1.44 by Robert Collins
Many transport related tweaks:
349
        paths = set(transport.iter_files_recursive())
350
        self.assertEqual(set(['dir/foo', 'dir/bar', 'bar']), paths)
351
352
    def test_stat(self):
1540.3.6 by Martin Pool
[merge] update from bzr.dev
353
        transport = MemoryTransport()
1955.3.7 by John Arbash Meinel
Fix the deprecation warnings in the transport tests themselves
354
        transport.put_bytes('foo', 'content')
355
        transport.put_bytes('bar', 'phowar')
1442.1.44 by Robert Collins
Many transport related tweaks:
356
        self.assertEqual(7, transport.stat('foo').st_size)
357
        self.assertEqual(6, transport.stat('bar').st_size)
1185.35.31 by Aaron Bentley
Throw ConnectionError instead of NoSuchFile except when we get a 404
358
2070.5.1 by Andrew Bennetts
Add ChrootTransportDecorator.
359
360
class ChrootDecoratorTransportTest(TestCase):
361
    """Chroot decoration specific tests."""
362
2018.5.54 by Andrew Bennetts
Fix ChrootTransportDecorator's abspath method to be consistent with its clone
363
    def test_abspath(self):
364
        # The abspath is always relative to the chroot_url.
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
365
        server = ChrootServer(get_transport('memory:///foo/bar/'))
366
        server.setUp()
367
        transport = get_transport(server.get_url())
368
        self.assertEqual(server.get_url(), transport.abspath('/'))
2018.5.54 by Andrew Bennetts
Fix ChrootTransportDecorator's abspath method to be consistent with its clone
369
370
        subdir_transport = transport.clone('subdir')
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
371
        self.assertEqual(server.get_url(), subdir_transport.abspath('/'))
372
        server.tearDown()
2379.2.1 by Robert Collins
Rewritten chroot transport that prevents accidental chroot escapes when
373
374
    def test_clone(self):
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
375
        server = ChrootServer(get_transport('memory:///foo/bar/'))
376
        server.setUp()
377
        transport = get_transport(server.get_url())
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
378
        # relpath from root and root path are the same
379
        relpath_cloned = transport.clone('foo')
380
        abspath_cloned = transport.clone('/foo')
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
381
        self.assertEqual(server, relpath_cloned.server)
382
        self.assertEqual(server, abspath_cloned.server)
383
        server.tearDown()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
384
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
385
    def test_chroot_url_preserves_chroot(self):
386
        """Calling get_transport on a chroot transport's base should produce a
387
        transport with exactly the same behaviour as the original chroot
388
        transport.
389
390
        This is so that it is not possible to escape a chroot by doing::
391
            url = chroot_transport.base
392
            parent_url = urlutils.join(url, '..')
393
            new_transport = get_transport(parent_url)
394
        """
395
        server = ChrootServer(get_transport('memory:///path/subpath'))
396
        server.setUp()
397
        transport = get_transport(server.get_url())
398
        new_transport = get_transport(transport.base)
399
        self.assertEqual(transport.server, new_transport.server)
400
        self.assertEqual(transport.base, new_transport.base)
401
        server.tearDown()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
402
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
403
    def test_urljoin_preserves_chroot(self):
404
        """Using urlutils.join(url, '..') on a chroot URL should not produce a
405
        URL that escapes the intended chroot.
406
407
        This is so that it is not possible to escape a chroot by doing::
408
            url = chroot_transport.base
409
            parent_url = urlutils.join(url, '..')
410
            new_transport = get_transport(parent_url)
411
        """
412
        server = ChrootServer(get_transport('memory:///path/'))
413
        server.setUp()
414
        transport = get_transport(server.get_url())
415
        self.assertRaises(
416
            InvalidURLJoin, urlutils.join, transport.base, '..')
417
        server.tearDown()
418
419
420
class ChrootServerTest(TestCase):
421
422
    def test_construct(self):
423
        backing_transport = MemoryTransport()
424
        server = ChrootServer(backing_transport)
425
        self.assertEqual(backing_transport, server.backing_transport)
426
427
    def test_setUp(self):
428
        backing_transport = MemoryTransport()
429
        server = ChrootServer(backing_transport)
430
        server.setUp()
2241.3.5 by ghigo
update to the latest bzr.dev
431
        self.assertTrue(server.scheme in _get_protocol_handlers().keys())
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
432
433
    def test_tearDown(self):
434
        backing_transport = MemoryTransport()
435
        server = ChrootServer(backing_transport)
436
        server.setUp()
437
        server.tearDown()
2241.3.5 by ghigo
update to the latest bzr.dev
438
        self.assertFalse(server.scheme in _get_protocol_handlers().keys())
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
439
440
    def test_get_url(self):
441
        backing_transport = MemoryTransport()
442
        server = ChrootServer(backing_transport)
443
        server.setUp()
444
        self.assertEqual('chroot-%d:///' % id(server), server.get_url())
445
        server.tearDown()
2018.5.53 by Andrew Bennetts
Small fix to urlutils.joinpath that was causing a misbehaviour in
446
2156.2.1 by v.ladeuil+lp at free
Make the tests windows compatible.
447
1534.4.9 by Robert Collins
Add a readonly decorator for transports.
448
class ReadonlyDecoratorTransportTest(TestCase):
449
    """Readonly decoration specific tests."""
450
451
    def test_local_parameters(self):
452
        import bzrlib.transport.readonly as readonly
453
        # connect to . in readonly mode
454
        transport = readonly.ReadonlyTransportDecorator('readonly+.')
455
        self.assertEqual(True, transport.listable())
456
        self.assertEqual(True, transport.is_readonly())
457
458
    def test_http_parameters(self):
2929.3.7 by Vincent Ladeuil
Rename bzrlib/test/HttpServer.py to bzrlib/tests/http_server.py and fix uses.
459
        from bzrlib.tests.http_server import HttpServer
1534.4.9 by Robert Collins
Add a readonly decorator for transports.
460
        import bzrlib.transport.readonly as readonly
2929.3.7 by Vincent Ladeuil
Rename bzrlib/test/HttpServer.py to bzrlib/tests/http_server.py and fix uses.
461
        # connect to '.' via http which is not listable
1534.4.9 by Robert Collins
Add a readonly decorator for transports.
462
        server = HttpServer()
463
        server.setUp()
464
        try:
465
            transport = get_transport('readonly+' + server.get_url())
466
            self.failUnless(isinstance(transport,
467
                                       readonly.ReadonlyTransportDecorator))
468
            self.assertEqual(False, transport.listable())
469
            self.assertEqual(True, transport.is_readonly())
470
        finally:
471
            server.tearDown()
1540.3.8 by Martin Pool
Some support for falling back between transport implementations.
472
473
1558.10.2 by Robert Collins
Refactor the FakeNFS support into a TransportDecorator.
474
class FakeNFSDecoratorTests(TestCaseInTempDir):
475
    """NFS decorator specific tests."""
476
477
    def get_nfs_transport(self, url):
478
        import bzrlib.transport.fakenfs as fakenfs
479
        # connect to url with nfs decoration
480
        return fakenfs.FakeNFSTransportDecorator('fakenfs+' + url)
481
482
    def test_local_parameters(self):
2701.1.1 by Martin Pool
Remove Transport.should_cache.
483
        # the listable and is_readonly parameters
1558.10.2 by Robert Collins
Refactor the FakeNFS support into a TransportDecorator.
484
        # are not changed by the fakenfs decorator
485
        transport = self.get_nfs_transport('.')
486
        self.assertEqual(True, transport.listable())
487
        self.assertEqual(False, transport.is_readonly())
488
489
    def test_http_parameters(self):
2701.1.1 by Martin Pool
Remove Transport.should_cache.
490
        # the listable and is_readonly parameters
1558.10.2 by Robert Collins
Refactor the FakeNFS support into a TransportDecorator.
491
        # are not changed by the fakenfs decorator
2929.3.7 by Vincent Ladeuil
Rename bzrlib/test/HttpServer.py to bzrlib/tests/http_server.py and fix uses.
492
        from bzrlib.tests.http_server import HttpServer
493
        # connect to '.' via http which is not listable
1558.10.2 by Robert Collins
Refactor the FakeNFS support into a TransportDecorator.
494
        server = HttpServer()
495
        server.setUp()
496
        try:
497
            transport = self.get_nfs_transport(server.get_url())
498
            self.assertIsInstance(
499
                transport, bzrlib.transport.fakenfs.FakeNFSTransportDecorator)
500
            self.assertEqual(False, transport.listable())
501
            self.assertEqual(True, transport.is_readonly())
502
        finally:
503
            server.tearDown()
504
505
    def test_fakenfs_server_default(self):
506
        # a FakeNFSServer() should bring up a local relpath server for itself
507
        import bzrlib.transport.fakenfs as fakenfs
508
        server = fakenfs.FakeNFSServer()
509
        server.setUp()
510
        try:
1951.2.1 by Martin Pool
Change to using LocalURLServer for testing.
511
            # the url should be decorated appropriately
1951.2.3 by Martin Pool
Localtransport cleanup review (john)
512
            self.assertStartsWith(server.get_url(), 'fakenfs+')
1558.10.2 by Robert Collins
Refactor the FakeNFS support into a TransportDecorator.
513
            # and we should be able to get a transport for it
514
            transport = get_transport(server.get_url())
515
            # which must be a FakeNFSTransportDecorator instance.
516
            self.assertIsInstance(
517
                transport, fakenfs.FakeNFSTransportDecorator)
518
        finally:
519
            server.tearDown()
520
521
    def test_fakenfs_rename_semantics(self):
522
        # a FakeNFS transport must mangle the way rename errors occur to
523
        # look like NFS problems.
524
        transport = self.get_nfs_transport('.')
525
        self.build_tree(['from/', 'from/foo', 'to/', 'to/bar'],
526
                        transport=transport)
2018.18.12 by Martin Pool
small test cleanups
527
        self.assertRaises(errors.ResourceBusy,
1558.10.2 by Robert Collins
Refactor the FakeNFS support into a TransportDecorator.
528
                          transport.rename, 'from', 'to')
529
530
1608.2.4 by Martin Pool
[broken] Add FakeFVATTransport
531
class FakeVFATDecoratorTests(TestCaseInTempDir):
532
    """Tests for simulation of VFAT restrictions"""
533
534
    def get_vfat_transport(self, url):
535
        """Return vfat-backed transport for test directory"""
536
        from bzrlib.transport.fakevfat import FakeVFATTransportDecorator
537
        return FakeVFATTransportDecorator('vfat+' + url)
538
539
    def test_transport_creation(self):
540
        from bzrlib.transport.fakevfat import FakeVFATTransportDecorator
541
        transport = self.get_vfat_transport('.')
542
        self.assertIsInstance(transport, FakeVFATTransportDecorator)
543
544
    def test_transport_mkdir(self):
545
        transport = self.get_vfat_transport('.')
546
        transport.mkdir('HELLO')
547
        self.assertTrue(transport.has('hello'))
548
        self.assertTrue(transport.has('Hello'))
549
1608.2.11 by Martin Pool
(FakeVFAT) add test for detection of invalid characters
550
    def test_forbidden_chars(self):
551
        transport = self.get_vfat_transport('.')
552
        self.assertRaises(ValueError, transport.has, "<NU>")
553
554
1540.3.8 by Martin Pool
Some support for falling back between transport implementations.
555
class BadTransportHandler(Transport):
556
    def __init__(self, base_url):
557
        raise DependencyNotPresent('some_lib', 'testing missing dependency')
558
559
560
class BackupTransportHandler(Transport):
561
    """Test transport that works as a backup for the BadTransportHandler"""
1540.3.10 by Martin Pool
[broken] keep hooking pycurl into test framework
562
    pass
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
563
564
565
class TestTransportImplementation(TestCaseInTempDir):
566
    """Implementation verification for transports.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
567
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
568
    To verify a transport we need a server factory, which is a callable
569
    that accepts no parameters and returns an implementation of
570
    bzrlib.transport.Server.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
571
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
572
    That Server is then used to construct transport instances and test
573
    the transport via loopback activity.
574
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
575
    Currently this assumes that the Transport object is connected to the
576
    current working directory.  So that whatever is done
577
    through the transport, should show up in the working
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
578
    directory, and vice-versa. This is a bug, because its possible to have
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
579
    URL schemes which provide access to something that may not be
580
    result in storage on the local disk, i.e. due to file system limits, or
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
581
    due to it being a database or some other non-filesystem tool.
582
583
    This also tests to make sure that the functions work with both
584
    generators and lists (assuming iter(list) is effectively a generator)
585
    """
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
586
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
587
    def setUp(self):
588
        super(TestTransportImplementation, self).setUp()
589
        self._server = self.transport_server()
590
        self._server.setUp()
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
591
        self.addCleanup(self._server.tearDown)
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
592
2520.3.1 by Vincent Ladeuil
Fix 110448 by adding a relpath parameter to get_transport.
593
    def get_transport(self, relpath=None):
594
        """Return a connected transport to the local directory.
595
596
        :param relpath: a path relative to the base url.
597
        """
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
598
        base_url = self._server.get_url()
2520.3.1 by Vincent Ladeuil
Fix 110448 by adding a relpath parameter to get_transport.
599
        url = self._adjust_url(base_url, relpath)
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
600
        # try getting the transport via the regular interface:
2520.3.1 by Vincent Ladeuil
Fix 110448 by adding a relpath parameter to get_transport.
601
        t = get_transport(url)
2485.8.39 by Vincent Ladeuil
Add tests around connection reuse.
602
        # vila--20070607 if the following are commented out the test suite
603
        # still pass. Is this really still needed or was it a forgotten
604
        # temporary fix ?
1986.2.5 by Robert Collins
Unbreak transport tests.
605
        if not isinstance(t, self.transport_class):
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
606
            # we did not get the correct transport class type. Override the
607
            # regular connection behaviour by direct construction.
2520.3.1 by Vincent Ladeuil
Fix 110448 by adding a relpath parameter to get_transport.
608
            t = self.transport_class(url)
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
609
        return t
1951.2.1 by Martin Pool
Change to using LocalURLServer for testing.
610
611
612
class TestLocalTransports(TestCase):
613
614
    def test_get_transport_from_abspath(self):
2804.4.1 by Alexander Belchenko
some win32-specific fixes for selftest
615
        here = osutils.abspath('.')
1951.2.1 by Martin Pool
Change to using LocalURLServer for testing.
616
        t = get_transport(here)
617
        self.assertIsInstance(t, LocalTransport)
618
        self.assertEquals(t.base, urlutils.local_path_to_url(here) + '/')
619
620
    def test_get_transport_from_relpath(self):
2804.4.1 by Alexander Belchenko
some win32-specific fixes for selftest
621
        here = osutils.abspath('.')
1951.2.1 by Martin Pool
Change to using LocalURLServer for testing.
622
        t = get_transport('.')
623
        self.assertIsInstance(t, LocalTransport)
1951.2.3 by Martin Pool
Localtransport cleanup review (john)
624
        self.assertEquals(t.base, urlutils.local_path_to_url('.') + '/')
1951.2.1 by Martin Pool
Change to using LocalURLServer for testing.
625
626
    def test_get_transport_from_local_url(self):
2804.4.1 by Alexander Belchenko
some win32-specific fixes for selftest
627
        here = osutils.abspath('.')
1951.2.1 by Martin Pool
Change to using LocalURLServer for testing.
628
        here_url = urlutils.local_path_to_url(here) + '/'
629
        t = get_transport(here_url)
630
        self.assertIsInstance(t, LocalTransport)
631
        self.assertEquals(t.base, here_url)
2245.6.1 by Alexander Belchenko
win32 UNC path: recursive cloning UNC path to root stops on //HOST, not on //
632
2018.18.4 by Martin Pool
Change Transport.local_abspath to raise NotLocalUrl, and test.
633
    def test_local_abspath(self):
2804.4.1 by Alexander Belchenko
some win32-specific fixes for selftest
634
        here = osutils.abspath('.')
2018.18.4 by Martin Pool
Change Transport.local_abspath to raise NotLocalUrl, and test.
635
        t = get_transport(here)
636
        self.assertEquals(t.local_abspath(''), here)
637
2245.6.1 by Alexander Belchenko
win32 UNC path: recursive cloning UNC path to root stops on //HOST, not on //
638
639
class TestWin32LocalTransport(TestCase):
640
641
    def test_unc_clone_to_root(self):
642
        # Win32 UNC path like \\HOST\path
643
        # clone to root should stop at least at \\HOST part
644
        # not on \\
2245.6.2 by Alexander Belchenko
Fix name of emulated Win32LocalTransport as Robert suggested.
645
        t = EmulatedWin32LocalTransport('file://HOST/path/to/some/dir/')
2245.6.1 by Alexander Belchenko
win32 UNC path: recursive cloning UNC path to root stops on //HOST, not on //
646
        for i in xrange(4):
647
            t = t.clone('..')
648
        self.assertEquals(t.base, 'file://HOST/')
649
        # make sure we reach the root
650
        t = t.clone('..')
651
        self.assertEquals(t.base, 'file://HOST/')
2477.1.7 by Martin Pool
test_transport must provide get_test_permutations
652
2485.8.61 by Vincent Ladeuil
From review comments, use a private scheme for testing.
653
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
654
class TestConnectedTransport(TestCase):
655
    """Tests for connected to remote server transports"""
656
657
    def test_parse_url(self):
2892.1.1 by Andrew Bennetts
Fix bug 146715: bzr+ssh:// and sftp:// should not assume port-not-specified means port 22
658
        t = ConnectedTransport('http://simple.example.com/home/source')
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
659
        self.assertEquals(t._host, 'simple.example.com')
3004.2.1 by Vincent Ladeuil
Fix 150860 by leaving port as user specified it.
660
        self.assertEquals(t._port, None)
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
661
        self.assertEquals(t._path, '/home/source/')
662
        self.failUnless(t._user is None)
663
        self.failUnless(t._password is None)
664
2892.1.1 by Andrew Bennetts
Fix bug 146715: bzr+ssh:// and sftp:// should not assume port-not-specified means port 22
665
        self.assertEquals(t.base, 'http://simple.example.com/home/source/')
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
666
3498.2.1 by Neil Martinsen-Burrell
Fix bug 228058: user names with @ signs should work
667
    def test_parse_url_with_at_in_user(self):
668
        # Bug 228058
669
        t = ConnectedTransport('ftp://user@host.com@www.host.com/')
670
        self.assertEquals(t._user, 'user@host.com')
671
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
672
    def test_parse_quoted_url(self):
673
        t = ConnectedTransport('http://ro%62ey:h%40t@ex%41mple.com:2222/path')
674
        self.assertEquals(t._host, 'exAmple.com')
675
        self.assertEquals(t._port, 2222)
676
        self.assertEquals(t._user, 'robey')
677
        self.assertEquals(t._password, 'h@t')
678
        self.assertEquals(t._path, '/path/')
679
680
        # Base should not keep track of the password
681
        self.assertEquals(t.base, 'http://robey@exAmple.com:2222/path/')
682
683
    def test_parse_invalid_url(self):
684
        self.assertRaises(errors.InvalidURL,
685
                          ConnectedTransport,
686
                          'sftp://lily.org:~janneke/public/bzr/gub')
687
688
    def test_relpath(self):
689
        t = ConnectedTransport('sftp://user@host.com/abs/path')
690
691
        self.assertEquals(t.relpath('sftp://user@host.com/abs/path/sub'), 'sub')
692
        self.assertRaises(errors.PathNotChild, t.relpath,
693
                          'http://user@host.com/abs/path/sub')
694
        self.assertRaises(errors.PathNotChild, t.relpath,
695
                          'sftp://user2@host.com/abs/path/sub')
696
        self.assertRaises(errors.PathNotChild, t.relpath,
697
                          'sftp://user@otherhost.com/abs/path/sub')
698
        self.assertRaises(errors.PathNotChild, t.relpath,
699
                          'sftp://user@host.com:33/abs/path/sub')
700
        # Make sure it works when we don't supply a username
701
        t = ConnectedTransport('sftp://host.com/abs/path')
702
        self.assertEquals(t.relpath('sftp://host.com/abs/path/sub'), 'sub')
703
704
        # Make sure it works when parts of the path will be url encoded
705
        t = ConnectedTransport('sftp://host.com/dev/%path')
706
        self.assertEquals(t.relpath('sftp://host.com/dev/%path/sub'), 'sub')
707
2485.8.32 by Vincent Ladeuil
Keep credentials used at connection creation for reconnection purposes.
708
    def test_connection_sharing_propagate_credentials(self):
2900.2.16 by Vincent Ladeuil
Make hhtp proxy aware of AuthenticationConfig (for password).
709
        t = ConnectedTransport('ftp://user@host.com/abs/path')
710
        self.assertEquals('user', t._user)
711
        self.assertEquals('host.com', t._host)
2485.8.32 by Vincent Ladeuil
Keep credentials used at connection creation for reconnection purposes.
712
        self.assertIs(None, t._get_connection())
713
        self.assertIs(None, t._password)
714
        c = t.clone('subdir')
2900.2.16 by Vincent Ladeuil
Make hhtp proxy aware of AuthenticationConfig (for password).
715
        self.assertIs(None, c._get_connection())
2485.8.32 by Vincent Ladeuil
Keep credentials used at connection creation for reconnection purposes.
716
        self.assertIs(None, t._password)
717
718
        # Simulate the user entering a password
719
        password = 'secret'
720
        connection = object()
721
        t._set_connection(connection, password)
722
        self.assertIs(connection, t._get_connection())
723
        self.assertIs(password, t._get_credentials())
724
        self.assertIs(connection, c._get_connection())
725
        self.assertIs(password, c._get_credentials())
2485.8.30 by Vincent Ladeuil
Implement reliable connection sharing.
726
2485.8.39 by Vincent Ladeuil
Add tests around connection reuse.
727
        # credentials can be updated
728
        new_password = 'even more secret'
729
        c._update_credentials(new_password)
730
        self.assertIs(connection, t._get_connection())
731
        self.assertIs(new_password, t._get_credentials())
732
        self.assertIs(connection, c._get_connection())
733
        self.assertIs(new_password, c._get_credentials())
734
2477.1.7 by Martin Pool
test_transport must provide get_test_permutations
735
2476.3.5 by Vincent Ladeuil
Naive implementation of transport reuse by Transport.get_transport().
736
class TestReusedTransports(TestCase):
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
737
    """Tests for transport reuse"""
2476.3.5 by Vincent Ladeuil
Naive implementation of transport reuse by Transport.get_transport().
738
739
    def test_reuse_same_transport(self):
1551.18.10 by Aaron Bentley
get_transport appends to possible_transports if it's an empty list
740
        possible_transports = []
741
        t1 = get_transport('http://foo/',
742
                           possible_transports=possible_transports)
743
        self.assertEqual([t1], possible_transports)
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
744
        t2 = get_transport('http://foo/', possible_transports=[t1])
745
        self.assertIs(t1, t2)
746
747
        # Also check that final '/' are handled correctly
748
        t3 = get_transport('http://foo/path/')
749
        t4 = get_transport('http://foo/path', possible_transports=[t3])
750
        self.assertIs(t3, t4)
751
2485.8.39 by Vincent Ladeuil
Add tests around connection reuse.
752
        t5 = get_transport('http://foo/path')
753
        t6 = get_transport('http://foo/path/', possible_transports=[t5])
754
        self.assertIs(t5, t6)
2476.3.5 by Vincent Ladeuil
Naive implementation of transport reuse by Transport.get_transport().
755
756
    def test_don_t_reuse_different_transport(self):
2485.8.39 by Vincent Ladeuil
Add tests around connection reuse.
757
        t1 = get_transport('http://foo/path')
758
        t2 = get_transport('http://bar/path', possible_transports=[t1])
2485.8.40 by Vincent Ladeuil
Fix typo.
759
        self.assertIsNot(t1, t2)
2476.3.13 by Vincent Ladeuil
merge bzr.dev@2495
760
761
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
762
class TestTransportTrace(TestCase):
763
764
    def test_get(self):
765
        transport = get_transport('trace+memory://')
766
        self.assertIsInstance(
767
            transport, bzrlib.transport.trace.TransportTraceDecorator)
768
769
    def test_clone_preserves_activity(self):
770
        transport = get_transport('trace+memory://')
771
        transport2 = transport.clone('.')
772
        self.assertTrue(transport is not transport2)
773
        self.assertTrue(transport._activity is transport2._activity)
774
775
    # the following specific tests are for the operations that have made use of
776
    # logging in tests; we could test every single operation but doing that
777
    # still won't cause a test failure when the top level Transport API
778
    # changes; so there is little return doing that.
779
    def test_get(self):
780
        transport = get_transport('trace+memory:///')
781
        transport.put_bytes('foo', 'barish')
782
        transport.get('foo')
783
        expected_result = []
784
        # put_bytes records the bytes, not the content to avoid memory
785
        # pressure.
786
        expected_result.append(('put_bytes', 'foo', 6, None))
787
        # get records the file name only.
788
        expected_result.append(('get', 'foo'))
789
        self.assertEqual(expected_result, transport._activity)
790
791
    def test_readv(self):
792
        transport = get_transport('trace+memory:///')
793
        transport.put_bytes('foo', 'barish')
794
        list(transport.readv('foo', [(0, 1), (3, 2)], adjust_for_latency=True,
795
            upper_limit=6))
796
        expected_result = []
797
        # put_bytes records the bytes, not the content to avoid memory
798
        # pressure.
799
        expected_result.append(('put_bytes', 'foo', 6, None))
800
        # readv records the supplied offset request
801
        expected_result.append(('readv', 'foo', [(0, 1), (3, 2)], True, 6))
802
        self.assertEqual(expected_result, transport._activity)