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
29
from cStringIO import StringIO
35
from bzrlib.selftest import TestCaseInTempDir, BzrTestBase
43
36
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
39
class ExternalBase(TestCaseInTempDir):
41
def runbzr(self, args, retcode=0, backtick=False):
42
if isinstance(args, basestring):
46
return self.run_bzr_captured(args, retcode=retcode)[0]
48
return self.run_bzr_captured(args, retcode=retcode)
58
51
class TestCommands(ExternalBase):
60
def test_nick_command(self):
61
"""bzr nick for viewing, setting nicknames"""
53
def test_help_commands(self):
56
self.runbzr('help commands')
57
self.runbzr('help help')
58
self.runbzr('commit -h')
60
def test_init_branch(self):
63
def test_whoami(self):
64
# this should always identify something, if only "john@localhost"
66
self.runbzr("whoami --email")
68
self.assertEquals(self.runbzr("whoami --email",
69
backtick=True).count('@'), 1)
71
def test_whoami_branch(self):
72
"""branch specific user identity works."""
64
73
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')
74
f = file('.bzr/email', 'wt')
75
f.write('Branch Identity <branch@identi.ty>')
77
bzr_email = os.environ.get('BZREMAIL')
78
if bzr_email is not None:
79
del os.environ['BZREMAIL']
80
whoami = self.runbzr("whoami",backtick=True)
81
whoami_email = self.runbzr("whoami --email",backtick=True)
82
self.assertTrue(whoami.startswith('Branch Identity <branch@identi.ty>'))
83
self.assertTrue(whoami_email.startswith('branch@identi.ty'))
84
# Verify that the environment variable overrides the value
86
os.environ['BZREMAIL'] = 'Different ID <other@environ.ment>'
87
whoami = self.runbzr("whoami",backtick=True)
88
whoami_email = self.runbzr("whoami --email",backtick=True)
89
self.assertTrue(whoami.startswith('Different ID <other@environ.ment>'))
90
self.assertTrue(whoami_email.startswith('other@environ.ment'))
91
if bzr_email is not None:
92
os.environ['BZREMAIL'] = bzr_email
71
94
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)
95
self.runbzr("pants", retcode=1)
96
self.runbzr("--pants off", retcode=1)
97
self.runbzr("diff --message foo", retcode=1)
99
def test_empty_commit(self):
101
self.build_tree(['hello.txt'])
102
self.runbzr("commit -m empty", retcode=1)
103
self.runbzr("add hello.txt")
104
self.runbzr("commit -m added")
106
def test_ignore_patterns(self):
107
from bzrlib.branch import Branch
109
b = Branch.initialize('.')
110
self.assertEquals(list(b.unknowns()), [])
112
file('foo.tmp', 'wt').write('tmp files are ignored')
113
self.assertEquals(list(b.unknowns()), [])
114
assert self.capture('unknowns') == ''
116
file('foo.c', 'wt').write('int main() {}')
117
self.assertEquals(list(b.unknowns()), ['foo.c'])
118
assert self.capture('unknowns') == 'foo.c\n'
120
self.runbzr(['add', 'foo.c'])
121
assert self.capture('unknowns') == ''
123
# 'ignore' works when creating the .bzignore file
124
file('foo.blah', 'wt').write('blah')
125
self.assertEquals(list(b.unknowns()), ['foo.blah'])
126
self.runbzr('ignore *.blah')
127
self.assertEquals(list(b.unknowns()), [])
128
assert file('.bzrignore', 'rU').read() == '*.blah\n'
130
# 'ignore' works when then .bzrignore file already exists
131
file('garh', 'wt').write('garh')
132
self.assertEquals(list(b.unknowns()), ['garh'])
133
assert self.capture('unknowns') == 'garh\n'
134
self.runbzr('ignore garh')
135
self.assertEquals(list(b.unknowns()), [])
136
assert file('.bzrignore', 'rU').read() == '*.blah\ngarh\n'
76
138
def test_revert(self):
77
139
self.runbzr('init')
154
221
self.runbzr('export ../latest')
155
222
self.assertEqual(file('../latest/goodbye', 'rt').read(), 'baz')
156
223
self.runbzr('export ../first -r 1')
157
self.assert_(not os.path.exists('../first/goodbye'))
224
assert not os.path.exists('../first/goodbye')
158
225
self.assertEqual(file('../first/hello', 'rt').read(), 'foo')
159
226
self.runbzr('export ../first.gz -r 1')
160
227
self.assertEqual(file('../first.gz/hello', 'rt').read(), 'foo')
161
228
self.runbzr('export ../first.bz2 -r 1')
162
229
self.assertEqual(file('../first.bz2/hello', 'rt').read(), 'foo')
230
self.runbzr('export ../first.tar -r 1')
231
assert os.path.isfile('../first.tar')
164
232
from tarfile import TarFile
165
self.runbzr('export ../first.tar -r 1')
166
self.assert_(os.path.isfile('../first.tar'))
167
233
tf = TarFile('../first.tar')
168
self.assert_('first/hello' in tf.getnames(), tf.getnames())
234
assert 'first/hello' in tf.getnames(), tf.getnames()
169
235
self.assertEqual(tf.extractfile('first/hello').read(), 'foo')
170
236
self.runbzr('export ../first.tar.gz -r 1')
171
self.assert_(os.path.isfile('../first.tar.gz'))
237
assert os.path.isfile('../first.tar.gz')
172
238
self.runbzr('export ../first.tbz2 -r 1')
173
self.assert_(os.path.isfile('../first.tbz2'))
239
assert os.path.isfile('../first.tbz2')
174
240
self.runbzr('export ../first.tar.bz2 -r 1')
175
self.assert_(os.path.isfile('../first.tar.bz2'))
241
assert os.path.isfile('../first.tar.bz2')
176
242
self.runbzr('export ../first.tar.tbz2 -r 1')
177
self.assert_(os.path.isfile('../first.tar.tbz2'))
243
assert os.path.isfile('../first.tar.tbz2')
179
244
from bz2 import BZ2File
180
245
tf = TarFile('../first.tar.tbz2',
181
246
fileobj=BZ2File('../first.tar.tbz2', 'r'))
182
self.assert_('first.tar/hello' in tf.getnames(), tf.getnames())
247
assert 'first.tar/hello' in tf.getnames(), tf.getnames()
183
248
self.assertEqual(tf.extractfile('first.tar/hello').read(), 'foo')
184
249
self.runbzr('export ../first2.tar -r 1 --root pizza')
185
250
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())
251
assert 'pizza/hello' in tf.getnames(), tf.getnames()
254
self.example_branch()
255
file('hello', 'wt').write('hello world!')
256
self.runbzr('commit -m fixing hello')
257
output = self.runbzr('diff -r 2..3', backtick=1)
258
self.assert_('\n+hello world!' in output)
259
output = self.runbzr('diff -r last:3..last:1', backtick=1)
260
self.assert_('\n+baz' in output)
262
def test_branch(self):
263
"""Branch from one branch to another."""
266
self.example_branch()
268
self.runbzr('branch a b')
269
self.runbzr('branch a c -r 1')
271
self.runbzr('commit -m foo --unchanged')
273
# naughty - abstraction violations RBC 20050928
274
print "test_branch used to delete the stores, how is this meant to work ?"
275
#shutil.rmtree('a/.bzr/revision-store')
276
#shutil.rmtree('a/.bzr/inventory-store', ignore_errors=True)
277
#shutil.rmtree('a/.bzr/text-store', ignore_errors=True)
278
self.runbzr('branch a d --basis b')
280
def test_merge(self):
281
from bzrlib.branch import Branch
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
285
self.example_branch()
287
self.runbzr('branch a b')
231
open('b', 'wb').write('else\n')
233
bzr(['commit', '-m', 'added b'])
289
file('goodbye', 'wt').write('quux')
290
self.runbzr(['commit', '-m', "more u's are always good"])
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"""
293
file('hello', 'wt').write('quuux')
294
# We can't merge when there are in-tree changes
295
self.runbzr('merge ../b', retcode=1)
296
self.runbzr(['commit', '-m', "Like an epidemic of u's"])
297
self.runbzr('merge ../b')
298
self.check_file_contents('goodbye', 'quux')
299
# Merging a branch pulls its revision into the tree
301
b = Branch.open('../b')
302
a.get_revision_xml(b.last_revision())
303
self.log('pending merges: %s', a.pending_merges())
304
# assert a.pending_merges() == [b.last_revision()], "Assertion %s %s" \
305
# % (a.pending_merges(), b.last_revision())
307
def test_merge_with_missing_file(self):
308
"""Merge handles missing file conflicts"""
312
print >> file('sub/a.txt', 'wb'), "hello"
313
print >> file('b.txt', 'wb'), "hello"
314
print >> file('sub/c.txt', 'wb'), "hello"
265
315
self.runbzr('init')
266
self.runbzr('commit -m unchanged --unchanged')
267
self.runbzr('pull', retcode=3)
268
self.runbzr('merge', retcode=3)
317
self.runbzr(('commit', '-m', 'added a'))
269
318
self.runbzr('branch . ../b')
272
self.runbzr('branch . ../c')
273
self.runbzr('pull ../c')
276
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')
319
print >> file('sub/a.txt', 'ab'), "there"
320
print >> file('b.txt', 'ab'), "there"
321
print >> file('sub/c.txt', 'ab'), "there"
322
self.runbzr(('commit', '-m', 'Added there'))
323
os.unlink('sub/a.txt')
324
os.unlink('sub/c.txt')
327
self.runbzr(('commit', '-m', 'Removed a.txt'))
329
print >> file('sub/a.txt', 'ab'), "something"
330
print >> file('b.txt', 'ab'), "something"
331
print >> file('sub/c.txt', 'ab'), "something"
332
self.runbzr(('commit', '-m', 'Modified a.txt'))
333
self.runbzr('merge ../a/')
334
assert os.path.exists('sub/a.txt.THIS')
335
assert os.path.exists('sub/a.txt.BASE')
337
self.runbzr('merge ../b/')
338
assert os.path.exists('sub/a.txt.OTHER')
339
assert os.path.exists('sub/a.txt.BASE')
342
"""Pull changes from one branch to another."""
346
self.example_branch()
347
self.runbzr('pull', retcode=1)
348
self.runbzr('missing', retcode=1)
349
self.runbzr('missing .')
350
self.runbzr('missing')
352
self.runbzr('pull /', retcode=1)
356
self.runbzr('branch a b')
360
self.runbzr('add subdir')
361
self.runbzr('commit -m blah --unchanged')
364
b = Branch.open('../b')
365
assert a.revision_history() == b.revision_history()[:-1]
366
self.runbzr('pull ../b')
367
assert a.revision_history() == b.revision_history()
368
self.runbzr('commit -m blah2 --unchanged')
370
self.runbzr('commit -m blah3 --unchanged')
371
self.runbzr('pull ../a', retcode=1)
372
print "DECIDE IF PULL CAN CONVERGE, blackbox.py"
375
self.runbzr('merge ../b')
376
self.runbzr('commit -m blah4 --unchanged')
377
os.chdir('../b/subdir')
378
self.runbzr('pull ../../a')
379
assert a.revision_history()[-1] == b.revision_history()[-1]
380
self.runbzr('commit -m blah5 --unchanged')
381
self.runbzr('commit -m blah6 --unchanged')
383
self.runbzr('pull ../a')
385
self.runbzr('commit -m blah7 --unchanged')
386
self.runbzr('merge ../b')
387
self.runbzr('commit -m blah8 --unchanged')
388
self.runbzr('pull ../b')
389
self.runbzr('pull ../b')
391
def test_add_reports(self):
392
"""add command prints the names of added files."""
393
b = Branch.initialize('.')
394
self.build_tree(['top.txt', 'dir/', 'dir/sub.txt'])
395
out = self.run_bzr_captured(['add'], retcode = 0)[0]
396
# the ordering is not defined at the moment
397
results = sorted(out.rstrip('\n').split('\n'))
398
self.assertEquals(['added dir',
399
'added dir'+os.sep+'sub.txt',
289
403
def test_unknown_command(self):
290
404
"""Handling of unknown command."""
291
405
out, err = self.run_bzr_captured(['fluffy-badger'],
293
407
self.assertEquals(out, '')
294
408
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 os.environ.has_key('BZRPATH'):
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
413
if hasattr(os, 'symlink'):
454
418
def listdir_sorted(dir):
455
419
L = os.listdir(dir)
485
449
self.assertEquals(capture('unknowns'), 'test.txt\n')
487
451
out = capture("status")
488
self.assertEquals(out, 'unknown:\n test.txt\n')
452
assert out == 'unknown:\n test.txt\n'
454
out = capture("status --all")
455
assert out == "unknown:\n test.txt\n"
457
out = capture("status test.txt --all")
458
assert out == "unknown:\n test.txt\n"
490
460
f = file('test2.txt', 'wt')
491
461
f.write('goodbye cruel world...\n')
494
464
out = capture("status test.txt")
495
self.assertEquals(out, "unknown:\n test.txt\n")
465
assert out == "unknown:\n test.txt\n"
497
467
out = capture("status")
498
self.assertEquals(out, ("unknown:\n" " test.txt\n" " test2.txt\n"))
468
assert out == ("unknown:\n"
500
472
os.unlink('test2.txt')
502
474
progress("command aliases")
504
self.assertEquals(out, ("unknown:\n" " test.txt\n"))
475
out = capture("st --all")
476
assert out == ("unknown:\n"
506
479
out = capture("stat")
507
self.assertEquals(out, ("unknown:\n" " test.txt\n"))
480
assert out == ("unknown:\n"
509
483
progress("command help")
510
484
runbzr("help st")
512
486
runbzr("help commands")
513
runbzr("help slartibartfast", 3)
487
runbzr("help slartibartfast", 1)
515
489
out = capture("help ci")
516
490
out.index('aliases: ')
492
progress("can't rename unversioned file")
493
runbzr("rename test.txt new-test.txt", 1)
495
progress("adding a file")
497
runbzr("add test.txt")
498
assert capture("unknowns") == ''
499
assert capture("status --all") == ("added:\n"
502
progress("rename newly-added file")
503
runbzr("rename test.txt hello.txt")
504
assert os.path.exists("hello.txt")
505
assert not os.path.exists("test.txt")
507
assert capture("revno") == '0\n'
509
progress("add first revision")
510
runbzr(['commit', '-m', 'add first revision'])
512
progress("more complex renames")
514
runbzr("rename hello.txt sub1", 1)
515
runbzr("rename hello.txt sub1/hello.txt", 1)
516
runbzr("move hello.txt sub1", 1)
519
runbzr("rename sub1 sub2")
520
runbzr("move hello.txt sub2")
521
assert capture("relpath sub2/hello.txt") == os.path.join("sub2", "hello.txt\n")
523
assert exists("sub2")
524
assert exists("sub2/hello.txt")
525
assert not exists("sub1")
526
assert not exists("hello.txt")
528
runbzr(['commit', '-m', 'commit with some things moved to subdirs'])
532
runbzr('move sub2/hello.txt sub1')
533
assert not exists('sub2/hello.txt')
534
assert exists('sub1/hello.txt')
535
runbzr('move sub2 sub1')
536
assert not exists('sub2')
537
assert exists('sub1/sub2')
539
runbzr(['commit', '-m', 'rename nested subdirectories'])
542
self.assertEquals(capture('root')[:-1],
543
os.path.join(self.test_dir, 'branch1'))
544
runbzr('move ../hello.txt .')
545
assert exists('./hello.txt')
546
self.assertEquals(capture('relpath hello.txt'),
547
os.path.join('sub1', 'sub2', 'hello.txt') + '\n')
548
assert capture('relpath ../../sub1/sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
549
runbzr(['commit', '-m', 'move to parent directory'])
551
assert capture('relpath sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
553
runbzr('move sub2/hello.txt .')
554
assert exists('hello.txt')
518
556
f = file('hello.txt', 'wt')
519
557
f.write('some nice new content\n')
522
runbzr("add hello.txt")
524
560
f = file('msg.tmp', 'wt')
525
f.write('this is my new commit\nand it has multiple lines, for fun')
561
f.write('this is my new commit\n')
528
564
runbzr('commit -F msg.tmp')
530
self.assertEquals(capture('revno'), '1\n')
531
runbzr('export -r 1 export-1.tmp')
566
assert capture('revno') == '5\n'
567
runbzr('export -r 5 export-5.tmp')
532
568
runbzr('export export.tmp')
536
572
runbzr('log -v --forward')
537
runbzr('log -m', retcode=3)
573
runbzr('log -m', retcode=1)
538
574
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'))
575
assert "this is my new commit" in log_out
576
assert "rename nested" not in log_out
577
assert 'revision-id' not in log_out
578
assert 'revision-id' in capture('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
581
progress("file with spaces in name")
553
582
mkdir('sub directory')
554
583
file('sub directory/file with spaces ', 'wt').write('see how this works\n')
556
runbzr('diff', retcode=1)
557
586
runbzr('commit -m add-spaces')
570
599
os.symlink("NOWHERE1", "link1")
571
600
runbzr('add link1')
572
self.assertEquals(self.capture('unknowns'), '')
601
assert self.capture('unknowns') == ''
573
602
runbzr(['commit', '-m', '1: added symlink link1'])
577
self.assertEquals(self.capture('unknowns'), '')
606
assert self.capture('unknowns') == ''
578
607
os.symlink("NOWHERE2", "d1/link2")
579
self.assertEquals(self.capture('unknowns'), 'd1/link2\n')
608
assert self.capture('unknowns') == 'd1/link2\n'
580
609
# is d1/link2 found when adding d1
582
self.assertEquals(self.capture('unknowns'), '')
611
assert self.capture('unknowns') == ''
583
612
os.symlink("NOWHERE3", "d1/link3")
584
self.assertEquals(self.capture('unknowns'), 'd1/link3\n')
613
assert self.capture('unknowns') == 'd1/link3\n'
585
614
runbzr(['commit', '-m', '2: added dir, symlink'])
587
616
runbzr('rename d1 d2')
588
617
runbzr('move d2/link2 .')
589
618
runbzr('move link1 d2')
590
self.assertEquals(os.readlink("./link2"), "NOWHERE2")
591
self.assertEquals(os.readlink("d2/link1"), "NOWHERE1")
619
assert os.readlink("./link2") == "NOWHERE2"
620
assert os.readlink("d2/link1") == "NOWHERE1"
592
621
runbzr('add d2/link3')
593
runbzr('diff', retcode=1)
594
623
runbzr(['commit', '-m', '3: rename of dir, move symlinks, add link3'])
596
625
os.unlink("link2")
597
626
os.symlink("TARGET 2", "link2")
598
627
os.unlink("d2/link1")
599
628
os.symlink("TARGET 1", "d2/link1")
600
runbzr('diff', retcode=1)
601
self.assertEquals(self.capture("relpath d2/link1"), "d2/link1\n")
630
assert self.capture("relpath d2/link1") == "d2/link1\n"
602
631
runbzr(['commit', '-m', '4: retarget of two links'])
604
633
runbzr('remove d2/link1')
605
self.assertEquals(self.capture('unknowns'), 'd2/link1\n')
634
assert self.capture('unknowns') == 'd2/link1\n'
606
635
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
639
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'])
640
assert self.capture('unknowns') == 'd2/link1\n'
641
runbzr(['commit', '-m', '6: remove d2/link1, move/rename link3'])
620
643
runbzr(['check'])
622
645
runbzr(['export', '-r', '1', 'exp1.tmp'])
623
646
chdir("exp1.tmp")
624
self.assertEquals(listdir_sorted("."), [ "link1" ])
625
self.assertEquals(os.readlink("link1"), "NOWHERE1")
647
assert listdir_sorted(".") == [ "link1" ]
648
assert os.readlink("link1") == "NOWHERE1"
628
651
runbzr(['export', '-r', '2', 'exp2.tmp'])
629
652
chdir("exp2.tmp")
630
self.assertEquals(listdir_sorted("."), [ "d1", "link1" ])
653
assert listdir_sorted(".") == [ "d1", "link1" ]
633
656
runbzr(['export', '-r', '3', 'exp3.tmp'])
634
657
chdir("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")
658
assert listdir_sorted(".") == [ "d2", "link2" ]
659
assert listdir_sorted("d2") == [ "link1", "link3" ]
660
assert os.readlink("d2/link1") == "NOWHERE1"
661
assert os.readlink("link2") == "NOWHERE2"
641
664
runbzr(['export', '-r', '4', 'exp4.tmp'])
642
665
chdir("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" ])
666
assert listdir_sorted(".") == [ "d2", "link2" ]
667
assert os.readlink("d2/link1") == "TARGET 1"
668
assert os.readlink("link2") == "TARGET 2"
669
assert listdir_sorted("d2") == [ "link1", "link3" ]
649
672
runbzr(['export', '-r', '5', 'exp5.tmp'])
650
673
chdir("exp5.tmp")
651
self.assertEquals(listdir_sorted("."), [ "d2", "link2" ])
652
self.assert_(os.path.islink("link2"))
653
self.assert_(listdir_sorted("d2")== [ "link3" ])
674
assert listdir_sorted(".") == [ "d2", "link2" ]
675
assert os.path.islink("link2")
676
assert listdir_sorted("d2")== [ "link3" ]
656
runbzr(['export', '-r', '8', 'exp6.tmp'])
679
runbzr(['export', '-r', '6', 'exp6.tmp'])
657
680
chdir("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")
681
assert listdir_sorted(".") == [ "d1", "d2", "link2" ]
682
assert listdir_sorted("d1") == [ "link3new" ]
683
assert listdir_sorted("d2") == []
684
assert os.readlink("d1/link3new") == "NOWHERE3"
664
687
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