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