/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1
# Copyright (C) 2005-2011, 2015, 2016 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
6015.50.1 by Martin Pool
Use a chmod wrapper to cope with eperm from chmod
18
import errno
6039.1.6 by Jelmer Vernooij
Add more tests.
19
import os
4700.1.1 by Robert Collins
Focus and move out of blackbox the acceptance test for bzr+ssh connection handshake/process spawning.
20
import subprocess
21
import sys
22
import threading
1442.1.44 by Robert Collins
Many transport related tweaks:
23
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
24
from .. import (
2018.18.4 by Martin Pool
Change Transport.local_abspath to raise NotLocalUrl, and test.
25
    errors,
2804.4.1 by Alexander Belchenko
some win32-specific fixes for selftest
26
    osutils,
4700.1.1 by Robert Collins
Focus and move out of blackbox the acceptance test for bzr+ssh connection handshake/process spawning.
27
    tests,
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
28
    transport,
2018.18.4 by Martin Pool
Change Transport.local_abspath to raise NotLocalUrl, and test.
29
    urlutils,
30
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
31
from ..directory_service import directories
32
from ..sixish import (
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
33
    BytesIO,
34
    )
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
35
from ..transport import (
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
36
    chroot,
4946.1.2 by John Arbash Meinel
Clean up a few more imports.
37
    fakenfs,
4912.2.4 by Martin Pool
Add test for unhtml_roughly, and truncate at 1000 bytes
38
    http,
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
39
    local,
6030.2.2 by Jelmer Vernooij
Add test.
40
    location_to_url,
4634.108.13 by John Arbash Meinel
Add a test case.
41
    memory,
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
42
    pathfilter,
4946.1.2 by John Arbash Meinel
Clean up a few more imports.
43
    readonly,
4634.108.13 by John Arbash Meinel
Add a test case.
44
    )
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
45
import breezy.transport.trace
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
46
from . import (
5017.3.22 by Vincent Ladeuil
selftest -s bt.test_transport passing
47
    features,
48
    test_server,
49
    )
1951.2.1 by Martin Pool
Change to using LocalURLServer for testing.
50
51
52
# 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.
53
54
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
55
class TestTransport(tests.TestCase):
1185.58.3 by John Arbash Meinel
code cleanup
56
    """Test the non transport-concrete class functionality."""
57
2241.3.1 by ghigo
uncomment test test__get_set_protocol_handlers
58
    def test__get_set_protocol_handlers(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
59
        handlers = transport._get_protocol_handlers()
6006.2.1 by Martin Pool
Clean up transport tests to use addCleanup
60
        self.assertNotEqual([], handlers.keys())
61
        transport._clear_protocol_handlers()
62
        self.addCleanup(transport._set_protocol_handlers, handlers)
63
        self.assertEqual([], transport._get_protocol_handlers().keys())
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.
64
65
    def test_get_transport_modules(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
66
        handlers = transport._get_protocol_handlers()
6006.2.1 by Martin Pool
Clean up transport tests to use addCleanup
67
        self.addCleanup(transport._set_protocol_handlers, handlers)
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
68
        # don't pollute the current handlers
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
69
        transport._clear_protocol_handlers()
6006.2.2 by Martin Pool
pep8 cleanup of test_transport
70
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.
71
        class SampleHandler(object):
72
            """I exist, isnt that enough?"""
6006.2.1 by Martin Pool
Clean up transport tests to use addCleanup
73
        transport._clear_protocol_handlers()
74
        transport.register_transport_proto('foo')
75
        transport.register_lazy_transport('foo',
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
76
                                            'breezy.tests.test_transport',
6006.2.1 by Martin Pool
Clean up transport tests to use addCleanup
77
                                            'TestTransport.SampleHandler')
78
        transport.register_transport_proto('bar')
79
        transport.register_lazy_transport('bar',
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
80
                                            'breezy.tests.test_transport',
6006.2.1 by Martin Pool
Clean up transport tests to use addCleanup
81
                                            'TestTransport.SampleHandler')
82
        self.assertEqual([SampleHandler.__module__,
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
83
                            'breezy.transport.chroot',
84
                            'breezy.transport.pathfilter'],
6006.2.1 by Martin Pool
Clean up transport tests to use addCleanup
85
                            transport._get_transport_modules())
1540.3.8 by Martin Pool
Some support for falling back between transport implementations.
86
87
    def test_transport_dependency(self):
88
        """Transport with missing dependency causes no error"""
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
89
        saved_handlers = transport._get_protocol_handlers()
6006.2.1 by Martin Pool
Clean up transport tests to use addCleanup
90
        self.addCleanup(transport._set_protocol_handlers, saved_handlers)
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
91
        # don't pollute the current handlers
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
92
        transport._clear_protocol_handlers()
6006.2.1 by Martin Pool
Clean up transport tests to use addCleanup
93
        transport.register_transport_proto('foo')
94
        transport.register_lazy_transport(
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
95
            'foo', 'breezy.tests.test_transport', 'BadTransportHandler')
1540.3.8 by Martin Pool
Some support for falling back between transport implementations.
96
        try:
6039.1.6 by Jelmer Vernooij
Add more tests.
97
            transport.get_transport_from_url('foo://fooserver/foo')
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
98
        except errors.UnsupportedProtocol as e:
6006.2.1 by Martin Pool
Clean up transport tests to use addCleanup
99
            e_str = str(e)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
100
            self.assertEqual('Unsupported protocol'
6006.2.1 by Martin Pool
Clean up transport tests to use addCleanup
101
                                ' for url "foo://fooserver/foo":'
102
                                ' Unable to import library "some_lib":'
103
                                ' testing missing dependency', str(e))
104
        else:
105
            self.fail('Did not raise UnsupportedProtocol')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
106
1540.3.10 by Martin Pool
[broken] keep hooking pycurl into test framework
107
    def test_transport_fallback(self):
108
        """Transport with missing dependency causes no error"""
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
109
        saved_handlers = transport._get_protocol_handlers()
6006.2.1 by Martin Pool
Clean up transport tests to use addCleanup
110
        self.addCleanup(transport._set_protocol_handlers, saved_handlers)
111
        transport._clear_protocol_handlers()
112
        transport.register_transport_proto('foo')
113
        transport.register_lazy_transport(
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
114
            'foo', 'breezy.tests.test_transport', 'BackupTransportHandler')
6006.2.1 by Martin Pool
Clean up transport tests to use addCleanup
115
        transport.register_lazy_transport(
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
116
            'foo', 'breezy.tests.test_transport', 'BadTransportHandler')
6039.1.6 by Jelmer Vernooij
Add more tests.
117
        t = transport.get_transport_from_url('foo://fooserver/foo')
6006.2.1 by Martin Pool
Clean up transport tests to use addCleanup
118
        self.assertTrue(isinstance(t, BackupTransportHandler))
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
119
4011.4.1 by Jelmer Vernooij
Point out bzr+ssh:// to the user when they use ssh://.
120
    def test_ssh_hints(self):
121
        """Transport ssh:// should raise an error pointing out bzr+ssh://"""
122
        try:
6039.1.6 by Jelmer Vernooij
Add more tests.
123
            transport.get_transport_from_url('ssh://fooserver/foo')
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
124
        except errors.UnsupportedProtocol as e:
4011.4.1 by Jelmer Vernooij
Point out bzr+ssh:// to the user when they use ssh://.
125
            e_str = str(e)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
126
            self.assertEqual('Unsupported protocol'
4011.4.1 by Jelmer Vernooij
Point out bzr+ssh:// to the user when they use ssh://.
127
                              ' for url "ssh://fooserver/foo":'
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
128
                              ' bzr supports bzr+ssh to operate over ssh,'
129
                              ' use "bzr+ssh://fooserver/foo".',
4011.4.1 by Jelmer Vernooij
Point out bzr+ssh:// to the user when they use ssh://.
130
                              str(e))
131
        else:
132
            self.fail('Did not raise UnsupportedProtocol')
133
2052.6.1 by Robert Collins
``Transport.get`` has had its interface made more clear for ease of use.
134
    def test_LateReadError(self):
135
        """The LateReadError helper should raise on read()."""
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
136
        a_file = transport.LateReadError('a path')
2052.6.1 by Robert Collins
``Transport.get`` has had its interface made more clear for ease of use.
137
        try:
138
            a_file.read()
6619.3.2 by Jelmer Vernooij
Apply 2to3 except fix.
139
        except errors.ReadError as error:
2052.6.1 by Robert Collins
``Transport.get`` has had its interface made more clear for ease of use.
140
            self.assertEqual('a path', error.path)
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
141
        self.assertRaises(errors.ReadError, a_file.read, 40)
2052.6.1 by Robert Collins
``Transport.get`` has had its interface made more clear for ease of use.
142
        a_file.close()
143
2018.18.4 by Martin Pool
Change Transport.local_abspath to raise NotLocalUrl, and test.
144
    def test_local_abspath_non_local_transport(self):
145
        # the base implementation should throw
4634.108.13 by John Arbash Meinel
Add a test case.
146
        t = memory.MemoryTransport()
2018.18.4 by Martin Pool
Change Transport.local_abspath to raise NotLocalUrl, and test.
147
        e = self.assertRaises(errors.NotLocalUrl, t.local_abspath, 't')
148
        self.assertEqual('memory:///t is not a local path.', str(e))
149
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
150
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
151
class TestCoalesceOffsets(tests.TestCase):
3059.2.17 by Vincent Ladeuil
Limit GET requests by body size instead of number of ranges.
152
153
    def check(self, expected, offsets, limit=0, max_size=0, fudge=0):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
154
        coalesce = transport.Transport._coalesce_offsets
155
        exp = [transport._CoalescedOffset(*x) for x in expected]
3059.2.17 by Vincent Ladeuil
Limit GET requests by body size instead of number of ranges.
156
        out = list(coalesce(offsets, limit=limit, fudge_factor=fudge,
157
                            max_size=max_size))
1864.5.9 by John Arbash Meinel
Switch to returning an object to make the api more understandable.
158
        self.assertEqual(exp, out)
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
159
160
    def test_coalesce_empty(self):
161
        self.check([], [])
162
163
    def test_coalesce_simple(self):
164
        self.check([(0, 10, [(0, 10)])], [(0, 10)])
165
166
    def test_coalesce_unrelated(self):
167
        self.check([(0, 10, [(0, 10)]),
168
                    (20, 10, [(0, 10)]),
169
                   ], [(0, 10), (20, 10)])
3059.2.17 by Vincent Ladeuil
Limit GET requests by body size instead of number of ranges.
170
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
171
    def test_coalesce_unsorted(self):
172
        self.check([(20, 10, [(0, 10)]),
173
                    (0, 10, [(0, 10)]),
174
                   ], [(20, 10), (0, 10)])
175
176
    def test_coalesce_nearby(self):
177
        self.check([(0, 20, [(0, 10), (10, 10)])],
178
                   [(0, 10), (10, 10)])
179
180
    def test_coalesce_overlapped(self):
3686.1.9 by John Arbash Meinel
Overlapping ranges are not allowed anymore.
181
        self.assertRaises(ValueError,
182
            self.check, [(0, 15, [(0, 10), (5, 10)])],
183
                        [(0, 10), (5, 10)])
1864.5.1 by John Arbash Meinel
Change the readv combining algorithm for one that is easier to test.
184
185
    def test_coalesce_limit(self):
186
        self.check([(10, 50, [(0, 10), (10, 10), (20, 10),
187
                              (30, 10), (40, 10)]),
188
                    (60, 50, [(0, 10), (10, 10), (20, 10),
189
                              (30, 10), (40, 10)]),
190
                   ], [(10, 10), (20, 10), (30, 10), (40, 10),
191
                       (50, 10), (60, 10), (70, 10), (80, 10),
192
                       (90, 10), (100, 10)],
193
                    limit=5)
194
195
    def test_coalesce_no_limit(self):
196
        self.check([(10, 100, [(0, 10), (10, 10), (20, 10),
197
                               (30, 10), (40, 10), (50, 10),
198
                               (60, 10), (70, 10), (80, 10),
199
                               (90, 10)]),
200
                   ], [(10, 10), (20, 10), (30, 10), (40, 10),
201
                       (50, 10), (60, 10), (70, 10), (80, 10),
202
                       (90, 10), (100, 10)])
203
1864.5.3 by John Arbash Meinel
Allow collapsing ranges even if they are just 'close'
204
    def test_coalesce_fudge(self):
205
        self.check([(10, 30, [(0, 10), (20, 10)]),
6006.2.2 by Martin Pool
pep8 cleanup of test_transport
206
                    (100, 10, [(0, 10)]),
1864.5.3 by John Arbash Meinel
Allow collapsing ranges even if they are just 'close'
207
                   ], [(10, 10), (30, 10), (100, 10)],
6006.2.2 by Martin Pool
pep8 cleanup of test_transport
208
                   fudge=10)
209
3059.2.17 by Vincent Ladeuil
Limit GET requests by body size instead of number of ranges.
210
    def test_coalesce_max_size(self):
211
        self.check([(10, 20, [(0, 10), (10, 10)]),
212
                    (30, 50, [(0, 50)]),
213
                    # If one range is above max_size, it gets its own coalesced
214
                    # offset
6006.2.2 by Martin Pool
pep8 cleanup of test_transport
215
                    (100, 80, [(0, 80)]),],
3059.2.17 by Vincent Ladeuil
Limit GET requests by body size instead of number of ranges.
216
                   [(10, 10), (20, 10), (30, 50), (100, 80)],
6006.2.2 by Martin Pool
pep8 cleanup of test_transport
217
                   max_size=50)
3059.2.17 by Vincent Ladeuil
Limit GET requests by body size instead of number of ranges.
218
219
    def test_coalesce_no_max_size(self):
6006.2.2 by Martin Pool
pep8 cleanup of test_transport
220
        self.check([(10, 170, [(0, 10), (10, 10), (20, 50), (70, 100)])],
3059.2.17 by Vincent Ladeuil
Limit GET requests by body size instead of number of ranges.
221
                   [(10, 10), (20, 10), (30, 50), (80, 100)],
222
                  )
1864.5.3 by John Arbash Meinel
Allow collapsing ranges even if they are just 'close'
223
3876.1.2 by John Arbash Meinel
Add a test case that checks the 100MB limit.
224
    def test_coalesce_default_limit(self):
225
        # By default we use a 100MB max size.
6006.2.2 by Martin Pool
pep8 cleanup of test_transport
226
        ten_mb = 10 * 1024 * 1024
227
        self.check([(0, 10 * ten_mb, [(i * ten_mb, ten_mb) for i in range(10)]),
3876.1.2 by John Arbash Meinel
Add a test case that checks the 100MB limit.
228
                    (10*ten_mb, ten_mb, [(0, ten_mb)])],
229
                   [(i*ten_mb, ten_mb) for i in range(11)])
6006.2.2 by Martin Pool
pep8 cleanup of test_transport
230
        self.check([(0, 11 * ten_mb, [(i * ten_mb, ten_mb) for i in range(11)])],
231
                   [(i * ten_mb, ten_mb) for i in range(11)],
3876.1.2 by John Arbash Meinel
Add a test case that checks the 100MB limit.
232
                   max_size=1*1024*1024*1024)
233
1540.3.3 by Martin Pool
Review updates of pycurl transport
234
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
235
class TestMemoryServer(tests.TestCase):
4634.108.13 by John Arbash Meinel
Add a test case.
236
237
    def test_create_server(self):
5017.3.45 by Vincent Ladeuil
Move MemoryServer back into bzrlib.transport.memory as it's needed as soon as a MemoryTransport is used. Add a NEWS entry.
238
        server = memory.MemoryServer()
4946.1.2 by John Arbash Meinel
Clean up a few more imports.
239
        server.start_server()
4634.108.13 by John Arbash Meinel
Add a test case.
240
        url = server.get_url()
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
241
        self.assertTrue(url in transport.transport_list_registry)
6039.1.6 by Jelmer Vernooij
Add more tests.
242
        t = transport.get_transport_from_url(url)
4634.108.13 by John Arbash Meinel
Add a test case.
243
        del t
4946.1.2 by John Arbash Meinel
Clean up a few more imports.
244
        server.stop_server()
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
245
        self.assertFalse(url in transport.transport_list_registry)
4634.108.13 by John Arbash Meinel
Add a test case.
246
        self.assertRaises(errors.UnsupportedProtocol,
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
247
                          transport.get_transport, url)
248
249
250
class TestMemoryTransport(tests.TestCase):
1442.1.44 by Robert Collins
Many transport related tweaks:
251
252
    def test_get_transport(self):
4634.108.13 by John Arbash Meinel
Add a test case.
253
        memory.MemoryTransport()
1442.1.44 by Robert Collins
Many transport related tweaks:
254
255
    def test_clone(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
256
        t = memory.MemoryTransport()
257
        self.assertTrue(isinstance(t, memory.MemoryTransport))
258
        self.assertEqual("memory:///", t.clone("/").base)
1442.1.44 by Robert Collins
Many transport related tweaks:
259
260
    def test_abspath(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
261
        t = memory.MemoryTransport()
262
        self.assertEqual("memory:///relpath", t.abspath('relpath'))
1442.1.44 by Robert Collins
Many transport related tweaks:
263
1910.15.1 by Andrew Bennetts
More tests for abspath and clone behaviour
264
    def test_abspath_of_root(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
265
        t = memory.MemoryTransport()
266
        self.assertEqual("memory:///", t.base)
267
        self.assertEqual("memory:///", t.abspath('/'))
1910.15.1 by Andrew Bennetts
More tests for abspath and clone behaviour
268
2070.3.1 by Andrew Bennetts
Fix memory_transport.abspath('/foo')
269
    def test_abspath_of_relpath_starting_at_root(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
270
        t = memory.MemoryTransport()
271
        self.assertEqual("memory:///foo", t.abspath('/foo'))
1442.1.44 by Robert Collins
Many transport related tweaks:
272
273
    def test_append_and_get(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
274
        t = memory.MemoryTransport()
275
        t.append_bytes('path', 'content')
276
        self.assertEqual(t.get('path').read(), 'content')
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
277
        t.append_file('path', BytesIO(b'content'))
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
278
        self.assertEqual(t.get('path').read(), 'contentcontent')
1442.1.44 by Robert Collins
Many transport related tweaks:
279
280
    def test_put_and_get(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
281
        t = memory.MemoryTransport()
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
282
        t.put_file('path', BytesIO(b'content'))
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
283
        self.assertEqual(t.get('path').read(), 'content')
284
        t.put_bytes('path', 'content')
285
        self.assertEqual(t.get('path').read(), 'content')
1442.1.44 by Robert Collins
Many transport related tweaks:
286
287
    def test_append_without_dir_fails(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
288
        t = memory.MemoryTransport()
289
        self.assertRaises(errors.NoSuchFile,
290
                          t.append_bytes, 'dir/path', 'content')
1442.1.44 by Robert Collins
Many transport related tweaks:
291
292
    def test_put_without_dir_fails(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
293
        t = memory.MemoryTransport()
294
        self.assertRaises(errors.NoSuchFile,
6621.22.2 by Martin
Use BytesIO or StringIO from bzrlib.sixish
295
                          t.put_file, 'dir/path', BytesIO(b'content'))
1442.1.44 by Robert Collins
Many transport related tweaks:
296
297
    def test_get_missing(self):
4634.108.13 by John Arbash Meinel
Add a test case.
298
        transport = memory.MemoryTransport()
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
299
        self.assertRaises(errors.NoSuchFile, transport.get, 'foo')
1442.1.44 by Robert Collins
Many transport related tweaks:
300
301
    def test_has_missing(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
302
        t = memory.MemoryTransport()
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
303
        self.assertEqual(False, t.has('foo'))
1442.1.44 by Robert Collins
Many transport related tweaks:
304
305
    def test_has_present(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
306
        t = memory.MemoryTransport()
307
        t.append_bytes('foo', 'content')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
308
        self.assertEqual(True, t.has('foo'))
1442.1.44 by Robert Collins
Many transport related tweaks:
309
2120.3.1 by John Arbash Meinel
Fix MemoryTransport.list_dir() implementation, and update tests
310
    def test_list_dir(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
311
        t = memory.MemoryTransport()
312
        t.put_bytes('foo', 'content')
313
        t.mkdir('dir')
314
        t.put_bytes('dir/subfoo', 'content')
315
        t.put_bytes('dirlike', 'content')
2120.3.1 by John Arbash Meinel
Fix MemoryTransport.list_dir() implementation, and update tests
316
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
317
        self.assertEqual(['dir', 'dirlike', 'foo'], sorted(t.list_dir('.')))
318
        self.assertEqual(['subfoo'], sorted(t.list_dir('dir')))
2120.3.1 by John Arbash Meinel
Fix MemoryTransport.list_dir() implementation, and update tests
319
1442.1.44 by Robert Collins
Many transport related tweaks:
320
    def test_mkdir(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
321
        t = memory.MemoryTransport()
322
        t.mkdir('dir')
323
        t.append_bytes('dir/path', 'content')
324
        self.assertEqual(t.get('dir/path').read(), 'content')
1442.1.44 by Robert Collins
Many transport related tweaks:
325
326
    def test_mkdir_missing_parent(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
327
        t = memory.MemoryTransport()
328
        self.assertRaises(errors.NoSuchFile, t.mkdir, 'dir/dir')
1442.1.44 by Robert Collins
Many transport related tweaks:
329
330
    def test_mkdir_twice(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
331
        t = memory.MemoryTransport()
332
        t.mkdir('dir')
333
        self.assertRaises(errors.FileExists, t.mkdir, 'dir')
1530.1.5 by Robert Collins
Reinstate Memory parameter tests.
334
335
    def test_parameters(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
336
        t = memory.MemoryTransport()
337
        self.assertEqual(True, t.listable())
338
        self.assertEqual(False, t.is_readonly())
1442.1.44 by Robert Collins
Many transport related tweaks:
339
340
    def test_iter_files_recursive(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
341
        t = memory.MemoryTransport()
342
        t.mkdir('dir')
343
        t.put_bytes('dir/foo', 'content')
344
        t.put_bytes('dir/bar', 'content')
345
        t.put_bytes('bar', 'content')
346
        paths = set(t.iter_files_recursive())
6619.3.12 by Jelmer Vernooij
Use 2to3 set_literal fixer.
347
        self.assertEqual({'dir/foo', 'dir/bar', 'bar'}, paths)
1442.1.44 by Robert Collins
Many transport related tweaks:
348
349
    def test_stat(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
350
        t = memory.MemoryTransport()
351
        t.put_bytes('foo', 'content')
352
        t.put_bytes('bar', 'phowar')
353
        self.assertEqual(7, t.stat('foo').st_size)
354
        self.assertEqual(6, t.stat('bar').st_size)
355
356
357
class ChrootDecoratorTransportTest(tests.TestCase):
2070.5.1 by Andrew Bennetts
Add ChrootTransportDecorator.
358
    """Chroot decoration specific tests."""
359
2018.5.54 by Andrew Bennetts
Fix ChrootTransportDecorator's abspath method to be consistent with its clone
360
    def test_abspath(self):
361
        # The abspath is always relative to the chroot_url.
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
362
        server = chroot.ChrootServer(
6039.1.6 by Jelmer Vernooij
Add more tests.
363
            transport.get_transport_from_url('memory:///foo/bar/'))
4659.1.2 by Robert Collins
Refactor creation and shutdown of test servers to use a common helper,
364
        self.start_server(server)
6039.1.6 by Jelmer Vernooij
Add more tests.
365
        t = transport.get_transport_from_url(server.get_url())
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
366
        self.assertEqual(server.get_url(), t.abspath('/'))
2018.5.54 by Andrew Bennetts
Fix ChrootTransportDecorator's abspath method to be consistent with its clone
367
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
368
        subdir_t = t.clone('subdir')
369
        self.assertEqual(server.get_url(), subdir_t.abspath('/'))
2379.2.1 by Robert Collins
Rewritten chroot transport that prevents accidental chroot escapes when
370
371
    def test_clone(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
372
        server = chroot.ChrootServer(
6039.1.6 by Jelmer Vernooij
Add more tests.
373
            transport.get_transport_from_url('memory:///foo/bar/'))
4659.1.2 by Robert Collins
Refactor creation and shutdown of test servers to use a common helper,
374
        self.start_server(server)
6039.1.6 by Jelmer Vernooij
Add more tests.
375
        t = transport.get_transport_from_url(server.get_url())
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
376
        # relpath from root and root path are the same
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
377
        relpath_cloned = t.clone('foo')
378
        abspath_cloned = t.clone('/foo')
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
379
        self.assertEqual(server, relpath_cloned.server)
380
        self.assertEqual(server, abspath_cloned.server)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
381
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
382
    def test_chroot_url_preserves_chroot(self):
383
        """Calling get_transport on a chroot transport's base should produce a
384
        transport with exactly the same behaviour as the original chroot
385
        transport.
386
387
        This is so that it is not possible to escape a chroot by doing::
388
            url = chroot_transport.base
389
            parent_url = urlutils.join(url, '..')
6039.1.6 by Jelmer Vernooij
Add more tests.
390
            new_t = transport.get_transport_from_url(parent_url)
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
391
        """
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
392
        server = chroot.ChrootServer(
6039.1.6 by Jelmer Vernooij
Add more tests.
393
            transport.get_transport_from_url('memory:///path/subpath'))
4659.1.2 by Robert Collins
Refactor creation and shutdown of test servers to use a common helper,
394
        self.start_server(server)
6039.1.6 by Jelmer Vernooij
Add more tests.
395
        t = transport.get_transport_from_url(server.get_url())
396
        new_t = transport.get_transport_from_url(t.base)
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
397
        self.assertEqual(t.server, new_t.server)
398
        self.assertEqual(t.base, new_t.base)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
399
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
400
    def test_urljoin_preserves_chroot(self):
401
        """Using urlutils.join(url, '..') on a chroot URL should not produce a
402
        URL that escapes the intended chroot.
403
404
        This is so that it is not possible to escape a chroot by doing::
405
            url = chroot_transport.base
406
            parent_url = urlutils.join(url, '..')
6039.1.6 by Jelmer Vernooij
Add more tests.
407
            new_t = transport.get_transport_from_url(parent_url)
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
408
        """
6006.2.2 by Martin Pool
pep8 cleanup of test_transport
409
        server = chroot.ChrootServer(
6039.1.6 by Jelmer Vernooij
Add more tests.
410
            transport.get_transport_from_url('memory:///path/'))
4659.1.2 by Robert Collins
Refactor creation and shutdown of test servers to use a common helper,
411
        self.start_server(server)
6039.1.6 by Jelmer Vernooij
Add more tests.
412
        t = transport.get_transport_from_url(server.get_url())
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
413
        self.assertRaises(
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
414
            errors.InvalidURLJoin, urlutils.join, t.base, '..')
415
416
417
class TestChrootServer(tests.TestCase):
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
418
419
    def test_construct(self):
4634.108.13 by John Arbash Meinel
Add a test case.
420
        backing_transport = memory.MemoryTransport()
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
421
        server = chroot.ChrootServer(backing_transport)
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
422
        self.assertEqual(backing_transport, server.backing_transport)
423
424
    def test_setUp(self):
4634.108.13 by John Arbash Meinel
Add a test case.
425
        backing_transport = memory.MemoryTransport()
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
426
        server = chroot.ChrootServer(backing_transport)
4934.3.3 by Martin Pool
Rename Server.setUp to Server.start_server
427
        server.start_server()
6006.2.1 by Martin Pool
Clean up transport tests to use addCleanup
428
        self.addCleanup(server.stop_server)
429
        self.assertTrue(server.scheme
430
                        in transport._get_protocol_handlers().keys())
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
431
4934.3.1 by Martin Pool
Rename Server.tearDown to .stop_server
432
    def test_stop_server(self):
4634.108.13 by John Arbash Meinel
Add a test case.
433
        backing_transport = memory.MemoryTransport()
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
434
        server = chroot.ChrootServer(backing_transport)
4934.3.3 by Martin Pool
Rename Server.setUp to Server.start_server
435
        server.start_server()
4934.3.1 by Martin Pool
Rename Server.tearDown to .stop_server
436
        server.stop_server()
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
437
        self.assertFalse(server.scheme
438
                         in transport._get_protocol_handlers().keys())
2018.5.104 by Andrew Bennetts
Completely rework chrooted transports.
439
440
    def test_get_url(self):
4634.108.13 by John Arbash Meinel
Add a test case.
441
        backing_transport = memory.MemoryTransport()
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
442
        server = chroot.ChrootServer(backing_transport)
4934.3.3 by Martin Pool
Rename Server.setUp to Server.start_server
443
        server.start_server()
6006.2.1 by Martin Pool
Clean up transport tests to use addCleanup
444
        self.addCleanup(server.stop_server)
445
        self.assertEqual('chroot-%d:///' % id(server), server.get_url())
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
5436.3.1 by Martin
Create new post_connect hook for transports
448
class TestHooks(tests.TestCase):
449
    """Basic tests for transport hooks"""
450
451
    def _get_connected_transport(self):
452
        return transport.ConnectedTransport("bogus:nowhere")
453
454
    def test_transporthooks_initialisation(self):
5436.3.5 by Martin
Ahem, whitespace fix
455
        """Check all expected transport hook points are set up"""
456
        hookpoint = transport.TransportHooks()
457
        self.assertTrue("post_connect" in hookpoint,
458
            "post_connect not in %s" % (hookpoint,))
5436.3.1 by Martin
Create new post_connect hook for transports
459
460
    def test_post_connect(self):
5436.3.5 by Martin
Ahem, whitespace fix
461
        """Ensure the post_connect hook is called when _set_transport is"""
462
        calls = []
463
        transport.Transport.hooks.install_named_hook("post_connect",
464
            calls.append, None)
5436.3.1 by Martin
Create new post_connect hook for transports
465
        t = self._get_connected_transport()
466
        self.assertLength(0, calls)
467
        t._set_connection("connection", "auth")
468
        self.assertEqual(calls, [t])
469
470
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
471
class PathFilteringDecoratorTransportTest(tests.TestCase):
4634.44.1 by Andrew Bennetts
First draft of a generic path-filtering transport decorator.
472
    """Pathfilter decoration specific tests."""
473
474
    def test_abspath(self):
475
        # The abspath is always relative to the base of the backing transport.
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
476
        server = pathfilter.PathFilteringServer(
6039.1.6 by Jelmer Vernooij
Add more tests.
477
            transport.get_transport_from_url('memory:///foo/bar/'),
4634.44.1 by Andrew Bennetts
First draft of a generic path-filtering transport decorator.
478
            lambda x: x)
4934.3.3 by Martin Pool
Rename Server.setUp to Server.start_server
479
        server.start_server()
6039.1.6 by Jelmer Vernooij
Add more tests.
480
        t = transport.get_transport_from_url(server.get_url())
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
481
        self.assertEqual(server.get_url(), t.abspath('/'))
4634.44.1 by Andrew Bennetts
First draft of a generic path-filtering transport decorator.
482
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
483
        subdir_t = t.clone('subdir')
484
        self.assertEqual(server.get_url(), subdir_t.abspath('/'))
4934.3.1 by Martin Pool
Rename Server.tearDown to .stop_server
485
        server.stop_server()
4634.44.1 by Andrew Bennetts
First draft of a generic path-filtering transport decorator.
486
487
    def make_pf_transport(self, filter_func=None):
488
        """Make a PathFilteringTransport backed by a MemoryTransport.
6006.2.2 by Martin Pool
pep8 cleanup of test_transport
489
4634.44.1 by Andrew Bennetts
First draft of a generic path-filtering transport decorator.
490
        :param filter_func: by default this will be a no-op function.  Use this
491
            parameter to override it."""
492
        if filter_func is None:
493
            filter_func = lambda x: x
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
494
        server = pathfilter.PathFilteringServer(
6039.1.6 by Jelmer Vernooij
Add more tests.
495
            transport.get_transport_from_url('memory:///foo/bar/'), filter_func)
4934.3.3 by Martin Pool
Rename Server.setUp to Server.start_server
496
        server.start_server()
4934.3.1 by Martin Pool
Rename Server.tearDown to .stop_server
497
        self.addCleanup(server.stop_server)
6039.1.6 by Jelmer Vernooij
Add more tests.
498
        return transport.get_transport_from_url(server.get_url())
4634.44.1 by Andrew Bennetts
First draft of a generic path-filtering transport decorator.
499
500
    def test__filter(self):
501
        # _filter (with an identity func as filter_func) always returns
502
        # paths relative to the base of the backing transport.
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
503
        t = self.make_pf_transport()
504
        self.assertEqual('foo', t._filter('foo'))
505
        self.assertEqual('foo/bar', t._filter('foo/bar'))
506
        self.assertEqual('', t._filter('..'))
507
        self.assertEqual('', t._filter('/'))
4634.44.1 by Andrew Bennetts
First draft of a generic path-filtering transport decorator.
508
        # The base of the pathfiltering transport is taken into account too.
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
509
        t = t.clone('subdir1/subdir2')
510
        self.assertEqual('subdir1/subdir2/foo', t._filter('foo'))
511
        self.assertEqual('subdir1/subdir2/foo/bar', t._filter('foo/bar'))
512
        self.assertEqual('subdir1', t._filter('..'))
513
        self.assertEqual('', t._filter('/'))
4634.44.1 by Andrew Bennetts
First draft of a generic path-filtering transport decorator.
514
4634.44.2 by Andrew Bennetts
Add another test.
515
    def test_filter_invocation(self):
516
        filter_log = []
6006.2.2 by Martin Pool
pep8 cleanup of test_transport
517
4634.44.2 by Andrew Bennetts
Add another test.
518
        def filter(path):
519
            filter_log.append(path)
520
            return path
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
521
        t = self.make_pf_transport(filter)
522
        t.has('abc')
4634.44.2 by Andrew Bennetts
Add another test.
523
        self.assertEqual(['abc'], filter_log)
524
        del filter_log[:]
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
525
        t.clone('abc').has('xyz')
4634.44.2 by Andrew Bennetts
Add another test.
526
        self.assertEqual(['abc/xyz'], filter_log)
527
        del filter_log[:]
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
528
        t.has('/abc')
4634.44.2 by Andrew Bennetts
Add another test.
529
        self.assertEqual(['abc'], filter_log)
530
4634.44.1 by Andrew Bennetts
First draft of a generic path-filtering transport decorator.
531
    def test_clone(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
532
        t = self.make_pf_transport()
4634.44.2 by Andrew Bennetts
Add another test.
533
        # relpath from root and root path are the same
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
534
        relpath_cloned = t.clone('foo')
535
        abspath_cloned = t.clone('/foo')
536
        self.assertEqual(t.server, relpath_cloned.server)
537
        self.assertEqual(t.server, abspath_cloned.server)
4634.44.1 by Andrew Bennetts
First draft of a generic path-filtering transport decorator.
538
539
    def test_url_preserves_pathfiltering(self):
540
        """Calling get_transport on a pathfiltered transport's base should
541
        produce a transport with exactly the same behaviour as the original
542
        pathfiltered transport.
543
544
        This is so that it is not possible to escape (accidentally or
545
        otherwise) the filtering by doing::
546
            url = filtered_transport.base
547
            parent_url = urlutils.join(url, '..')
6039.1.6 by Jelmer Vernooij
Add more tests.
548
            new_t = transport.get_transport_from_url(parent_url)
4634.44.1 by Andrew Bennetts
First draft of a generic path-filtering transport decorator.
549
        """
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
550
        t = self.make_pf_transport()
6039.1.6 by Jelmer Vernooij
Add more tests.
551
        new_t = transport.get_transport_from_url(t.base)
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
552
        self.assertEqual(t.server, new_t.server)
553
        self.assertEqual(t.base, new_t.base)
554
555
556
class ReadonlyDecoratorTransportTest(tests.TestCase):
1534.4.9 by Robert Collins
Add a readonly decorator for transports.
557
    """Readonly decoration specific tests."""
558
559
    def test_local_parameters(self):
560
        # connect to . in readonly mode
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
561
        t = readonly.ReadonlyTransportDecorator('readonly+.')
562
        self.assertEqual(True, t.listable())
563
        self.assertEqual(True, t.is_readonly())
1534.4.9 by Robert Collins
Add a readonly decorator for transports.
564
565
    def test_http_parameters(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
566
        from breezy.tests.http_server import HttpServer
2929.3.7 by Vincent Ladeuil
Rename bzrlib/test/HttpServer.py to bzrlib/tests/http_server.py and fix uses.
567
        # connect to '.' via http which is not listable
1534.4.9 by Robert Collins
Add a readonly decorator for transports.
568
        server = HttpServer()
4659.1.2 by Robert Collins
Refactor creation and shutdown of test servers to use a common helper,
569
        self.start_server(server)
6039.1.6 by Jelmer Vernooij
Add more tests.
570
        t = transport.get_transport_from_url('readonly+' + server.get_url())
5784.1.1 by Martin Pool
Stop using failIf, failUnless, etc
571
        self.assertIsInstance(t, readonly.ReadonlyTransportDecorator)
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
572
        self.assertEqual(False, t.listable())
573
        self.assertEqual(True, t.is_readonly())
574
575
576
class FakeNFSDecoratorTests(tests.TestCaseInTempDir):
1558.10.2 by Robert Collins
Refactor the FakeNFS support into a TransportDecorator.
577
    """NFS decorator specific tests."""
578
579
    def get_nfs_transport(self, url):
580
        # connect to url with nfs decoration
581
        return fakenfs.FakeNFSTransportDecorator('fakenfs+' + url)
582
583
    def test_local_parameters(self):
2701.1.1 by Martin Pool
Remove Transport.should_cache.
584
        # the listable and is_readonly parameters
1558.10.2 by Robert Collins
Refactor the FakeNFS support into a TransportDecorator.
585
        # are not changed by the fakenfs decorator
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
586
        t = self.get_nfs_transport('.')
587
        self.assertEqual(True, t.listable())
588
        self.assertEqual(False, t.is_readonly())
1558.10.2 by Robert Collins
Refactor the FakeNFS support into a TransportDecorator.
589
590
    def test_http_parameters(self):
2701.1.1 by Martin Pool
Remove Transport.should_cache.
591
        # the listable and is_readonly parameters
1558.10.2 by Robert Collins
Refactor the FakeNFS support into a TransportDecorator.
592
        # are not changed by the fakenfs decorator
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
593
        from breezy.tests.http_server import HttpServer
2929.3.7 by Vincent Ladeuil
Rename bzrlib/test/HttpServer.py to bzrlib/tests/http_server.py and fix uses.
594
        # connect to '.' via http which is not listable
1558.10.2 by Robert Collins
Refactor the FakeNFS support into a TransportDecorator.
595
        server = HttpServer()
4659.1.2 by Robert Collins
Refactor creation and shutdown of test servers to use a common helper,
596
        self.start_server(server)
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
597
        t = self.get_nfs_transport(server.get_url())
598
        self.assertIsInstance(t, fakenfs.FakeNFSTransportDecorator)
599
        self.assertEqual(False, t.listable())
600
        self.assertEqual(True, t.is_readonly())
1558.10.2 by Robert Collins
Refactor the FakeNFS support into a TransportDecorator.
601
602
    def test_fakenfs_server_default(self):
603
        # a FakeNFSServer() should bring up a local relpath server for itself
5017.3.22 by Vincent Ladeuil
selftest -s bt.test_transport passing
604
        server = test_server.FakeNFSServer()
4659.1.2 by Robert Collins
Refactor creation and shutdown of test servers to use a common helper,
605
        self.start_server(server)
606
        # the url should be decorated appropriately
607
        self.assertStartsWith(server.get_url(), 'fakenfs+')
608
        # and we should be able to get a transport for it
6039.1.6 by Jelmer Vernooij
Add more tests.
609
        t = transport.get_transport_from_url(server.get_url())
4659.1.2 by Robert Collins
Refactor creation and shutdown of test servers to use a common helper,
610
        # which must be a FakeNFSTransportDecorator instance.
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
611
        self.assertIsInstance(t, fakenfs.FakeNFSTransportDecorator)
1558.10.2 by Robert Collins
Refactor the FakeNFS support into a TransportDecorator.
612
613
    def test_fakenfs_rename_semantics(self):
614
        # a FakeNFS transport must mangle the way rename errors occur to
615
        # look like NFS problems.
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
616
        t = self.get_nfs_transport('.')
1558.10.2 by Robert Collins
Refactor the FakeNFS support into a TransportDecorator.
617
        self.build_tree(['from/', 'from/foo', 'to/', 'to/bar'],
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
618
                        transport=t)
619
        self.assertRaises(errors.ResourceBusy, t.rename, 'from', 'to')
620
621
622
class FakeVFATDecoratorTests(tests.TestCaseInTempDir):
1608.2.4 by Martin Pool
[broken] Add FakeFVATTransport
623
    """Tests for simulation of VFAT restrictions"""
624
625
    def get_vfat_transport(self, url):
626
        """Return vfat-backed transport for test directory"""
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
627
        from breezy.transport.fakevfat import FakeVFATTransportDecorator
1608.2.4 by Martin Pool
[broken] Add FakeFVATTransport
628
        return FakeVFATTransportDecorator('vfat+' + url)
629
630
    def test_transport_creation(self):
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
631
        from breezy.transport.fakevfat import FakeVFATTransportDecorator
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
632
        t = self.get_vfat_transport('.')
633
        self.assertIsInstance(t, FakeVFATTransportDecorator)
1608.2.4 by Martin Pool
[broken] Add FakeFVATTransport
634
635
    def test_transport_mkdir(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
636
        t = self.get_vfat_transport('.')
637
        t.mkdir('HELLO')
638
        self.assertTrue(t.has('hello'))
639
        self.assertTrue(t.has('Hello'))
1608.2.4 by Martin Pool
[broken] Add FakeFVATTransport
640
1608.2.11 by Martin Pool
(FakeVFAT) add test for detection of invalid characters
641
    def test_forbidden_chars(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
642
        t = self.get_vfat_transport('.')
643
        self.assertRaises(ValueError, t.has, "<NU>")
644
645
646
class BadTransportHandler(transport.Transport):
1540.3.8 by Martin Pool
Some support for falling back between transport implementations.
647
    def __init__(self, base_url):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
648
        raise errors.DependencyNotPresent('some_lib',
649
                                          'testing missing dependency')
650
651
652
class BackupTransportHandler(transport.Transport):
1540.3.8 by Martin Pool
Some support for falling back between transport implementations.
653
    """Test transport that works as a backup for the BadTransportHandler"""
1540.3.10 by Martin Pool
[broken] keep hooking pycurl into test framework
654
    pass
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
655
656
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
657
class TestTransportImplementation(tests.TestCaseInTempDir):
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
658
    """Implementation verification for transports.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
659
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
660
    To verify a transport we need a server factory, which is a callable
661
    that accepts no parameters and returns an implementation of
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
662
    breezy.transport.Server.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
663
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
664
    That Server is then used to construct transport instances and test
665
    the transport via loopback activity.
666
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
667
    Currently this assumes that the Transport object is connected to the
668
    current working directory.  So that whatever is done
669
    through the transport, should show up in the working
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
670
    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
671
    URL schemes which provide access to something that may not be
672
    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.
673
    due to it being a database or some other non-filesystem tool.
674
675
    This also tests to make sure that the functions work with both
676
    generators and lists (assuming iter(list) is effectively a generator)
677
    """
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
678
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
679
    def setUp(self):
680
        super(TestTransportImplementation, self).setUp()
681
        self._server = self.transport_server()
4659.1.2 by Robert Collins
Refactor creation and shutdown of test servers to use a common helper,
682
        self.start_server(self._server)
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
683
2520.3.1 by Vincent Ladeuil
Fix 110448 by adding a relpath parameter to get_transport.
684
    def get_transport(self, relpath=None):
685
        """Return a connected transport to the local directory.
686
687
        :param relpath: a path relative to the base url.
688
        """
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
689
        base_url = self._server.get_url()
2520.3.1 by Vincent Ladeuil
Fix 110448 by adding a relpath parameter to get_transport.
690
        url = self._adjust_url(base_url, relpath)
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
691
        # try getting the transport via the regular interface:
6039.1.5 by Jelmer Vernooij
Add get_transport_from_url and get_transport_from_path functions.
692
        t = transport.get_transport_from_url(url)
2485.8.39 by Vincent Ladeuil
Add tests around connection reuse.
693
        # vila--20070607 if the following are commented out the test suite
694
        # still pass. Is this really still needed or was it a forgotten
695
        # temporary fix ?
1986.2.5 by Robert Collins
Unbreak transport tests.
696
        if not isinstance(t, self.transport_class):
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
697
            # we did not get the correct transport class type. Override the
698
            # regular connection behaviour by direct construction.
2520.3.1 by Vincent Ladeuil
Fix 110448 by adding a relpath parameter to get_transport.
699
            t = self.transport_class(url)
1871.1.2 by Robert Collins
Reduce code duplication in transport-parameterised tests.
700
        return t
1951.2.1 by Martin Pool
Change to using LocalURLServer for testing.
701
702
6039.1.6 by Jelmer Vernooij
Add more tests.
703
class TestTransportFromPath(tests.TestCaseInTempDir):
704
705
    def test_with_path(self):
706
        t = transport.get_transport_from_path(self.test_dir)
707
        self.assertIsInstance(t, local.LocalTransport)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
708
        self.assertEqual(t.base.rstrip("/"),
6039.1.6 by Jelmer Vernooij
Add more tests.
709
            urlutils.local_path_to_url(self.test_dir))
710
711
    def test_with_url(self):
712
        t = transport.get_transport_from_path("file:")
713
        self.assertIsInstance(t, local.LocalTransport)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
714
        self.assertEqual(t.base.rstrip("/"),
6039.1.6 by Jelmer Vernooij
Add more tests.
715
            urlutils.local_path_to_url(os.path.join(self.test_dir, "file:")))
716
717
718
class TestTransportFromUrl(tests.TestCaseInTempDir):
719
720
    def test_with_path(self):
721
        self.assertRaises(errors.InvalidURL, transport.get_transport_from_url,
722
            self.test_dir)
723
724
    def test_with_url(self):
725
        url = urlutils.local_path_to_url(self.test_dir)
726
        t = transport.get_transport_from_url(url)
727
        self.assertIsInstance(t, local.LocalTransport)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
728
        self.assertEqual(t.base.rstrip("/"), url)
6039.1.6 by Jelmer Vernooij
Add more tests.
729
5268.7.25 by Jelmer Vernooij
Make sure trailing slash is present.
730
    def test_with_url_and_segment_parameters(self):
731
        url = urlutils.local_path_to_url(self.test_dir)+",branch=foo"
732
        t = transport.get_transport_from_url(url)
733
        self.assertIsInstance(t, local.LocalTransport)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
734
        self.assertEqual(t.base.rstrip("/"), url)
5268.7.25 by Jelmer Vernooij
Make sure trailing slash is present.
735
        with open(os.path.join(self.test_dir, "afile"), 'w') as f:
736
            f.write("data")
737
        self.assertTrue(t.has("afile"))
738
6039.1.6 by Jelmer Vernooij
Add more tests.
739
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
740
class TestLocalTransports(tests.TestCase):
1951.2.1 by Martin Pool
Change to using LocalURLServer for testing.
741
742
    def test_get_transport_from_abspath(self):
2804.4.1 by Alexander Belchenko
some win32-specific fixes for selftest
743
        here = osutils.abspath('.')
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
744
        t = transport.get_transport(here)
745
        self.assertIsInstance(t, local.LocalTransport)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
746
        self.assertEqual(t.base, urlutils.local_path_to_url(here) + '/')
1951.2.1 by Martin Pool
Change to using LocalURLServer for testing.
747
748
    def test_get_transport_from_relpath(self):
2804.4.1 by Alexander Belchenko
some win32-specific fixes for selftest
749
        here = osutils.abspath('.')
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
750
        t = transport.get_transport('.')
751
        self.assertIsInstance(t, local.LocalTransport)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
752
        self.assertEqual(t.base, urlutils.local_path_to_url('.') + '/')
1951.2.1 by Martin Pool
Change to using LocalURLServer for testing.
753
754
    def test_get_transport_from_local_url(self):
2804.4.1 by Alexander Belchenko
some win32-specific fixes for selftest
755
        here = osutils.abspath('.')
1951.2.1 by Martin Pool
Change to using LocalURLServer for testing.
756
        here_url = urlutils.local_path_to_url(here) + '/'
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
757
        t = transport.get_transport(here_url)
758
        self.assertIsInstance(t, local.LocalTransport)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
759
        self.assertEqual(t.base, here_url)
2245.6.1 by Alexander Belchenko
win32 UNC path: recursive cloning UNC path to root stops on //HOST, not on //
760
2018.18.4 by Martin Pool
Change Transport.local_abspath to raise NotLocalUrl, and test.
761
    def test_local_abspath(self):
2804.4.1 by Alexander Belchenko
some win32-specific fixes for selftest
762
        here = osutils.abspath('.')
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
763
        t = transport.get_transport(here)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
764
        self.assertEqual(t.local_abspath(''), here)
2018.18.4 by Martin Pool
Change Transport.local_abspath to raise NotLocalUrl, and test.
765
2245.6.1 by Alexander Belchenko
win32 UNC path: recursive cloning UNC path to root stops on //HOST, not on //
766
6015.50.1 by Martin Pool
Use a chmod wrapper to cope with eperm from chmod
767
class TestLocalTransportMutation(tests.TestCaseInTempDir):
768
769
    def test_local_transport_mkdir(self):
770
        here = osutils.abspath('.')
771
        t = transport.get_transport(here)
772
        t.mkdir('test')
773
        self.assertTrue(os.path.exists('test'))
774
775
    def test_local_transport_mkdir_permission_denied(self):
776
        # See https://bugs.launchpad.net/bzr/+bug/606537
777
        here = osutils.abspath('.')
778
        t = transport.get_transport(here)
779
        def fake_chmod(path, mode):
780
            e = OSError('permission denied')
781
            e.errno = errno.EPERM
782
            raise e
783
        self.overrideAttr(os, 'chmod', fake_chmod)
784
        t.mkdir('test')
6619.3.14 by Jelmer Vernooij
Convert some octal numbers to new notations.
785
        t.mkdir('test2', mode=0o707)
6015.50.1 by Martin Pool
Use a chmod wrapper to cope with eperm from chmod
786
        self.assertTrue(os.path.exists('test'))
787
        self.assertTrue(os.path.exists('test2'))
788
789
6006.4.3 by Martin Pool
Add FileStream.fdatasync
790
class TestLocalTransportWriteStream(tests.TestCaseWithTransport):
791
792
    def test_local_fdatasync_calls_fdatasync(self):
793
        """Check fdatasync on a stream tries to flush the data to the OS.
794
        
795
        We can't easily observe the external effect but we can at least see
796
        it's called.
797
        """
6056.1.1 by Vincent Ladeuil
os.fdatasync is not defined on BSD-based OSes
798
        sentinel = object()
799
        fdatasync = getattr(os, 'fdatasync', sentinel)
800
        if fdatasync is sentinel:
801
            raise tests.TestNotApplicable('fdatasync not supported')
6006.4.3 by Martin Pool
Add FileStream.fdatasync
802
        t = self.get_transport('.')
803
        calls = self.recordCalls(os, 'fdatasync')
804
        w = t.open_write_stream('out')
805
        w.write('foo')
806
        w.fdatasync()
807
        with open('out', 'rb') as f:
808
            # Should have been flushed.
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
809
            self.assertEqual(f.read(), 'foo')
810
        self.assertEqual(len(calls), 1, calls)
6006.4.3 by Martin Pool
Add FileStream.fdatasync
811
6110.3.1 by Jelmer Vernooij
Raise NoSuchFile rather than IOError from open_write_stream when the target
812
    def test_missing_directory(self):
813
        t = self.get_transport('.')
814
        self.assertRaises(errors.NoSuchFile, t.open_write_stream, 'dir/foo')
815
6006.4.3 by Martin Pool
Add FileStream.fdatasync
816
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
817
class TestWin32LocalTransport(tests.TestCase):
2245.6.1 by Alexander Belchenko
win32 UNC path: recursive cloning UNC path to root stops on //HOST, not on //
818
819
    def test_unc_clone_to_root(self):
6603.1.4 by Vincent Ladeuil
Skip the missed test in test_transport.
820
        self.requireFeature(features.win32_feature)
2245.6.1 by Alexander Belchenko
win32 UNC path: recursive cloning UNC path to root stops on //HOST, not on //
821
        # Win32 UNC path like \\HOST\path
822
        # clone to root should stop at least at \\HOST part
823
        # not on \\
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
824
        t = local.EmulatedWin32LocalTransport('file://HOST/path/to/some/dir/')
6651.2.2 by Martin
Apply 2to3 xrange fix and fix up with sixish range
825
        for i in range(4):
2245.6.1 by Alexander Belchenko
win32 UNC path: recursive cloning UNC path to root stops on //HOST, not on //
826
            t = t.clone('..')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
827
        self.assertEqual(t.base, 'file://HOST/')
2245.6.1 by Alexander Belchenko
win32 UNC path: recursive cloning UNC path to root stops on //HOST, not on //
828
        # make sure we reach the root
829
        t = t.clone('..')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
830
        self.assertEqual(t.base, 'file://HOST/')
2477.1.7 by Martin Pool
test_transport must provide get_test_permutations
831
2485.8.61 by Vincent Ladeuil
From review comments, use a private scheme for testing.
832
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
833
class TestConnectedTransport(tests.TestCase):
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
834
    """Tests for connected to remote server transports"""
835
836
    def test_parse_url(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
837
        t = transport.ConnectedTransport(
838
            'http://simple.example.com/home/source')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
839
        self.assertEqual(t._parsed_url.host, 'simple.example.com')
840
        self.assertEqual(t._parsed_url.port, None)
841
        self.assertEqual(t._parsed_url.path, '/home/source/')
6055.2.1 by Jelmer Vernooij
Add UnparsedUrl.
842
        self.assertTrue(t._parsed_url.user is None)
843
        self.assertTrue(t._parsed_url.password is None)
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
844
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
845
        self.assertEqual(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.
846
3498.2.1 by Neil Martinsen-Burrell
Fix bug 228058: user names with @ signs should work
847
    def test_parse_url_with_at_in_user(self):
848
        # Bug 228058
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
849
        t = transport.ConnectedTransport('ftp://user@host.com@www.host.com/')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
850
        self.assertEqual(t._parsed_url.user, 'user@host.com')
3498.2.1 by Neil Martinsen-Burrell
Fix bug 228058: user names with @ signs should work
851
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
852
    def test_parse_quoted_url(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
853
        t = transport.ConnectedTransport(
854
            'http://ro%62ey:h%40t@ex%41mple.com:2222/path')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
855
        self.assertEqual(t._parsed_url.host, 'exAmple.com')
856
        self.assertEqual(t._parsed_url.port, 2222)
857
        self.assertEqual(t._parsed_url.user, 'robey')
858
        self.assertEqual(t._parsed_url.password, 'h@t')
859
        self.assertEqual(t._parsed_url.path, '/path/')
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
860
861
        # Base should not keep track of the password
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
862
        self.assertEqual(t.base, 'http://ro%62ey@ex%41mple.com:2222/path/')
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
863
864
    def test_parse_invalid_url(self):
865
        self.assertRaises(errors.InvalidURL,
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
866
                          transport.ConnectedTransport,
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
867
                          'sftp://lily.org:~janneke/public/bzr/gub')
868
869
    def test_relpath(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
870
        t = transport.ConnectedTransport('sftp://user@host.com/abs/path')
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
871
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
872
        self.assertEqual(t.relpath('sftp://user@host.com/abs/path/sub'),
6006.2.2 by Martin Pool
pep8 cleanup of test_transport
873
            'sub')
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
874
        self.assertRaises(errors.PathNotChild, t.relpath,
875
                          'http://user@host.com/abs/path/sub')
876
        self.assertRaises(errors.PathNotChild, t.relpath,
877
                          'sftp://user2@host.com/abs/path/sub')
878
        self.assertRaises(errors.PathNotChild, t.relpath,
879
                          'sftp://user@otherhost.com/abs/path/sub')
880
        self.assertRaises(errors.PathNotChild, t.relpath,
881
                          'sftp://user@host.com:33/abs/path/sub')
882
        # Make sure it works when we don't supply a username
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
883
        t = transport.ConnectedTransport('sftp://host.com/abs/path')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
884
        self.assertEqual(t.relpath('sftp://host.com/abs/path/sub'), 'sub')
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
885
886
        # Make sure it works when parts of the path will be url encoded
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
887
        t = transport.ConnectedTransport('sftp://host.com/dev/%path')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
888
        self.assertEqual(t.relpath('sftp://host.com/dev/%path/sub'), 'sub')
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
889
2485.8.32 by Vincent Ladeuil
Keep credentials used at connection creation for reconnection purposes.
890
    def test_connection_sharing_propagate_credentials(self):
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
891
        t = transport.ConnectedTransport('ftp://user@host.com/abs/path')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
892
        self.assertEqual('user', t._parsed_url.user)
893
        self.assertEqual('host.com', t._parsed_url.host)
2485.8.32 by Vincent Ladeuil
Keep credentials used at connection creation for reconnection purposes.
894
        self.assertIs(None, t._get_connection())
6055.2.1 by Jelmer Vernooij
Add UnparsedUrl.
895
        self.assertIs(None, t._parsed_url.password)
2485.8.32 by Vincent Ladeuil
Keep credentials used at connection creation for reconnection purposes.
896
        c = t.clone('subdir')
2900.2.16 by Vincent Ladeuil
Make hhtp proxy aware of AuthenticationConfig (for password).
897
        self.assertIs(None, c._get_connection())
6055.2.1 by Jelmer Vernooij
Add UnparsedUrl.
898
        self.assertIs(None, t._parsed_url.password)
2485.8.32 by Vincent Ladeuil
Keep credentials used at connection creation for reconnection purposes.
899
900
        # Simulate the user entering a password
901
        password = 'secret'
902
        connection = object()
903
        t._set_connection(connection, password)
904
        self.assertIs(connection, t._get_connection())
905
        self.assertIs(password, t._get_credentials())
906
        self.assertIs(connection, c._get_connection())
907
        self.assertIs(password, c._get_credentials())
2485.8.30 by Vincent Ladeuil
Implement reliable connection sharing.
908
2485.8.39 by Vincent Ladeuil
Add tests around connection reuse.
909
        # credentials can be updated
910
        new_password = 'even more secret'
911
        c._update_credentials(new_password)
912
        self.assertIs(connection, t._get_connection())
913
        self.assertIs(new_password, t._get_credentials())
914
        self.assertIs(connection, c._get_connection())
915
        self.assertIs(new_password, c._get_credentials())
916
2477.1.7 by Martin Pool
test_transport must provide get_test_permutations
917
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
918
class TestReusedTransports(tests.TestCase):
2485.8.19 by Vincent Ladeuil
Add a new ConnectedTransport class refactored from [s]ftp and http.
919
    """Tests for transport reuse"""
2476.3.5 by Vincent Ladeuil
Naive implementation of transport reuse by Transport.get_transport().
920
921
    def test_reuse_same_transport(self):
1551.18.10 by Aaron Bentley
get_transport appends to possible_transports if it's an empty list
922
        possible_transports = []
6039.1.6 by Jelmer Vernooij
Add more tests.
923
        t1 = transport.get_transport_from_url('http://foo/',
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
924
                                     possible_transports=possible_transports)
1551.18.10 by Aaron Bentley
get_transport appends to possible_transports if it's an empty list
925
        self.assertEqual([t1], possible_transports)
6039.1.6 by Jelmer Vernooij
Add more tests.
926
        t2 = transport.get_transport_from_url('http://foo/',
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
927
                                     possible_transports=[t1])
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
928
        self.assertIs(t1, t2)
929
930
        # Also check that final '/' are handled correctly
6039.1.6 by Jelmer Vernooij
Add more tests.
931
        t3 = transport.get_transport_from_url('http://foo/path/')
932
        t4 = transport.get_transport_from_url('http://foo/path',
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
933
                                     possible_transports=[t3])
2485.8.37 by Vincent Ladeuil
Fix merge multiple connections. Test suite *not* passing (sftp
934
        self.assertIs(t3, t4)
935
6039.1.6 by Jelmer Vernooij
Add more tests.
936
        t5 = transport.get_transport_from_url('http://foo/path')
937
        t6 = transport.get_transport_from_url('http://foo/path/',
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
938
                                     possible_transports=[t5])
2485.8.39 by Vincent Ladeuil
Add tests around connection reuse.
939
        self.assertIs(t5, t6)
2476.3.5 by Vincent Ladeuil
Naive implementation of transport reuse by Transport.get_transport().
940
941
    def test_don_t_reuse_different_transport(self):
6039.1.6 by Jelmer Vernooij
Add more tests.
942
        t1 = transport.get_transport_from_url('http://foo/path')
943
        t2 = transport.get_transport_from_url('http://bar/path',
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
944
                                     possible_transports=[t1])
2485.8.40 by Vincent Ladeuil
Fix typo.
945
        self.assertIsNot(t1, t2)
2476.3.13 by Vincent Ladeuil
merge bzr.dev@2495
946
947
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
948
class TestTransportTrace(tests.TestCase):
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
949
6039.1.5 by Jelmer Vernooij
Add get_transport_from_url and get_transport_from_path functions.
950
    def test_decorator(self):
6039.1.6 by Jelmer Vernooij
Add more tests.
951
        t = transport.get_transport_from_url('trace+memory://')
6006.2.2 by Martin Pool
pep8 cleanup of test_transport
952
        self.assertIsInstance(
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
953
            t, breezy.transport.trace.TransportTraceDecorator)
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
954
955
    def test_clone_preserves_activity(self):
6039.1.6 by Jelmer Vernooij
Add more tests.
956
        t = transport.get_transport_from_url('trace+memory://')
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
957
        t2 = t.clone('.')
958
        self.assertTrue(t is not t2)
959
        self.assertTrue(t._activity is t2._activity)
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
960
961
    # the following specific tests are for the operations that have made use of
962
    # logging in tests; we could test every single operation but doing that
963
    # still won't cause a test failure when the top level Transport API
964
    # changes; so there is little return doing that.
965
    def test_get(self):
6039.1.6 by Jelmer Vernooij
Add more tests.
966
        t = transport.get_transport_from_url('trace+memory:///')
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
967
        t.put_bytes('foo', 'barish')
968
        t.get('foo')
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
969
        expected_result = []
970
        # put_bytes records the bytes, not the content to avoid memory
971
        # pressure.
972
        expected_result.append(('put_bytes', 'foo', 6, None))
973
        # get records the file name only.
974
        expected_result.append(('get', 'foo'))
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
975
        self.assertEqual(expected_result, t._activity)
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
976
977
    def test_readv(self):
6039.1.6 by Jelmer Vernooij
Add more tests.
978
        t = transport.get_transport_from_url('trace+memory:///')
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
979
        t.put_bytes('foo', 'barish')
980
        list(t.readv('foo', [(0, 1), (3, 2)],
981
                     adjust_for_latency=True, upper_limit=6))
2745.5.3 by Robert Collins
* Move transport logging into a new transport class
982
        expected_result = []
983
        # put_bytes records the bytes, not the content to avoid memory
984
        # pressure.
985
        expected_result.append(('put_bytes', 'foo', 6, None))
986
        # readv records the supplied offset request
987
        expected_result.append(('readv', 'foo', [(0, 1), (3, 2)], True, 6))
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
988
        self.assertEqual(expected_result, t._activity)
4700.1.1 by Robert Collins
Focus and move out of blackbox the acceptance test for bzr+ssh connection handshake/process spawning.
989
990
991
class TestSSHConnections(tests.TestCaseWithTransport):
992
993
    def test_bzr_connect_to_bzr_ssh(self):
6006.2.2 by Martin Pool
pep8 cleanup of test_transport
994
        """get_transport of a bzr+ssh:// behaves correctly.
4700.1.1 by Robert Collins
Focus and move out of blackbox the acceptance test for bzr+ssh connection handshake/process spawning.
995
996
        bzr+ssh:// should cause bzr to run a remote bzr smart server over SSH.
997
        """
998
        # This test actually causes a bzr instance to be invoked, which is very
999
        # expensive: it should be the only such test in the test suite.
1000
        # A reasonable evolution for this would be to simply check inside
1001
        # check_channel_exec_request that the command is appropriate, and then
1002
        # satisfy requests in-process.
4913.2.16 by John Arbash Meinel
Move bzrlib.tests.ParamikoFeature to bzrlib.tests.features.paramiko
1003
        self.requireFeature(features.paramiko)
4700.1.1 by Robert Collins
Focus and move out of blackbox the acceptance test for bzr+ssh connection handshake/process spawning.
1004
        # SFTPFullAbsoluteServer has a get_url method, and doesn't
1005
        # override the interface (doesn't change self._vendor).
1006
        # Note that this does encryption, so can be slow.
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
1007
        from breezy.tests import stub_sftp
4700.1.1 by Robert Collins
Focus and move out of blackbox the acceptance test for bzr+ssh connection handshake/process spawning.
1008
1009
        # Start an SSH server
1010
        self.command_executed = []
1011
        # XXX: This is horrible -- we define a really dumb SSH server that
1012
        # executes commands, and manage the hooking up of stdin/out/err to the
1013
        # SSH channel ourselves.  Surely this has already been implemented
1014
        # elsewhere?
4857.2.2 by John Arbash Meinel
Change the connect-to-bzr test so that it cleans itself up.
1015
        started = []
6006.2.2 by Martin Pool
pep8 cleanup of test_transport
1016
4797.11.2 by Vincent Ladeuil
Stop requiring testtools for sftp use.
1017
        class StubSSHServer(stub_sftp.StubServer):
4700.1.1 by Robert Collins
Focus and move out of blackbox the acceptance test for bzr+ssh connection handshake/process spawning.
1018
1019
            test = self
1020
1021
            def check_channel_exec_request(self, channel, command):
1022
                self.test.command_executed.append(command)
1023
                proc = subprocess.Popen(
1024
                    command, shell=True, stdin=subprocess.PIPE,
1025
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
1026
1027
                # XXX: horribly inefficient, not to mention ugly.
6006.2.2 by Martin Pool
pep8 cleanup of test_transport
1028
                # Start a thread for each of stdin/out/err, and relay bytes
1029
                # from the subprocess to channel and vice versa.
4700.1.1 by Robert Collins
Focus and move out of blackbox the acceptance test for bzr+ssh connection handshake/process spawning.
1030
                def ferry_bytes(read, write, close):
1031
                    while True:
1032
                        bytes = read(1)
1033
                        if bytes == '':
1034
                            close()
1035
                            break
1036
                        write(bytes)
1037
1038
                file_functions = [
1039
                    (channel.recv, proc.stdin.write, proc.stdin.close),
1040
                    (proc.stdout.read, channel.sendall, channel.close),
1041
                    (proc.stderr.read, channel.sendall_stderr, channel.close)]
4857.2.2 by John Arbash Meinel
Change the connect-to-bzr test so that it cleans itself up.
1042
                started.append(proc)
4700.1.1 by Robert Collins
Focus and move out of blackbox the acceptance test for bzr+ssh connection handshake/process spawning.
1043
                for read, write, close in file_functions:
1044
                    t = threading.Thread(
1045
                        target=ferry_bytes, args=(read, write, close))
1046
                    t.start()
4857.2.2 by John Arbash Meinel
Change the connect-to-bzr test so that it cleans itself up.
1047
                    started.append(t)
4700.1.1 by Robert Collins
Focus and move out of blackbox the acceptance test for bzr+ssh connection handshake/process spawning.
1048
1049
                return True
1050
4797.11.2 by Vincent Ladeuil
Stop requiring testtools for sftp use.
1051
        ssh_server = stub_sftp.SFTPFullAbsoluteServer(StubSSHServer)
4700.1.1 by Robert Collins
Focus and move out of blackbox the acceptance test for bzr+ssh connection handshake/process spawning.
1052
        # We *don't* want to override the default SSH vendor: the detected one
1053
        # is the one to use.
5247.4.20 by Vincent Ladeuil
Ugly fix for the last test failure.
1054
1055
        # FIXME: I don't understand the above comment, SFTPFullAbsoluteServer
1056
        # inherits from SFTPServer which forces the SSH vendor to
1057
        # ssh.ParamikoVendor(). So it's forced, not detected. --vila 20100623
4700.1.1 by Robert Collins
Focus and move out of blackbox the acceptance test for bzr+ssh connection handshake/process spawning.
1058
        self.start_server(ssh_server)
5247.4.20 by Vincent Ladeuil
Ugly fix for the last test failure.
1059
        port = ssh_server.port
4700.1.1 by Robert Collins
Focus and move out of blackbox the acceptance test for bzr+ssh connection handshake/process spawning.
1060
1061
        if sys.platform == 'win32':
6622.1.1 by Jelmer Vernooij
Rename bzrlib => brzlib, bzr => brz.
1062
            bzr_remote_path = sys.executable + ' ' + self.get_brz_path()
4700.1.1 by Robert Collins
Focus and move out of blackbox the acceptance test for bzr+ssh connection handshake/process spawning.
1063
        else:
6622.1.1 by Jelmer Vernooij
Rename bzrlib => brzlib, bzr => brz.
1064
            bzr_remote_path = self.get_brz_path()
6622.1.33 by Jelmer Vernooij
Fix more tests (all?)
1065
        self.overrideEnv('BZR_REMOTE_PATH', bzr_remote_path)
4700.1.1 by Robert Collins
Focus and move out of blackbox the acceptance test for bzr+ssh connection handshake/process spawning.
1066
6622.1.33 by Jelmer Vernooij
Fix more tests (all?)
1067
        # Access the branch via a bzr+ssh URL.  The BZR_REMOTE_PATH environment
4700.1.1 by Robert Collins
Focus and move out of blackbox the acceptance test for bzr+ssh connection handshake/process spawning.
1068
        # variable is used to tell bzr what command to run on the remote end.
1069
        path_to_branch = osutils.abspath('.')
1070
        if sys.platform == 'win32':
4700.1.2 by Robert Collins
Review feedback.
1071
            # On Windows, we export all drives as '/C:/, etc. So we need to
1072
            # prefix a '/' to get the right path.
1073
            path_to_branch = '/' + path_to_branch
1074
        url = 'bzr+ssh://fred:secret@localhost:%d%s' % (port, path_to_branch)
5010.2.10 by Vincent Ladeuil
Fix test_transport.py imports.
1075
        t = transport.get_transport(url)
4700.1.2 by Robert Collins
Review feedback.
1076
        self.permit_url(t.base)
4700.1.1 by Robert Collins
Focus and move out of blackbox the acceptance test for bzr+ssh connection handshake/process spawning.
1077
        t.mkdir('foo')
1078
1079
        self.assertEqual(
1080
            ['%s serve --inet --directory=/ --allow-writes' % bzr_remote_path],
1081
            self.command_executed)
4857.2.2 by John Arbash Meinel
Change the connect-to-bzr test so that it cleans itself up.
1082
        # Make sure to disconnect, so that the remote process can stop, and we
1083
        # can cleanup. Then pause the test until everything is shutdown
1084
        t._client._medium.disconnect()
1085
        if not started:
1086
            return
1087
        # First wait for the subprocess
1088
        started[0].wait()
1089
        # And the rest are threads
1090
        for t in started[1:]:
1091
            t.join()
4912.2.4 by Martin Pool
Add test for unhtml_roughly, and truncate at 1000 bytes
1092
1093
1094
class TestUnhtml(tests.TestCase):
1095
1096
    """Tests for unhtml_roughly"""
1097
1098
    def test_truncation(self):
1099
        fake_html = "<p>something!\n" * 1000
1100
        result = http.unhtml_roughly(fake_html)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1101
        self.assertEqual(len(result), 1000)
4912.2.4 by Martin Pool
Add test for unhtml_roughly, and truncate at 1000 bytes
1102
        self.assertStartsWith(result, " something!")
6030.2.2 by Jelmer Vernooij
Add test.
1103
1104
1105
class SomeDirectory(object):
1106
1107
    def look_up(self, name, url):
1108
        return "http://bar"
1109
1110
1111
class TestLocationToUrl(tests.TestCase):
1112
6060.1.2 by John Arbash Meinel
Fix location_to_url tests that needed to watch out for drive letters.
1113
    def get_base_location(self):
1114
        path = osutils.abspath('/foo/bar')
1115
        if path.startswith('/'):
1116
            url = 'file://%s' % (path,)
1117
        else:
1118
            # On Windows, abspaths start with the drive letter, so we have to
1119
            # add in the extra '/'
1120
            url = 'file:///%s' % (path,)
1121
        return path, url
1122
6030.2.2 by Jelmer Vernooij
Add test.
1123
    def test_regular_url(self):
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1124
        self.assertEqual("file://foo", location_to_url("file://foo"))
6030.2.2 by Jelmer Vernooij
Add test.
1125
1126
    def test_directory(self):
1127
        directories.register("bar:", SomeDirectory, "Dummy directory")
1128
        self.addCleanup(directories.remove, "bar:")
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1129
        self.assertEqual("http://bar", location_to_url("bar:"))
6030.2.3 by Jelmer Vernooij
Move encoding of path to URL.
1130
1131
    def test_unicode_url(self):
1132
        self.assertRaises(errors.InvalidURL, location_to_url,
1133
            "http://fo/\xc3\xaf".decode("utf-8"))
1134
1135
    def test_unicode_path(self):
6060.1.2 by John Arbash Meinel
Fix location_to_url tests that needed to watch out for drive letters.
1136
        path, url = self.get_base_location()
1137
        location = path + "\xc3\xaf".decode("utf-8")
1138
        url += '%C3%AF'
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1139
        self.assertEqual(url, location_to_url(location))
6030.2.4 by Jelmer Vernooij
Move local file interpretation to location_to_url.
1140
1141
    def test_path(self):
6060.1.2 by John Arbash Meinel
Fix location_to_url tests that needed to watch out for drive letters.
1142
        path, url = self.get_base_location()
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1143
        self.assertEqual(url, location_to_url(path))
6037.1.1 by Jelmer Vernooij
Allow file: for use with relative local paths.
1144
1145
    def test_relative_file_url(self):
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1146
        self.assertEqual(urlutils.local_path_to_url(".") + "/bar",
6037.1.1 by Jelmer Vernooij
Allow file: for use with relative local paths.
1147
            location_to_url("file:bar"))
6037.1.2 by Jelmer Vernooij
Add another test.
1148
1149
    def test_absolute_file_url(self):
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
1150
        self.assertEqual("file:///bar", location_to_url("file:/bar"))