1
1
# Copyright (C) 2005 by Canonical Ltd
2
2
# -*- coding: utf-8 -*-
4
4
# This program is free software; you can redistribute it and/or modify
5
5
# it under the terms of the GNU General Public License as published by
6
6
# the Free Software Foundation; either version 2 of the License, or
7
7
# (at your option) any later version.
9
9
# This program is distributed in the hope that it will be useful,
10
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
12
# GNU General Public License for more details.
14
14
# You should have received a copy of the GNU General Public License
15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
# Mr. Smoketoomuch: I'm sorry?
19
# Mr. Bounder: You'd better cut down a little then.
20
# Mr. Smoketoomuch: Oh, I see! Smoke too much so I'd better cut down a little
23
19
"""Black-box tests for bzr.
25
21
These check that it behaves properly when it's invoked through the regular
26
command-line interface. This doesn't actually run a new interpreter but
27
rather starts again from the run_bzr function.
22
command-line interface.
24
This always reinvokes bzr through a new Python interpreter, which is a
25
bit inefficient but arguably tests in a way more representative of how
26
it's normally invoked.
31
# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
32
# Note: Please don't add new tests here, it's too big and bulky. Instead add
33
# them into small suites in bzrlib.tests.blackbox.test_FOO for the particular
34
# UI command/aspect that is being tested.
37
from cStringIO import StringIO
32
from bzrlib.selftest import TestCaseInTempDir, BzrTestBase
43
33
from bzrlib.branch import Branch
44
import bzrlib.bzrdir as bzrdir
45
from bzrlib.errors import BzrCommandError
46
from bzrlib.osutils import (
52
from bzrlib.tests.HTTPTestUtil import TestCaseWithWebserver
53
from bzrlib.tests.test_sftp_transport import TestCaseWithSFTPServer
54
from bzrlib.tests.blackbox import ExternalBase
55
from bzrlib.workingtree import WorkingTree
34
from bzrlib.commands import run_bzr
37
class ExternalBase(TestCaseInTempDir):
38
def runbzr(self, args, retcode=0,backtick=False):
39
if isinstance(args, basestring):
43
return self.backtick(['python', self.BZRPATH,] + args,
46
return self.runcmd(['python', self.BZRPATH,] + args,
58
50
class TestCommands(ExternalBase):
60
def test_nick_command(self):
61
"""bzr nick for viewing, setting nicknames"""
52
def test_help_commands(self):
55
self.runbzr('help commands')
56
self.runbzr('help help')
57
self.runbzr('commit -h')
59
def test_init_branch(self):
62
def test_whoami(self):
63
# this should always identify something, if only "john@localhost"
65
self.runbzr("whoami --email")
67
self.assertEquals(self.runbzr("whoami --email",
68
backtick=True).count('@'), 1)
70
def test_whoami_branch(self):
71
"""branch specific user identity works."""
64
72
self.runbzr('init')
65
nick = self.runbzr("nick",backtick=True)
66
self.assertEqual(nick, 'me.dev\n')
67
nick = self.runbzr("nick moo")
68
nick = self.runbzr("nick",backtick=True)
69
self.assertEqual(nick, 'moo\n')
73
f = file('.bzr/email', 'wt')
74
f.write('Branch Identity <branch@identi.ty>')
76
whoami = self.runbzr("whoami",backtick=True)
77
whoami_email = self.runbzr("whoami --email",backtick=True)
78
self.assertTrue(whoami.startswith('Branch Identity <branch@identi.ty>'))
79
self.assertTrue(whoami_email.startswith('branch@identi.ty'))
71
81
def test_invalid_commands(self):
72
self.runbzr("pants", retcode=3)
73
self.runbzr("--pants off", retcode=3)
74
self.runbzr("diff --message foo", retcode=3)
82
self.runbzr("pants", retcode=1)
83
self.runbzr("--pants off", retcode=1)
84
self.runbzr("diff --message foo", retcode=1)
86
def test_empty_commit(self):
88
self.build_tree(['hello.txt'])
89
self.runbzr("commit -m empty", retcode=1)
90
self.runbzr("add hello.txt")
91
self.runbzr("commit -m added")
93
def test_ignore_patterns(self):
94
from bzrlib.branch import Branch
96
b = Branch('.', init=True)
97
self.assertEquals(list(b.unknowns()), [])
99
file('foo.tmp', 'wt').write('tmp files are ignored')
100
self.assertEquals(list(b.unknowns()), [])
101
assert self.backtick('bzr unknowns') == ''
103
file('foo.c', 'wt').write('int main() {}')
104
self.assertEquals(list(b.unknowns()), ['foo.c'])
105
assert self.backtick('bzr unknowns') == 'foo.c\n'
107
self.runbzr(['add', 'foo.c'])
108
assert self.backtick('bzr unknowns') == ''
110
# 'ignore' works when creating the .bzignore file
111
file('foo.blah', 'wt').write('blah')
112
self.assertEquals(list(b.unknowns()), ['foo.blah'])
113
self.runbzr('ignore *.blah')
114
self.assertEquals(list(b.unknowns()), [])
115
assert file('.bzrignore', 'rb').read() == '*.blah\n'
117
# 'ignore' works when then .bzrignore file already exists
118
file('garh', 'wt').write('garh')
119
self.assertEquals(list(b.unknowns()), ['garh'])
120
assert self.backtick('bzr unknowns') == 'garh\n'
121
self.runbzr('ignore garh')
122
self.assertEquals(list(b.unknowns()), [])
123
assert file('.bzrignore', 'rb').read() == '*.blah\ngarh\n'
76
125
def test_revert(self):
77
126
self.runbzr('init')
147
184
test.runbzr('add goodbye')
148
185
test.runbzr('commit -m setup goodbye')
150
def test_export(self):
153
self.example_branch()
154
self.runbzr('export ../latest')
155
self.assertEqual(file('../latest/goodbye', 'rt').read(), 'baz')
156
self.runbzr('export ../first -r 1')
157
self.assert_(not os.path.exists('../first/goodbye'))
158
self.assertEqual(file('../first/hello', 'rt').read(), 'foo')
159
self.runbzr('export ../first.gz -r 1')
160
self.assertEqual(file('../first.gz/hello', 'rt').read(), 'foo')
161
self.runbzr('export ../first.bz2 -r 1')
162
self.assertEqual(file('../first.bz2/hello', 'rt').read(), 'foo')
164
from tarfile import TarFile
165
self.runbzr('export ../first.tar -r 1')
166
self.assert_(os.path.isfile('../first.tar'))
167
tf = TarFile('../first.tar')
168
self.assert_('first/hello' in tf.getnames(), tf.getnames())
169
self.assertEqual(tf.extractfile('first/hello').read(), 'foo')
170
self.runbzr('export ../first.tar.gz -r 1')
171
self.assert_(os.path.isfile('../first.tar.gz'))
172
self.runbzr('export ../first.tbz2 -r 1')
173
self.assert_(os.path.isfile('../first.tbz2'))
174
self.runbzr('export ../first.tar.bz2 -r 1')
175
self.assert_(os.path.isfile('../first.tar.bz2'))
176
self.runbzr('export ../first.tar.tbz2 -r 1')
177
self.assert_(os.path.isfile('../first.tar.tbz2'))
179
from bz2 import BZ2File
180
tf = TarFile('../first.tar.tbz2',
181
fileobj=BZ2File('../first.tar.tbz2', 'r'))
182
self.assert_('first.tar/hello' in tf.getnames(), tf.getnames())
183
self.assertEqual(tf.extractfile('first.tar/hello').read(), 'foo')
184
self.runbzr('export ../first2.tar -r 1 --root pizza')
185
tf = TarFile('../first2.tar')
186
self.assert_('pizza/hello' in tf.getnames(), tf.getnames())
188
from zipfile import ZipFile
189
self.runbzr('export ../first.zip -r 1')
190
self.failUnlessExists('../first.zip')
191
zf = ZipFile('../first.zip')
192
self.assert_('first/hello' in zf.namelist(), zf.namelist())
193
self.assertEqual(zf.read('first/hello'), 'foo')
195
self.runbzr('export ../first2.zip -r 1 --root pizza')
196
zf = ZipFile('../first2.zip')
197
self.assert_('pizza/hello' in zf.namelist(), zf.namelist())
199
self.runbzr('export ../first-zip --format=zip -r 1')
200
zf = ZipFile('../first-zip')
201
self.assert_('first-zip/hello' in zf.namelist(), zf.namelist())
203
def test_inventory(self):
205
def output_equals(value, *args):
206
out = self.runbzr(['inventory'] + list(args), backtick=True)
207
self.assertEquals(out, value)
210
open('a', 'wb').write('hello\n')
216
output_equals('a\n', '--kind', 'file')
217
output_equals('b\n', '--kind', 'directory')
219
def test_pull_verbose(self):
220
"""Pull changes from one branch to another and watch the output."""
226
self.example_branch()
231
open('b', 'wb').write('else\n')
233
bzr(['commit', '-m', 'added b'])
236
out = bzr('pull --verbose ../b', backtick=True)
237
self.failIfEqual(out.find('Added Revisions:'), -1)
238
self.failIfEqual(out.find('message:\n added b'), -1)
239
self.failIfEqual(out.find('added b'), -1)
241
# Check that --overwrite --verbose prints out the removed entries
242
bzr('commit -m foo --unchanged')
244
bzr('commit -m baz --unchanged')
245
bzr('pull ../a', retcode=3)
246
out = bzr('pull --overwrite --verbose ../a', backtick=1)
248
remove_loc = out.find('Removed Revisions:')
249
self.failIfEqual(remove_loc, -1)
250
added_loc = out.find('Added Revisions:')
251
self.failIfEqual(added_loc, -1)
253
removed_message = out.find('message:\n baz')
254
self.failIfEqual(removed_message, -1)
255
self.failUnless(remove_loc < removed_message < added_loc)
257
added_message = out.find('message:\n foo')
258
self.failIfEqual(added_message, -1)
259
self.failUnless(added_loc < added_message)
261
def test_locations(self):
262
"""Using and remembering different locations"""
266
self.runbzr('commit -m unchanged --unchanged')
267
self.runbzr('pull', retcode=3)
268
self.runbzr('merge', retcode=3)
269
self.runbzr('branch . ../b')
272
self.runbzr('branch . ../c')
273
self.runbzr('pull ../c')
187
def test_revert(self):
188
self.example_branch()
189
file('hello', 'wt').write('bar')
190
file('goodbye', 'wt').write('qux')
191
self.runbzr('revert hello')
192
self.check_file_contents('hello', 'foo')
193
self.check_file_contents('goodbye', 'qux')
194
self.runbzr('revert')
195
self.check_file_contents('goodbye', 'baz')
197
def test_merge(self):
198
from bzrlib.branch import Branch
202
self.example_branch()
204
self.runbzr('branch a b')
206
file('goodbye', 'wt').write('quux')
207
self.runbzr(['commit', '-m', "more u's are always good"])
210
file('hello', 'wt').write('quuux')
211
# We can't merge when there are in-tree changes
212
self.runbzr('merge ../b', retcode=1)
213
self.runbzr(['commit', '-m', "Like an epidemic of u's"])
214
self.runbzr('merge ../b')
215
self.check_file_contents('goodbye', 'quux')
216
# Merging a branch pulls its revision into the tree
219
a.get_revision_xml(b.last_patch())
220
self.log('pending merges: %s', a.pending_merges())
221
# assert a.pending_merges() == [b.last_patch()], "Assertion %s %s" \
222
# % (a.pending_merges(), b.last_patch())
225
"""Pull changes from one branch to another."""
229
self.example_branch()
230
self.runbzr('pull', retcode=1)
231
self.runbzr('missing', retcode=1)
232
self.runbzr('missing .')
233
self.runbzr('missing')
235
self.runbzr('pull /', retcode=1)
239
self.runbzr('branch a b')
242
self.runbzr('commit -m blah --unchanged')
246
assert a.revision_history() == b.revision_history()[:-1]
276
247
self.runbzr('pull ../b')
278
self.runbzr('pull ../c')
279
self.runbzr('branch ../c ../d')
285
self.runbzr('pull', retcode=3)
286
self.runbzr('pull ../a --remember')
289
def test_unknown_command(self):
290
"""Handling of unknown command."""
291
out, err = self.run_bzr_captured(['fluffy-badger'],
293
self.assertEquals(out, '')
294
err.index('unknown command')
296
def create_conflicts(self):
297
"""Create a conflicted tree"""
300
file('hello', 'wb').write("hi world")
301
file('answer', 'wb').write("42")
304
self.runbzr('commit -m base')
305
self.runbzr('branch . ../other')
306
self.runbzr('branch . ../this')
308
file('hello', 'wb').write("Hello.")
309
file('answer', 'wb').write("Is anyone there?")
310
self.runbzr('commit -m other')
312
file('hello', 'wb').write("Hello, world")
313
self.runbzr('mv answer question')
314
file('question', 'wb').write("What do you get when you multiply six"
316
self.runbzr('commit -m this')
318
def test_status(self):
322
self.runbzr('commit --unchanged --message f')
323
self.runbzr('branch . ../branch2')
324
self.runbzr('branch . ../branch3')
325
self.runbzr('commit --unchanged --message peter')
326
os.chdir('../branch2')
327
self.runbzr('merge ../branch1')
328
self.runbzr('commit --unchanged --message pumpkin')
329
os.chdir('../branch3')
330
self.runbzr('merge ../branch2')
331
message = self.capture('status')
334
def test_conflicts(self):
335
"""Handling of merge conflicts"""
336
self.create_conflicts()
337
self.runbzr('merge ../other --show-base', retcode=1)
338
conflict_text = file('hello').read()
339
self.assert_('<<<<<<<' in conflict_text)
340
self.assert_('>>>>>>>' in conflict_text)
341
self.assert_('=======' in conflict_text)
342
self.assert_('|||||||' in conflict_text)
343
self.assert_('hi world' in conflict_text)
344
self.runbzr('revert')
345
self.runbzr('resolve --all')
346
self.runbzr('merge ../other', retcode=1)
347
conflict_text = file('hello').read()
348
self.assert_('|||||||' not in conflict_text)
349
self.assert_('hi world' not in conflict_text)
350
result = self.runbzr('conflicts', backtick=1)
351
self.assertEquals(result, "Text conflict in hello\nText conflict in"
353
result = self.runbzr('status', backtick=1)
354
self.assert_("conflicts:\n Text conflict in hello\n"
355
" Text conflict in question\n" in result, result)
356
self.runbzr('resolve hello')
357
result = self.runbzr('conflicts', backtick=1)
358
self.assertEquals(result, "Text conflict in question\n")
359
self.runbzr('commit -m conflicts', retcode=3)
360
self.runbzr('resolve --all')
361
result = self.runbzr('conflicts', backtick=1)
362
self.runbzr('commit -m conflicts')
363
self.assertEquals(result, "")
366
# create a source branch
367
os.mkdir('my-branch')
368
os.chdir('my-branch')
369
self.example_branch()
371
# with no push target, fail
372
self.runbzr('push', retcode=3)
373
# with an explicit target work
374
self.runbzr('push ../output-branch')
375
# with an implicit target work
378
self.runbzr('missing ../output-branch')
379
# advance this branch
380
self.runbzr('commit --unchanged -m unchanged')
382
os.chdir('../output-branch')
383
# There is no longer a difference as long as we have
384
# access to the working tree
387
# But we should be missing a revision
388
self.runbzr('missing ../my-branch', retcode=1)
390
# diverge the branches
391
self.runbzr('commit --unchanged -m unchanged')
392
os.chdir('../my-branch')
394
self.runbzr('push', retcode=3)
395
# and there are difference
396
self.runbzr('missing ../output-branch', retcode=1)
397
self.runbzr('missing --verbose ../output-branch', retcode=1)
398
# but we can force a push
399
self.runbzr('push --overwrite')
401
self.runbzr('missing ../output-branch')
403
# pushing to a new dir with no parent should fail
404
self.runbzr('push ../missing/new-branch', retcode=3)
405
# unless we provide --create-prefix
406
self.runbzr('push --create-prefix ../missing/new-branch')
408
self.runbzr('missing ../missing/new-branch')
410
def test_external_command(self):
411
"""Test that external commands can be run by setting the path
413
# We don't at present run bzr in a subprocess for blackbox tests, and so
414
# don't really capture stdout, only the internal python stream.
415
# Therefore we don't use a subcommand that produces any output or does
416
# anything -- we just check that it can be run successfully.
417
cmd_name = 'test-command'
418
if sys.platform == 'win32':
420
oldpath = os.environ.get('BZRPATH', None)
423
if 'BZRPATH' in os.environ:
424
del os.environ['BZRPATH']
426
f = file(cmd_name, 'wb')
427
if sys.platform == 'win32':
428
f.write('@echo off\n')
430
f.write('#!/bin/sh\n')
431
# f.write('echo Hello from test-command')
433
os.chmod(cmd_name, 0755)
435
# It should not find the command in the local
436
# directory by default, since it is not in my path
437
bzr(cmd_name, retcode=3)
439
# Now put it into my path
440
os.environ['BZRPATH'] = '.'
444
# Make sure empty path elements are ignored
445
os.environ['BZRPATH'] = os.pathsep
447
bzr(cmd_name, retcode=3)
451
os.environ['BZRPATH'] = oldpath
454
def listdir_sorted(dir):
248
assert a.revision_history() == b.revision_history()
249
self.runbzr('commit -m blah2 --unchanged')
251
self.runbzr('commit -m blah3 --unchanged')
252
self.runbzr('pull ../a', retcode=1)
254
self.runbzr('merge ../b')
255
self.runbzr('commit -m blah4 --unchanged')
257
self.runbzr('pull ../a')
258
assert a.revision_history()[-1] == b.revision_history()[-1]
261
def test_add_reports(self):
262
"""add command prints the names of added files."""
263
b = Branch('.', init=True)
264
self.build_tree(['top.txt', 'dir/', 'dir/sub.txt'])
266
from cStringIO import StringIO
269
ret = self.apply_redirected(None, out, None,
272
self.assertEquals(ret, 0)
274
# the ordering is not defined at the moment
275
results = sorted(out.getvalue().rstrip('\n').split('\n'))
276
self.assertEquals(['added dir',
460
282
class OldTests(ExternalBase):
482
304
f.write('hello world!\n')
485
self.assertEquals(capture('unknowns'), 'test.txt\n')
487
out = capture("status")
488
self.assertEquals(out, 'unknown:\n test.txt\n')
307
out = backtick("bzr unknowns")
308
self.assertEquals(out, 'test.txt\n')
310
out = backtick("bzr status")
311
assert out == 'unknown:\n test.txt\n'
313
out = backtick("bzr status --all")
314
assert out == "unknown:\n test.txt\n"
316
out = backtick("bzr status test.txt --all")
317
assert out == "unknown:\n test.txt\n"
490
319
f = file('test2.txt', 'wt')
491
320
f.write('goodbye cruel world...\n')
494
out = capture("status test.txt")
495
self.assertEquals(out, "unknown:\n test.txt\n")
323
out = backtick("bzr status test.txt")
324
assert out == "unknown:\n test.txt\n"
497
out = capture("status")
498
self.assertEquals(out, ("unknown:\n" " test.txt\n" " test2.txt\n"))
326
out = backtick("bzr status")
327
assert out == ("unknown:\n"
500
331
os.unlink('test2.txt')
502
333
progress("command aliases")
504
self.assertEquals(out, ("unknown:\n" " test.txt\n"))
334
out = backtick("bzr st --all")
335
assert out == ("unknown:\n"
506
out = capture("stat")
507
self.assertEquals(out, ("unknown:\n" " test.txt\n"))
338
out = backtick("bzr stat")
339
assert out == ("unknown:\n"
509
342
progress("command help")
510
343
runbzr("help st")
512
345
runbzr("help commands")
513
runbzr("help slartibartfast", 3)
346
runbzr("help slartibartfast", 1)
515
out = capture("help ci")
348
out = backtick("bzr help ci")
516
349
out.index('aliases: ')
351
progress("can't rename unversioned file")
352
runbzr("rename test.txt new-test.txt", 1)
354
progress("adding a file")
356
runbzr("add test.txt")
357
assert backtick("bzr unknowns") == ''
358
assert backtick("bzr status --all") == ("added:\n"
361
progress("rename newly-added file")
362
runbzr("rename test.txt hello.txt")
363
assert os.path.exists("hello.txt")
364
assert not os.path.exists("test.txt")
366
assert backtick("bzr revno") == '0\n'
368
progress("add first revision")
369
runbzr(['commit', '-m', 'add first revision'])
371
progress("more complex renames")
373
runbzr("rename hello.txt sub1", 1)
374
runbzr("rename hello.txt sub1/hello.txt", 1)
375
runbzr("move hello.txt sub1", 1)
378
runbzr("rename sub1 sub2")
379
runbzr("move hello.txt sub2")
380
assert backtick("bzr relpath sub2/hello.txt") == os.path.join("sub2", "hello.txt\n")
382
assert exists("sub2")
383
assert exists("sub2/hello.txt")
384
assert not exists("sub1")
385
assert not exists("hello.txt")
387
runbzr(['commit', '-m', 'commit with some things moved to subdirs'])
391
runbzr('move sub2/hello.txt sub1')
392
assert not exists('sub2/hello.txt')
393
assert exists('sub1/hello.txt')
394
runbzr('move sub2 sub1')
395
assert not exists('sub2')
396
assert exists('sub1/sub2')
398
runbzr(['commit', '-m', 'rename nested subdirectories'])
401
self.assertEquals(backtick('bzr root')[:-1],
402
os.path.join(self.test_dir, 'branch1'))
403
runbzr('move ../hello.txt .')
404
assert exists('./hello.txt')
405
assert backtick('bzr relpath hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
406
assert backtick('bzr relpath ../../sub1/sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
407
runbzr(['commit', '-m', 'move to parent directory'])
409
assert backtick('bzr relpath sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
411
runbzr('move sub2/hello.txt .')
412
assert exists('hello.txt')
518
414
f = file('hello.txt', 'wt')
519
415
f.write('some nice new content\n')
522
runbzr("add hello.txt")
524
418
f = file('msg.tmp', 'wt')
525
f.write('this is my new commit\nand it has multiple lines, for fun')
419
f.write('this is my new commit\n')
528
422
runbzr('commit -F msg.tmp')
530
self.assertEquals(capture('revno'), '1\n')
531
runbzr('export -r 1 export-1.tmp')
424
assert backtick('bzr revno') == '5\n'
425
runbzr('export -r 5 export-5.tmp')
532
426
runbzr('export export.tmp')
536
430
runbzr('log -v --forward')
537
runbzr('log -m', retcode=3)
538
log_out = capture('log -m commit')
539
self.assert_("this is my new commit\n and" in log_out)
540
self.assert_("rename nested" not in log_out)
541
self.assert_('revision-id' not in log_out)
542
self.assert_('revision-id' in capture('log --show-ids -m commit'))
431
runbzr('log -m', retcode=1)
432
log_out = backtick('bzr log -m commit')
433
assert "this is my new commit" in log_out
434
assert "rename nested" not in log_out
435
assert 'revision-id' not in log_out
436
assert 'revision-id' in backtick('bzr log --show-ids -m commit')
544
log_out = capture('log --line')
545
# determine the widest line we want
546
max_width = terminal_width() - 1
547
for line in log_out.splitlines():
548
self.assert_(len(line) <= max_width, len(line))
549
self.assert_("this is my new commit and" not in log_out)
550
self.assert_("this is my new commit" in log_out)
552
439
progress("file with spaces in name")
553
440
mkdir('sub directory')
554
441
file('sub directory/file with spaces ', 'wt').write('see how this works\n')
556
runbzr('diff', retcode=1)
557
444
runbzr('commit -m add-spaces')
570
os.symlink("NOWHERE1", "link1")
572
self.assertEquals(self.capture('unknowns'), '')
573
runbzr(['commit', '-m', '1: added symlink link1'])
577
self.assertEquals(self.capture('unknowns'), '')
578
os.symlink("NOWHERE2", "d1/link2")
579
self.assertEquals(self.capture('unknowns'), 'd1/link2\n')
580
# is d1/link2 found when adding d1
582
self.assertEquals(self.capture('unknowns'), '')
583
os.symlink("NOWHERE3", "d1/link3")
584
self.assertEquals(self.capture('unknowns'), 'd1/link3\n')
585
runbzr(['commit', '-m', '2: added dir, symlink'])
587
runbzr('rename d1 d2')
588
runbzr('move d2/link2 .')
589
runbzr('move link1 d2')
590
self.assertEquals(os.readlink("./link2"), "NOWHERE2")
591
self.assertEquals(os.readlink("d2/link1"), "NOWHERE1")
592
runbzr('add d2/link3')
593
runbzr('diff', retcode=1)
594
runbzr(['commit', '-m', '3: rename of dir, move symlinks, add link3'])
597
os.symlink("TARGET 2", "link2")
598
os.unlink("d2/link1")
599
os.symlink("TARGET 1", "d2/link1")
600
runbzr('diff', retcode=1)
601
self.assertEquals(self.capture("relpath d2/link1"), "d2/link1\n")
602
runbzr(['commit', '-m', '4: retarget of two links'])
604
runbzr('remove d2/link1')
605
self.assertEquals(self.capture('unknowns'), 'd2/link1\n')
606
runbzr(['commit', '-m', '5: remove d2/link1'])
607
# try with the rm alias
608
runbzr('add d2/link1')
609
runbzr(['commit', '-m', '6: add d2/link1'])
610
runbzr('rm d2/link1')
611
self.assertEquals(self.capture('unknowns'), 'd2/link1\n')
612
runbzr(['commit', '-m', '7: remove d2/link1'])
616
runbzr('rename d2/link3 d1/link3new')
617
self.assertEquals(self.capture('unknowns'), 'd2/link1\n')
618
runbzr(['commit', '-m', '8: remove d2/link1, move/rename link3'])
622
runbzr(['export', '-r', '1', 'exp1.tmp'])
624
self.assertEquals(listdir_sorted("."), [ "link1" ])
625
self.assertEquals(os.readlink("link1"), "NOWHERE1")
628
runbzr(['export', '-r', '2', 'exp2.tmp'])
630
self.assertEquals(listdir_sorted("."), [ "d1", "link1" ])
633
runbzr(['export', '-r', '3', 'exp3.tmp'])
635
self.assertEquals(listdir_sorted("."), [ "d2", "link2" ])
636
self.assertEquals(listdir_sorted("d2"), [ "link1", "link3" ])
637
self.assertEquals(os.readlink("d2/link1"), "NOWHERE1")
638
self.assertEquals(os.readlink("link2") , "NOWHERE2")
641
runbzr(['export', '-r', '4', 'exp4.tmp'])
643
self.assertEquals(listdir_sorted("."), [ "d2", "link2" ])
644
self.assertEquals(os.readlink("d2/link1"), "TARGET 1")
645
self.assertEquals(os.readlink("link2") , "TARGET 2")
646
self.assertEquals(listdir_sorted("d2"), [ "link1", "link3" ])
649
runbzr(['export', '-r', '5', 'exp5.tmp'])
651
self.assertEquals(listdir_sorted("."), [ "d2", "link2" ])
652
self.assert_(os.path.islink("link2"))
653
self.assert_(listdir_sorted("d2")== [ "link3" ])
656
runbzr(['export', '-r', '8', 'exp6.tmp'])
658
self.assertEqual(listdir_sorted("."), [ "d1", "d2", "link2"])
659
self.assertEquals(listdir_sorted("d1"), [ "link3new" ])
660
self.assertEquals(listdir_sorted("d2"), [])
661
self.assertEquals(os.readlink("d1/link3new"), "NOWHERE3")
664
progress("skipping symlink tests")
667
class RemoteTests(object):
668
"""Test bzr ui commands against remote branches."""
670
def test_branch(self):
672
wt = self.make_branch_and_tree('from')
674
wt.commit('empty commit for nonsense', allow_pointless=True)
675
url = self.get_readonly_url('from')
676
self.run_bzr('branch', url, 'to')
677
branch = Branch.open('to')
678
self.assertEqual(1, len(branch.revision_history()))
679
# the branch should be set in to to from
680
self.assertEqual(url + '/', branch.get_parent())
683
self.build_tree(['branch/', 'branch/file'])
684
self.capture('init branch')
685
self.capture('add branch/file')
686
self.capture('commit -m foo branch')
687
url = self.get_readonly_url('branch/file')
688
output = self.capture('log %s' % url)
689
self.assertEqual(8, len(output.split('\n')))
691
def test_check(self):
692
self.build_tree(['branch/', 'branch/file'])
693
self.capture('init branch')
694
self.capture('add branch/file')
695
self.capture('commit -m foo branch')
696
url = self.get_readonly_url('branch/')
697
self.run_bzr('check', url)
700
# create a source branch
701
os.mkdir('my-branch')
702
os.chdir('my-branch')
704
file('hello', 'wt').write('foo')
705
self.run_bzr('add', 'hello')
706
self.run_bzr('commit', '-m', 'setup')
708
# with an explicit target work
709
self.run_bzr('push', self.get_url('output-branch'))
712
class HTTPTests(TestCaseWithWebserver, RemoteTests):
713
"""Test various commands against a HTTP server."""
716
class SFTPTestsAbsolute(TestCaseWithSFTPServer, RemoteTests):
717
"""Test various commands against a SFTP server using abs paths."""
720
class SFTPTestsAbsoluteSibling(TestCaseWithSFTPServer, RemoteTests):
721
"""Test various commands against a SFTP server using abs paths."""
724
super(SFTPTestsAbsoluteSibling, self).setUp()
725
self._override_home = '/dev/noone/runs/tests/here'
728
class SFTPTestsRelative(TestCaseWithSFTPServer, RemoteTests):
729
"""Test various commands against a SFTP server using homedir rel paths."""
732
super(SFTPTestsRelative, self).setUp()
733
self._get_remote_is_absolute = False