/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2221.5.1 by Dmitry Vasiliev
Added support for Putty's SSH implementation
1
# Copyright (C) 2005 Robey Pointer <robey@lag.net>
2
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
3
#
1185.16.127 by Martin Pool
[patch] paramiko sftp tests (robey)
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
8
#
1185.16.127 by Martin Pool
[patch] paramiko sftp tests (robey)
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
13
#
1185.16.127 by Martin Pool
[patch] paramiko sftp tests (robey)
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1185.16.127 by Martin Pool
[patch] paramiko sftp tests (robey)
17
18
import os
19
import socket
2321.3.7 by Alexander Belchenko
fixes for passing test_sftp_transport on win32 (thankyou John)
20
import sys
1185.16.127 by Martin Pool
[patch] paramiko sftp tests (robey)
21
import threading
1871.1.3 by Robert Collins
proof of concept slowsocket wrapper.
22
import time
1185.16.127 by Martin Pool
[patch] paramiko sftp tests (robey)
23
2485.8.20 by Vincent Ladeuil
Refactor SFTPTransport. Test suite passes.
24
from bzrlib import (
25
    bzrdir,
3777.1.1 by Aaron Bentley
Use auth.conf for sftp
26
    config,
2485.8.20 by Vincent Ladeuil
Refactor SFTPTransport. Test suite passes.
27
    errors,
3686.1.2 by John Arbash Meinel
Start moving the readv code into a helper.
28
    tests,
29
    transport as _mod_transport,
4222.3.13 by Jelmer Vernooij
Add tests to ensure sftp and ftp don't prompt for usernames.
30
    ui,
2485.8.20 by Vincent Ladeuil
Refactor SFTPTransport. Test suite passes.
31
    )
32
from bzrlib.osutils import (
33
    pathjoin,
34
    lexists,
35
    set_or_unset_env,
36
    )
37
from bzrlib.tests import (
4913.2.16 by John Arbash Meinel
Move bzrlib.tests.ParamikoFeature to bzrlib.tests.features.paramiko
38
    features,
2485.8.20 by Vincent Ladeuil
Refactor SFTPTransport. Test suite passes.
39
    TestCaseWithTransport,
40
    TestCase,
41
    TestSkipped,
42
    )
2929.3.7 by Vincent Ladeuil
Rename bzrlib/test/HttpServer.py to bzrlib/tests/http_server.py and fix uses.
43
from bzrlib.tests.http_server import HttpServer
1986.1.10 by Robert Collins
Merge from bzr.dev, fixing found bugs handling 'has('/')' in MemoryTransport and SFTP transports.
44
from bzrlib.transport import get_transport
1711.2.132 by John Arbash Meinel
Clean up PEP8 and unused imports in bench_sftp.py, and missing import in bzrlib/tests/test_sftp_transport.py
45
import bzrlib.transport.http
2822.1.1 by v.ladeuil+lp at free
Fix #59150 (again) by handling paramiko availability for transport_util.py.
46
4913.2.16 by John Arbash Meinel
Move bzrlib.tests.ParamikoFeature to bzrlib.tests.features.paramiko
47
if features.paramiko.available():
3686.1.2 by John Arbash Meinel
Start moving the readv code into a helper.
48
    from bzrlib.transport import sftp as _mod_sftp
2822.1.1 by v.ladeuil+lp at free
Fix #59150 (again) by handling paramiko availability for transport_util.py.
49
    from bzrlib.transport.sftp import (
50
        SFTPAbsoluteServer,
51
        SFTPHomeDirServer,
52
        SFTPTransport,
53
        )
54
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
55
from bzrlib.workingtree import WorkingTree
1185.16.127 by Martin Pool
[patch] paramiko sftp tests (robey)
56
1874.1.12 by Carl Friedrich Bolz
More fixes according to John's comments.
57
1874.1.14 by Carl Friedrich Bolz
Rename setup method to make its intent clearer. Some PEP 8 issues.
58
def set_test_transport_to_sftp(testcase):
1874.1.9 by Carl Friedrich Bolz
Try to fix all the issues outline by john and Robert.
59
    """A helper to set transports on test case instances."""
1874.1.6 by holger krekel
(cfbolz, hpk) Factor out common set_transport code.
60
    if getattr(testcase, '_get_remote_is_absolute', None) is None:
61
        testcase._get_remote_is_absolute = True
62
    if testcase._get_remote_is_absolute:
2018.5.114 by Robert Collins
Commit current test pass improvements.
63
        testcase.transport_server = SFTPAbsoluteServer
1874.1.6 by holger krekel
(cfbolz, hpk) Factor out common set_transport code.
64
    else:
2018.5.114 by Robert Collins
Commit current test pass improvements.
65
        testcase.transport_server = SFTPHomeDirServer
2004.1.25 by v.ladeuil+lp at free
Shuffle http related test code. Hopefully it ends up at the right place :)
66
    testcase.transport_readonly_server = HttpServer
1530.1.6 by Robert Collins
Trim duplicate sftp tests.
67
1874.1.9 by Carl Friedrich Bolz
Try to fix all the issues outline by john and Robert.
68
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
69
class TestCaseWithSFTPServer(TestCaseWithTransport):
1530.1.6 by Robert Collins
Trim duplicate sftp tests.
70
    """A test case base class that provides a sftp server on localhost."""
1185.16.127 by Martin Pool
[patch] paramiko sftp tests (robey)
71
72
    def setUp(self):
1524.1.1 by Robert Collins
Test sftp with relative, absolute-in-homedir and absolute-not-in-homedir
73
        super(TestCaseWithSFTPServer, self).setUp()
4913.2.16 by John Arbash Meinel
Move bzrlib.tests.ParamikoFeature to bzrlib.tests.features.paramiko
74
        self.requireFeature(features.paramiko)
2381.1.1 by Robert Collins
Split out hpss test fixes which dont depend on new or altered API's.
75
        set_test_transport_to_sftp(self)
1524.1.1 by Robert Collins
Test sftp with relative, absolute-in-homedir and absolute-not-in-homedir
76
1530.1.6 by Robert Collins
Trim duplicate sftp tests.
77
3686.1.2 by John Arbash Meinel
Start moving the readv code into a helper.
78
class SFTPLockTests(TestCaseWithSFTPServer):
1185.16.127 by Martin Pool
[patch] paramiko sftp tests (robey)
79
1185.49.3 by John Arbash Meinel
Added a form of locking to sftp branches. Refactored _sftp_open_exclusive to take a relative path
80
    def test_sftp_locks(self):
81
        from bzrlib.errors import LockError
82
        t = self.get_transport()
83
84
        l = t.lock_write('bogus')
85
        self.failUnlessExists('bogus.write-lock')
86
87
        # Don't wait for the lock, locking an already locked
88
        # file should raise an assert
89
        self.assertRaises(LockError, t.lock_write, 'bogus')
90
91
        l.unlock()
1185.31.33 by John Arbash Meinel
A couple more path.join statements needed changing.
92
        self.failIf(lexists('bogus.write-lock'))
1185.49.3 by John Arbash Meinel
Added a form of locking to sftp branches. Refactored _sftp_open_exclusive to take a relative path
93
94
        open('something.write-lock', 'wb').write('fake lock\n')
95
        self.assertRaises(LockError, t.lock_write, 'something')
96
        os.remove('something.write-lock')
97
98
        l = t.lock_write('something')
99
100
        l2 = t.lock_write('bogus')
101
102
        l.unlock()
103
        l2.unlock()
104
1524.1.1 by Robert Collins
Test sftp with relative, absolute-in-homedir and absolute-not-in-homedir
105
1530.1.6 by Robert Collins
Trim duplicate sftp tests.
106
class SFTPTransportTestRelative(TestCaseWithSFTPServer):
1524.1.1 by Robert Collins
Test sftp with relative, absolute-in-homedir and absolute-not-in-homedir
107
    """Test the SFTP transport with homedir based relative paths."""
108
109
    def test__remote_path(self):
2823.1.4 by Vincent Ladeuil
Use assertIsSameRealPath to avoid OSX aliasing (specifically /tmp
110
        if sys.platform == 'darwin':
2823.1.11 by Vincent Ladeuil
Review feedback.
111
            # This test is about sftp absolute path handling. There is already
112
            # (in this test) a TODO about windows needing an absolute path
113
            # without drive letter. To me, using self.test_dir is a trick to
114
            # get an absolute path for comparison purposes.  That fails for OSX
115
            # because the sftp server doesn't resolve the links (and it doesn't
116
            # have to). --vila 20070924
2823.1.8 by Vincent Ladeuil
Rewrite expected failure message
117
            self.knownFailure('Mac OSX symlinks /tmp to /private/tmp,'
118
                              ' testing against self.test_dir'
119
                              ' is not appropriate')
1524.1.1 by Robert Collins
Test sftp with relative, absolute-in-homedir and absolute-not-in-homedir
120
        t = self.get_transport()
2321.3.7 by Alexander Belchenko
fixes for passing test_sftp_transport on win32 (thankyou John)
121
        # This test require unix-like absolute path
122
        test_dir = self.test_dir
123
        if sys.platform == 'win32':
124
            # using hack suggested by John Meinel.
125
            # TODO: write another mock server for this test
126
            #       and use absolute path without drive letter
127
            test_dir = '/' + test_dir
1524.1.1 by Robert Collins
Test sftp with relative, absolute-in-homedir and absolute-not-in-homedir
128
        # try what is currently used:
129
        # remote path = self._abspath(relpath)
2823.1.14 by Vincent Ladeuil
Fix 141382 by comparing real paths.
130
        self.assertIsSameRealPath(test_dir + '/relative',
131
                                  t._remote_path('relative'))
1524.1.1 by Robert Collins
Test sftp with relative, absolute-in-homedir and absolute-not-in-homedir
132
        # we dont os.path.join because windows gives us the wrong path
2321.3.7 by Alexander Belchenko
fixes for passing test_sftp_transport on win32 (thankyou John)
133
        root_segments = test_dir.split('/')
1524.1.1 by Robert Collins
Test sftp with relative, absolute-in-homedir and absolute-not-in-homedir
134
        root_parent = '/'.join(root_segments[:-1])
135
        # .. should be honoured
2823.1.14 by Vincent Ladeuil
Fix 141382 by comparing real paths.
136
        self.assertIsSameRealPath(root_parent + '/sibling',
137
                                  t._remote_path('../sibling'))
1524.1.1 by Robert Collins
Test sftp with relative, absolute-in-homedir and absolute-not-in-homedir
138
        # /  should be illegal ?
139
        ### FIXME decide and then test for all transports. RBC20051208
140
1530.1.6 by Robert Collins
Trim duplicate sftp tests.
141
1986.1.10 by Robert Collins
Merge from bzr.dev, fixing found bugs handling 'has('/')' in MemoryTransport and SFTP transports.
142
class SFTPTransportTestRelativeRoot(TestCaseWithSFTPServer):
1530.1.6 by Robert Collins
Trim duplicate sftp tests.
143
    """Test the SFTP transport with homedir based relative paths."""
144
145
    def setUp(self):
2485.8.43 by Vincent Ladeuil
Cleaning.
146
        # Only SFTPHomeDirServer is tested here
1530.1.6 by Robert Collins
Trim duplicate sftp tests.
147
        self._get_remote_is_absolute = False
1986.1.10 by Robert Collins
Merge from bzr.dev, fixing found bugs handling 'has('/')' in MemoryTransport and SFTP transports.
148
        super(SFTPTransportTestRelativeRoot, self).setUp()
1530.1.6 by Robert Collins
Trim duplicate sftp tests.
149
1524.1.1 by Robert Collins
Test sftp with relative, absolute-in-homedir and absolute-not-in-homedir
150
    def test__remote_path_relative_root(self):
151
        # relative paths are preserved
152
        t = self.get_transport('')
2485.8.27 by Vincent Ladeuil
Hearing jam saying "vila, you're trying too hard", I simplified again.
153
        self.assertEqual('/~/', t._path)
154
        # the remote path should be relative to home dir
155
        # (i.e. not begining with a '/')
1524.1.1 by Robert Collins
Test sftp with relative, absolute-in-homedir and absolute-not-in-homedir
156
        self.assertEqual('a', t._remote_path('a'))
157
158
1185.49.14 by John Arbash Meinel
[merge] bzr.dev
159
class SFTPNonServerTest(TestCase):
1185.58.12 by John Arbash Meinel
Changing so that sftp tests are skipped rather than hidden when paramiko isn't present
160
    def setUp(self):
161
        TestCase.setUp(self)
4913.2.16 by John Arbash Meinel
Move bzrlib.tests.ParamikoFeature to bzrlib.tests.features.paramiko
162
        self.requireFeature(features.paramiko)
1185.58.12 by John Arbash Meinel
Changing so that sftp tests are skipped rather than hidden when paramiko isn't present
163
2485.8.20 by Vincent Ladeuil
Refactor SFTPTransport. Test suite passes.
164
    def test_parse_url_with_home_dir(self):
2485.8.38 by Vincent Ladeuil
Finish sftp refactoring. Test suite passing.
165
        s = SFTPTransport('sftp://ro%62ey:h%40t@example.com:2222/~/relative')
1185.40.4 by Robey Pointer
fix sftp urls to support the ietf draft url spec wrt relative vs absolute sftp urls (this will break existing branch urls); fix username/password parsing in sftp urls; add unit tests to make sure sftp url parsing is working
166
        self.assertEquals(s._host, 'example.com')
167
        self.assertEquals(s._port, 2222)
2485.8.20 by Vincent Ladeuil
Refactor SFTPTransport. Test suite passes.
168
        self.assertEquals(s._user, 'robey')
2485.8.38 by Vincent Ladeuil
Finish sftp refactoring. Test suite passing.
169
        self.assertEquals(s._password, 'h@t')
2485.8.27 by Vincent Ladeuil
Hearing jam saying "vila, you're trying too hard", I simplified again.
170
        self.assertEquals(s._path, '/~/relative/')
1185.49.23 by John Arbash Meinel
bugreport from Matthieu Moy: relpath was failing, but throwing an unhelpful exception.
171
172
    def test_relpath(self):
2485.8.38 by Vincent Ladeuil
Finish sftp refactoring. Test suite passing.
173
        s = SFTPTransport('sftp://user@host.com/abs/path')
2485.8.20 by Vincent Ladeuil
Refactor SFTPTransport. Test suite passes.
174
        self.assertRaises(errors.PathNotChild, s.relpath,
175
                          'sftp://user@host.com/~/rel/path/sub')
1185.33.58 by Martin Pool
[patch] Better error when sftp urls are given with invalid port numbers (Matthieu Moy)
176
2013.1.2 by John Arbash Meinel
Add a test that we can always fall back to the paramiko vendor
177
    def test_get_paramiko_vendor(self):
178
        """Test that if no 'ssh' is available we get builtin paramiko"""
179
        from bzrlib.transport import ssh
180
        # set '.' as the only location in the path, forcing no 'ssh' to exist
2221.5.18 by Dmitry Vasiliev
Fixed variable name
181
        orig_vendor = ssh._ssh_vendor_manager._cached_ssh_vendor
2013.1.2 by John Arbash Meinel
Add a test that we can always fall back to the paramiko vendor
182
        orig_path = set_or_unset_env('PATH', '.')
183
        try:
184
            # No vendor defined yet, query for one
2221.5.18 by Dmitry Vasiliev
Fixed variable name
185
            ssh._ssh_vendor_manager.clear_cache()
2013.1.2 by John Arbash Meinel
Add a test that we can always fall back to the paramiko vendor
186
            vendor = ssh._get_ssh_vendor()
187
            self.assertIsInstance(vendor, ssh.ParamikoVendor)
188
        finally:
189
            set_or_unset_env('PATH', orig_path)
2221.5.18 by Dmitry Vasiliev
Fixed variable name
190
            ssh._ssh_vendor_manager._cached_ssh_vendor = orig_vendor
2013.1.2 by John Arbash Meinel
Add a test that we can always fall back to the paramiko vendor
191
1986.1.10 by Robert Collins
Merge from bzr.dev, fixing found bugs handling 'has('/')' in MemoryTransport and SFTP transports.
192
    def test_abspath_root_sibling_server(self):
193
        from bzrlib.transport.sftp import SFTPSiblingAbsoluteServer
194
        server = SFTPSiblingAbsoluteServer()
195
        server.setUp()
196
        try:
197
            transport = get_transport(server.get_url())
198
            self.assertFalse(transport.abspath('/').endswith('/~/'))
199
            self.assertTrue(transport.abspath('/').endswith('/'))
200
            del transport
201
        finally:
202
            server.tearDown()
203
1185.40.4 by Robey Pointer
fix sftp urls to support the ietf draft url spec wrt relative vs absolute sftp urls (this will break existing branch urls); fix username/password parsing in sftp urls; add unit tests to make sure sftp url parsing is working
204
1185.49.3 by John Arbash Meinel
Added a form of locking to sftp branches. Refactored _sftp_open_exclusive to take a relative path
205
class SFTPBranchTest(TestCaseWithSFTPServer):
206
    """Test some stuff when accessing a bzr Branch over sftp"""
207
208
    def test_lock_file(self):
1666.1.4 by Robert Collins
* 'Metadir' is now the default disk format. This improves behaviour in
209
        # old format branches use a special lock file on sftp.
210
        b = self.make_branch('', format=bzrdir.BzrDirFormat6())
211
        b = bzrlib.branch.Branch.open(self.get_url())
1185.49.3 by John Arbash Meinel
Added a form of locking to sftp branches. Refactored _sftp_open_exclusive to take a relative path
212
        self.failUnlessExists('.bzr/')
213
        self.failUnlessExists('.bzr/branch-format')
214
        self.failUnlessExists('.bzr/branch-lock')
215
1185.31.33 by John Arbash Meinel
A couple more path.join statements needed changing.
216
        self.failIf(lexists('.bzr/branch-lock.write-lock'))
1185.49.3 by John Arbash Meinel
Added a form of locking to sftp branches. Refactored _sftp_open_exclusive to take a relative path
217
        b.lock_write()
218
        self.failUnlessExists('.bzr/branch-lock.write-lock')
219
        b.unlock()
1185.31.33 by John Arbash Meinel
A couple more path.join statements needed changing.
220
        self.failIf(lexists('.bzr/branch-lock.write-lock'))
1185.49.3 by John Arbash Meinel
Added a form of locking to sftp branches. Refactored _sftp_open_exclusive to take a relative path
221
1185.49.26 by John Arbash Meinel
Adding tests for remote sftp branches without working trees, plus a bugfix to allow push to still work with a warning.
222
    def test_push_support(self):
223
        self.build_tree(['a/', 'a/foo'])
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
224
        t = bzrdir.BzrDir.create_standalone_workingtree('a')
1534.4.26 by Robert Collins
Move working tree initialisation out from Branch.initialize, deprecated Branch.initialize to Branch.create.
225
        b = t.branch
1185.49.26 by John Arbash Meinel
Adding tests for remote sftp branches without working trees, plus a bugfix to allow push to still work with a warning.
226
        t.add('foo')
227
        t.commit('foo', rev_id='a1')
228
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
229
        b2 = bzrdir.BzrDir.create_branch_and_repo(self.get_url('/b'))
1185.49.26 by John Arbash Meinel
Adding tests for remote sftp branches without working trees, plus a bugfix to allow push to still work with a warning.
230
        b2.pull(b)
231
232
        self.assertEquals(b2.revision_history(), ['a1'])
233
1185.31.48 by John Arbash Meinel
Added a small test to sftp to make sure some replacing was going on in the remote side.
234
        open('a/foo', 'wt').write('something new in foo\n')
235
        t.commit('new', rev_id='a2')
236
        b2.pull(b)
237
238
        self.assertEquals(b2.revision_history(), ['a1', 'a2'])
239
1185.49.3 by John Arbash Meinel
Added a form of locking to sftp branches. Refactored _sftp_open_exclusive to take a relative path
240
1185.49.32 by John Arbash Meinel
Update tests to show that all ssh vendor failed connections work correctly, has some stipple from real ssh
241
class SSHVendorConnection(TestCaseWithSFTPServer):
242
    """Test that the ssh vendors can all connect.
243
244
    Verify that a full-handshake (SSH over loopback TCP) sftp connection works.
245
246
    We have 3 sftp implementations in the test suite:
247
      'loopback': Doesn't use ssh, just uses a local socket. Most tests are
248
                  done this way to save the handshaking time, so it is not
249
                  tested again here
250
      'none':     This uses paramiko's built-in ssh client and server, and layers
251
                  sftp on top of it.
252
      None:       If 'ssh' exists on the machine, then it will be spawned as a
253
                  child process.
254
    """
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
255
1185.49.32 by John Arbash Meinel
Update tests to show that all ssh vendor failed connections work correctly, has some stipple from real ssh
256
    def setUp(self):
257
        super(SSHVendorConnection, self).setUp()
1534.4.50 by Robert Collins
Got the bzrdir api straightened out, plenty of refactoring to use it pending, but the api is up and running.
258
        from bzrlib.transport.sftp import SFTPFullAbsoluteServer
1185.49.32 by John Arbash Meinel
Update tests to show that all ssh vendor failed connections work correctly, has some stipple from real ssh
259
260
        def create_server():
261
            """Just a wrapper so that when created, it will set _vendor"""
262
            # SFTPFullAbsoluteServer can handle any vendor,
263
            # it just needs to be set between the time it is instantiated
264
            # and the time .setUp() is called
265
            server = SFTPFullAbsoluteServer()
266
            server._vendor = self._test_vendor
267
            return server
268
        self._test_vendor = 'loopback'
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
269
        self.vfs_transport_server = create_server
1185.49.32 by John Arbash Meinel
Update tests to show that all ssh vendor failed connections work correctly, has some stipple from real ssh
270
        f = open('a_file', 'wb')
271
        try:
272
            f.write('foobar\n')
273
        finally:
274
            f.close()
275
276
    def set_vendor(self, vendor):
277
        self._test_vendor = vendor
278
279
    def test_connection_paramiko(self):
1951.1.8 by Andrew Bennetts
Make _get_ssh_vendor return the vendor object, rather than just a string.
280
        from bzrlib.transport import ssh
281
        self.set_vendor(ssh.ParamikoVendor())
1185.49.32 by John Arbash Meinel
Update tests to show that all ssh vendor failed connections work correctly, has some stipple from real ssh
282
        t = self.get_transport()
283
        self.assertEqual('foobar\n', t.get('a_file').read())
284
285
    def test_connection_vendor(self):
286
        raise TestSkipped("We don't test spawning real ssh,"
287
                          " because it prompts for a password."
288
                          " Enable this test if we figure out"
289
                          " how to prevent this.")
290
        self.set_vendor(None)
291
        t = self.get_transport()
292
        self.assertEqual('foobar\n', t.get('a_file').read())
293
294
295
class SSHVendorBadConnection(TestCaseWithTransport):
296
    """Test that the ssh vendors handle bad connection properly
297
298
    We don't subclass TestCaseWithSFTPServer, because we don't actually
299
    need an SFTP connection.
300
    """
301
302
    def setUp(self):
4913.2.16 by John Arbash Meinel
Move bzrlib.tests.ParamikoFeature to bzrlib.tests.features.paramiko
303
        self.requireFeature(features.paramiko)
1185.49.32 by John Arbash Meinel
Update tests to show that all ssh vendor failed connections work correctly, has some stipple from real ssh
304
        super(SSHVendorBadConnection, self).setUp()
1951.1.10 by Andrew Bennetts
Move register_ssh_vendor, _ssh_vendor and _get_ssh_vendor into ssh.py
305
        import bzrlib.transport.ssh
1185.49.32 by John Arbash Meinel
Update tests to show that all ssh vendor failed connections work correctly, has some stipple from real ssh
306
1185.49.35 by John Arbash Meinel
Update tests to use a truly unused port
307
        # open a random port, so we know nobody else is using it
308
        # but don't actually listen on the port.
309
        s = socket.socket()
310
        s.bind(('localhost', 0))
311
        self.bogus_url = 'sftp://%s:%s/' % s.getsockname()
1185.49.32 by John Arbash Meinel
Update tests to show that all ssh vendor failed connections work correctly, has some stipple from real ssh
312
2221.5.18 by Dmitry Vasiliev
Fixed variable name
313
        orig_vendor = bzrlib.transport.ssh._ssh_vendor_manager._cached_ssh_vendor
1185.49.35 by John Arbash Meinel
Update tests to use a truly unused port
314
        def reset():
2221.5.18 by Dmitry Vasiliev
Fixed variable name
315
            bzrlib.transport.ssh._ssh_vendor_manager._cached_ssh_vendor = orig_vendor
1185.49.35 by John Arbash Meinel
Update tests to use a truly unused port
316
            s.close()
317
        self.addCleanup(reset)
1185.49.32 by John Arbash Meinel
Update tests to show that all ssh vendor failed connections work correctly, has some stipple from real ssh
318
319
    def set_vendor(self, vendor):
1951.1.10 by Andrew Bennetts
Move register_ssh_vendor, _ssh_vendor and _get_ssh_vendor into ssh.py
320
        import bzrlib.transport.ssh
2221.5.18 by Dmitry Vasiliev
Fixed variable name
321
        bzrlib.transport.ssh._ssh_vendor_manager._cached_ssh_vendor = vendor
1185.49.32 by John Arbash Meinel
Update tests to show that all ssh vendor failed connections work correctly, has some stipple from real ssh
322
323
    def test_bad_connection_paramiko(self):
324
        """Test that a real connection attempt raises the right error"""
1951.1.8 by Andrew Bennetts
Make _get_ssh_vendor return the vendor object, rather than just a string.
325
        from bzrlib.transport import ssh
326
        self.set_vendor(ssh.ParamikoVendor())
2485.8.38 by Vincent Ladeuil
Finish sftp refactoring. Test suite passing.
327
        t = bzrlib.transport.get_transport(self.bogus_url)
328
        self.assertRaises(errors.ConnectionError, t.get, 'foobar')
1185.49.32 by John Arbash Meinel
Update tests to show that all ssh vendor failed connections work correctly, has some stipple from real ssh
329
330
    def test_bad_connection_ssh(self):
331
        """None => auto-detect vendor"""
332
        self.set_vendor(None)
1185.49.33 by John Arbash Meinel
Spawn another bzr instance using run_bzr_subprocess, so we don't get stipple
333
        # This is how I would normally test the connection code
334
        # it makes it very clear what we are testing.
335
        # However, 'ssh' will create stipple on the output, so instead
336
        # I'm using run_bzr_subprocess, and parsing the output
337
        # try:
338
        #     t = bzrlib.transport.get_transport(self.bogus_url)
339
        # except errors.ConnectionError:
340
        #     # Correct error
341
        #     pass
342
        # except errors.NameError, e:
343
        #     if 'SSHException' in str(e):
344
        #         raise TestSkipped('Known NameError bug in paramiko 1.6.1')
345
        #     raise
346
        # else:
347
        #     self.fail('Excepted ConnectionError to be raised')
348
2665.4.1 by Aaron Bentley
teach run_bzr_subprocess to accept either a list of strings or a string
349
        out, err = self.run_bzr_subprocess(['log', self.bogus_url], retcode=3)
1185.49.33 by John Arbash Meinel
Spawn another bzr instance using run_bzr_subprocess, so we don't get stipple
350
        self.assertEqual('', out)
351
        if "NameError: global name 'SSHException'" in err:
352
            # We aren't fixing this bug, because it is a bug in
353
            # paramiko, but we know about it, so we don't have to
354
            # fail the test
355
            raise TestSkipped('Known NameError bug with paramiko-1.6.1')
2052.4.4 by John Arbash Meinel
Create a SocketConnectionError to make creating nice errors easier
356
        self.assertContainsRe(err, r'bzr: ERROR: Unable to connect to SSH host'
357
                                   r' 127\.0\.0\.1:\d+; ')
1185.49.32 by John Arbash Meinel
Update tests to show that all ssh vendor failed connections work correctly, has some stipple from real ssh
358
1871.1.3 by Robert Collins
proof of concept slowsocket wrapper.
359
360
class SFTPLatencyKnob(TestCaseWithSFTPServer):
361
    """Test that the testing SFTPServer's latency knob works."""
362
1874.1.9 by Carl Friedrich Bolz
Try to fix all the issues outline by john and Robert.
363
    def test_latency_knob_slows_transport(self):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
364
        # change the latency knob to 500ms. We take about 40ms for a
1871.1.3 by Robert Collins
proof of concept slowsocket wrapper.
365
        # loopback connection ordinarily.
1874.1.9 by Carl Friedrich Bolz
Try to fix all the issues outline by john and Robert.
366
        start_time = time.time()
367
        self.get_server().add_latency = 0.5
368
        transport = self.get_transport()
2485.8.38 by Vincent Ladeuil
Finish sftp refactoring. Test suite passing.
369
        transport.has('not me') # Force connection by issuing a request
1874.1.9 by Carl Friedrich Bolz
Try to fix all the issues outline by john and Robert.
370
        with_latency_knob_time = time.time() - start_time
371
        self.assertTrue(with_latency_knob_time > 0.4)
372
373
    def test_default(self):
374
        # This test is potentially brittle: under extremely high machine load
375
        # it could fail, but that is quite unlikely
2631.1.1 by Aaron Bentley
Disable timing-sensitive test
376
        raise TestSkipped('Timing-sensitive test')
1874.1.9 by Carl Friedrich Bolz
Try to fix all the issues outline by john and Robert.
377
        start_time = time.time()
378
        transport = self.get_transport()
2485.8.38 by Vincent Ladeuil
Finish sftp refactoring. Test suite passing.
379
        transport.has('not me') # Force connection by issuing a request
1874.1.9 by Carl Friedrich Bolz
Try to fix all the issues outline by john and Robert.
380
        regular_time = time.time() - start_time
381
        self.assertTrue(regular_time < 0.5)
382
1874.1.2 by Carl Friedrich Bolz
Refined the SocketDelay to charge latency only once per round-trip and to
383
384
class FakeSocket(object):
1874.1.9 by Carl Friedrich Bolz
Try to fix all the issues outline by john and Robert.
385
    """Fake socket object used to test the SocketDelay wrapper without
386
    using a real socket.
387
    """
1874.1.2 by Carl Friedrich Bolz
Refined the SocketDelay to charge latency only once per round-trip and to
388
389
    def __init__(self):
390
        self._data = ""
391
392
    def send(self, data, flags=0):
393
        self._data += data
394
        return len(data)
395
396
    def sendall(self, data, flags=0):
397
        self._data += data
398
        return len(data)
399
400
    def recv(self, size, flags=0):
401
        if size < len(self._data):
402
            result = self._data[:size]
403
            self._data = self._data[size:]
404
            return result
405
        else:
406
            result = self._data
407
            self._data = ""
408
            return result
409
1874.1.9 by Carl Friedrich Bolz
Try to fix all the issues outline by john and Robert.
410
1874.1.2 by Carl Friedrich Bolz
Refined the SocketDelay to charge latency only once per round-trip and to
411
class TestSocketDelay(TestCase):
1874.1.9 by Carl Friedrich Bolz
Try to fix all the issues outline by john and Robert.
412
1874.1.2 by Carl Friedrich Bolz
Refined the SocketDelay to charge latency only once per round-trip and to
413
    def setUp(self):
414
        TestCase.setUp(self)
4913.2.16 by John Arbash Meinel
Move bzrlib.tests.ParamikoFeature to bzrlib.tests.features.paramiko
415
        self.requireFeature(features.paramiko)
1874.1.2 by Carl Friedrich Bolz
Refined the SocketDelay to charge latency only once per round-trip and to
416
417
    def test_delay(self):
418
        from bzrlib.transport.sftp import SocketDelay
419
        sending = FakeSocket()
1874.1.9 by Carl Friedrich Bolz
Try to fix all the issues outline by john and Robert.
420
        receiving = SocketDelay(sending, 0.1, bandwidth=1000000,
421
                                really_sleep=False)
1874.1.2 by Carl Friedrich Bolz
Refined the SocketDelay to charge latency only once per round-trip and to
422
        # check that simulated time is charged only per round-trip:
423
        t1 = SocketDelay.simulated_time
424
        receiving.send("connect1")
425
        self.assertEqual(sending.recv(1024), "connect1")
426
        t2 = SocketDelay.simulated_time
427
        self.assertAlmostEqual(t2 - t1, 0.1)
428
        receiving.send("connect2")
429
        self.assertEqual(sending.recv(1024), "connect2")
430
        sending.send("hello")
431
        self.assertEqual(receiving.recv(1024), "hello")
432
        t3 = SocketDelay.simulated_time
433
        self.assertAlmostEqual(t3 - t2, 0.1)
434
        sending.send("hello")
435
        self.assertEqual(receiving.recv(1024), "hello")
436
        sending.send("hello")
437
        self.assertEqual(receiving.recv(1024), "hello")
438
        sending.send("hello")
439
        self.assertEqual(receiving.recv(1024), "hello")
440
        t4 = SocketDelay.simulated_time
441
        self.assertAlmostEqual(t4, t3)
442
443
    def test_bandwidth(self):
444
        from bzrlib.transport.sftp import SocketDelay
445
        sending = FakeSocket()
1874.1.9 by Carl Friedrich Bolz
Try to fix all the issues outline by john and Robert.
446
        receiving = SocketDelay(sending, 0, bandwidth=8.0/(1024*1024),
447
                                really_sleep=False)
1874.1.2 by Carl Friedrich Bolz
Refined the SocketDelay to charge latency only once per round-trip and to
448
        # check that simulated time is charged only per round-trip:
449
        t1 = SocketDelay.simulated_time
450
        receiving.send("connect")
451
        self.assertEqual(sending.recv(1024), "connect")
452
        sending.send("a" * 100)
453
        self.assertEqual(receiving.recv(1024), "a" * 100)
454
        t2 = SocketDelay.simulated_time
455
        self.assertAlmostEqual(t2 - t1, 100 + 7)
456
1874.1.3 by Carl Friedrich Bolz
Merge bzr.dev.
457
3815.2.4 by Martin Pool
merge fix for out-of-order SFTP readv
458
class ReadvFile(object):
459
    """An object that acts like Paramiko's SFTPFile.readv()"""
460
461
    def __init__(self, data):
462
        self._data = data
463
464
    def readv(self, requests):
465
        for start, length in requests:
466
            yield self._data[start:start+length]
467
468
3882.7.16 by Martin Pool
Update SFTP tests to accommodate progress reporting
469
def _null_report_activity(*a, **k):
470
    pass
471
472
3686.1.2 by John Arbash Meinel
Start moving the readv code into a helper.
473
class Test_SFTPReadvHelper(tests.TestCase):
474
3686.1.6 by John Arbash Meinel
Respond to Martin's review comments.
475
    def checkGetRequests(self, expected_requests, offsets):
4913.2.16 by John Arbash Meinel
Move bzrlib.tests.ParamikoFeature to bzrlib.tests.features.paramiko
476
        self.requireFeature(features.paramiko)
3882.7.16 by Martin Pool
Update SFTP tests to accommodate progress reporting
477
        helper = _mod_sftp._SFTPReadvHelper(offsets, 'artificial_test',
478
            _null_report_activity)
3686.1.2 by John Arbash Meinel
Start moving the readv code into a helper.
479
        self.assertEqual(expected_requests, helper._get_requests())
480
481
    def test__get_requests(self):
482
        # Small single requests become a single readv request
3686.1.6 by John Arbash Meinel
Respond to Martin's review comments.
483
        self.checkGetRequests([(0, 100)],
484
                              [(0, 20), (30, 50), (20, 10), (80, 20)])
3686.1.2 by John Arbash Meinel
Start moving the readv code into a helper.
485
        # Non-contiguous ranges are given as multiple requests
3686.1.6 by John Arbash Meinel
Respond to Martin's review comments.
486
        self.checkGetRequests([(0, 20), (30, 50)],
487
                              [(10, 10), (30, 20), (0, 10), (50, 30)])
3686.1.2 by John Arbash Meinel
Start moving the readv code into a helper.
488
        # Ranges larger than _max_request_size (32kB) are broken up into
489
        # multiple requests, even if it actually spans multiple logical
490
        # requests
3686.1.6 by John Arbash Meinel
Respond to Martin's review comments.
491
        self.checkGetRequests([(0, 32768), (32768, 32768), (65536, 464)],
492
                              [(0, 40000), (40000, 100), (40100, 1900),
493
                               (42000, 24000)])
3777.1.1 by Aaron Bentley
Use auth.conf for sftp
494
3815.2.4 by Martin Pool
merge fix for out-of-order SFTP readv
495
    def checkRequestAndYield(self, expected, data, offsets):
4913.2.16 by John Arbash Meinel
Move bzrlib.tests.ParamikoFeature to bzrlib.tests.features.paramiko
496
        self.requireFeature(features.paramiko)
3882.7.16 by Martin Pool
Update SFTP tests to accommodate progress reporting
497
        helper = _mod_sftp._SFTPReadvHelper(offsets, 'artificial_test',
498
            _null_report_activity)
3815.2.4 by Martin Pool
merge fix for out-of-order SFTP readv
499
        data_f = ReadvFile(data)
500
        result = list(helper.request_and_yield_offsets(data_f))
501
        self.assertEqual(expected, result)
502
503
    def test_request_and_yield_offsets(self):
504
        data = 'abcdefghijklmnopqrstuvwxyz'
505
        self.checkRequestAndYield([(0, 'a'), (5, 'f'), (10, 'klm')], data,
506
                                  [(0, 1), (5, 1), (10, 3)])
507
        # Should combine requests, and split them again
508
        self.checkRequestAndYield([(0, 'a'), (1, 'b'), (10, 'klm')], data,
509
                                  [(0, 1), (1, 1), (10, 3)])
510
        # Out of order requests. The requests should get combined, but then be
511
        # yielded out-of-order. We also need one that is at the end of a
512
        # previous range. See bug #293746
513
        self.checkRequestAndYield([(0, 'a'), (10, 'k'), (4, 'efg'), (1, 'bcd')],
514
                                  data, [(0, 1), (10, 1), (4, 3), (1, 3)])
515
3777.1.1 by Aaron Bentley
Use auth.conf for sftp
516
517
class TestUsesAuthConfig(TestCaseWithSFTPServer):
3777.1.4 by Aaron Bentley
bzr+ssh and sftp both use ssh scheme.
518
    """Test that AuthenticationConfig can supply default usernames."""
3777.1.1 by Aaron Bentley
Use auth.conf for sftp
519
3777.1.2 by Aaron Bentley
Make testing more thorough
520
    def get_transport_for_connection(self, set_config):
3777.1.1 by Aaron Bentley
Use auth.conf for sftp
521
        port = self.get_server()._listener.port
3777.1.2 by Aaron Bentley
Make testing more thorough
522
        if set_config:
523
            conf = config.AuthenticationConfig()
524
            conf._get_config().update(
3777.1.4 by Aaron Bentley
bzr+ssh and sftp both use ssh scheme.
525
                {'sftptest': {'scheme': 'ssh', 'port': port, 'user': 'bar'}})
3777.1.2 by Aaron Bentley
Make testing more thorough
526
            conf._save()
3777.1.1 by Aaron Bentley
Use auth.conf for sftp
527
        t = get_transport('sftp://localhost:%d' % port)
3777.1.2 by Aaron Bentley
Make testing more thorough
528
        # force a connection to be performed.
3777.1.1 by Aaron Bentley
Use auth.conf for sftp
529
        t.has('foo')
3777.1.2 by Aaron Bentley
Make testing more thorough
530
        return t
531
532
    def test_sftp_uses_config(self):
533
        t = self.get_transport_for_connection(set_config=True)
3777.1.1 by Aaron Bentley
Use auth.conf for sftp
534
        self.assertEqual('bar', t._get_credentials()[0])
3777.1.2 by Aaron Bentley
Make testing more thorough
535
536
    def test_sftp_is_none_if_no_config(self):
537
        t = self.get_transport_for_connection(set_config=False)
4304.2.1 by Vincent Ladeuil
Fix bug #367726 by reverting some default user handling introduced
538
        self.assertIs(None, t._get_credentials()[0])
4222.3.13 by Jelmer Vernooij
Add tests to ensure sftp and ftp don't prompt for usernames.
539
540
    def test_sftp_doesnt_prompt_username(self):
541
        stdout = tests.StringIOWrapper()
542
        ui.ui_factory = tests.TestUIFactory(stdin='joe\nfoo\n', stdout=stdout)
543
        t = self.get_transport_for_connection(set_config=False)
4304.2.1 by Vincent Ladeuil
Fix bug #367726 by reverting some default user handling introduced
544
        self.assertIs(None, t._get_credentials()[0])
4222.3.13 by Jelmer Vernooij
Add tests to ensure sftp and ftp don't prompt for usernames.
545
        # No prompts should've been printed, stdin shouldn't have been read
546
        self.assertEquals("", stdout.getvalue())
547
        self.assertEquals(0, ui.ui_factory.stdin.tell())