~bzr-pqm/bzr/bzr.dev

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