~bzr-pqm/bzr/bzr.dev

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