91
105
TestCaseInTempDir.setUp(self)
92
106
self._root = self.test_dir
107
self._is_setup = False
109
def delayed_setup(self):
110
# some tests are just stubs that call setUp and then immediately call
111
# tearDwon. so don't create the port listener until get_transport is
112
# called and we know we're in an actual test.
94
115
self._listener = SingleListener(self._run_server)
95
116
self._listener.setDaemon(True)
96
117
self._listener.start()
97
118
self._sftp_url = 'sftp://foo:bar@localhost:%d/' % (self._listener.port,)
119
self._is_setup = True
99
121
def tearDown(self):
100
self._listener.stop()
123
self._listener.stop()
124
except AttributeError:
101
126
TestCaseInTempDir.tearDown(self)
104
129
class SFTPTransportTest (TestCaseWithSFTPServer, TestTransportMixIn):
133
TestCaseWithSFTPServer.setUp(self)
136
def log(self, *args):
137
"""Override the default log to grab sftp server messages"""
138
TestCaseWithSFTPServer.log(self, *args)
139
if args and args[0].startswith('sftpserver'):
140
self.sftplogs.append(args[0])
107
142
def get_transport(self):
108
144
from bzrlib.transport.sftp import SFTPTransport
109
145
url = self._sftp_url
110
146
return SFTPTransport(url)
148
def test_sftp_locks(self):
149
from bzrlib.errors import LockError
150
t = self.get_transport()
152
l = t.lock_write('bogus')
153
self.failUnlessExists('bogus.write-lock')
155
# Don't wait for the lock, locking an already locked
156
# file should raise an assert
157
self.assertRaises(LockError, t.lock_write, 'bogus')
160
self.failIf(os.path.lexists('bogus.write-lock'))
162
open('something.write-lock', 'wb').write('fake lock\n')
163
self.assertRaises(LockError, t.lock_write, 'something')
164
os.remove('something.write-lock')
166
l = t.lock_write('something')
168
l2 = t.lock_write('bogus')
173
def test_multiple_connections(self):
174
t = self.get_transport()
175
self.assertEquals(self.sftplogs,
176
['sftpserver - authorizing: foo'
177
, 'sftpserver - channel request: session, 1'])
179
# The second request should reuse the first connection
180
# SingleListener only allows for a single connection,
181
# So the next line fails unless the connection is reused
182
t2 = self.get_transport()
183
self.assertEquals(self.sftplogs, [])
186
class FakeSFTPTransport (object):
188
fake = FakeSFTPTransport()
191
class SFTPNonServerTest(TestCase):
192
def test_parse_url(self):
193
from bzrlib.transport.sftp import SFTPTransport
194
s = SFTPTransport('sftp://simple.example.com/%2fhome/source', clone_from=fake)
195
self.assertEquals(s._host, 'simple.example.com')
196
self.assertEquals(s._port, None)
197
self.assertEquals(s._path, '/home/source')
198
self.failUnless(s._password is None)
200
self.assertEquals(s.base, 'sftp://simple.example.com/%2Fhome/source')
202
s = SFTPTransport('sftp://ro%62ey:h%40t@example.com:2222/relative', clone_from=fake)
203
self.assertEquals(s._host, 'example.com')
204
self.assertEquals(s._port, 2222)
205
self.assertEquals(s._username, 'robey')
206
self.assertEquals(s._password, 'h@t')
207
self.assertEquals(s._path, 'relative')
209
# Base should not keep track of the password
210
self.assertEquals(s.base, 'sftp://robey@example.com:2222/relative')
212
# Double slash should be accepted instead of using %2F
213
s = SFTPTransport('sftp://user@example.com:22//absolute/path', clone_from=fake)
214
self.assertEquals(s._host, 'example.com')
215
self.assertEquals(s._port, 22)
216
self.assertEquals(s._username, 'user')
217
self.assertEquals(s._password, None)
218
self.assertEquals(s._path, '/absolute/path')
220
# Also, don't show the port if it is the default 22
221
self.assertEquals(s.base, 'sftp://user@example.com:22/%2Fabsolute/path')
223
def test_relpath(self):
224
from bzrlib.transport.sftp import SFTPTransport
225
from bzrlib.errors import PathNotChild
227
s = SFTPTransport('sftp://user@host.com//abs/path', clone_from=fake)
228
self.assertEquals(s.relpath('sftp://user@host.com//abs/path/sub'), 'sub')
229
# Can't test this one, because we actually get an AssertionError
230
# TODO: Consider raising an exception rather than an assert
231
#self.assertRaises(PathNotChild, s.relpath, 'http://user@host.com//abs/path/sub')
232
self.assertRaises(PathNotChild, s.relpath, 'sftp://user2@host.com//abs/path/sub')
233
self.assertRaises(PathNotChild, s.relpath, 'sftp://user@otherhost.com//abs/path/sub')
234
self.assertRaises(PathNotChild, s.relpath, 'sftp://user@host.com:33//abs/path/sub')
235
self.assertRaises(PathNotChild, s.relpath, 'sftp://user@host.com/abs/path/sub')
237
# Make sure it works when we don't supply a username
238
s = SFTPTransport('sftp://host.com//abs/path', clone_from=fake)
239
self.assertEquals(s.relpath('sftp://host.com//abs/path/sub'), 'sub')
241
# Make sure it works when parts of the path will be url encoded
242
# TODO: These may be incorrect, we might need to urllib.urlencode() before
243
# we pass the paths into the SFTPTransport constructor
244
s = SFTPTransport('sftp://host.com/dev/,path', clone_from=fake)
245
self.assertEquals(s.relpath('sftp://host.com/dev/,path/sub'), 'sub')
246
s = SFTPTransport('sftp://host.com/dev/%path', clone_from=fake)
247
self.assertEquals(s.relpath('sftp://host.com/dev/%path/sub'), 'sub')
249
def test_parse_invalid_url(self):
250
from bzrlib.transport.sftp import SFTPTransport, TransportError
252
s = SFTPTransport('sftp://lilypond.org:~janneke/public_html/bzr/gub',
254
self.fail('expected exception not raised')
255
except TransportError, e:
256
self.assertEquals(str(e),
257
'~janneke: invalid port number')
260
class SFTPBranchTest(TestCaseWithSFTPServer):
261
"""Test some stuff when accessing a bzr Branch over sftp"""
263
def test_lock_file(self):
264
"""Make sure that a Branch accessed over sftp tries to lock itself."""
265
from bzrlib.branch import Branch
268
b = Branch.initialize(self._sftp_url)
269
self.failUnlessExists('.bzr/')
270
self.failUnlessExists('.bzr/branch-format')
271
self.failUnlessExists('.bzr/branch-lock')
273
self.failIf(os.path.lexists('.bzr/branch-lock.write-lock'))
275
self.failUnlessExists('.bzr/branch-lock.write-lock')
277
self.failIf(os.path.lexists('.bzr/branch-lock.write-lock'))
279
def test_no_working_tree(self):
280
from bzrlib.branch import Branch
282
b = Branch.initialize(self._sftp_url)
283
self.assertRaises(errors.NoWorkingTree, b.working_tree)
285
def test_push_support(self):
286
from bzrlib.branch import Branch
289
self.build_tree(['a/', 'a/foo'])
290
b = Branch.initialize('a')
293
t.commit('foo', rev_id='a1')
296
b2 = Branch.initialize(self._sftp_url + 'b')
299
self.assertEquals(b2.revision_history(), ['a1'])
112
302
if not paramiko_loaded:
113
304
del SFTPTransportTest
305
del SFTPNonServerTest