~bzr-pqm/bzr/bzr.dev

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