~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/blackbox.py

  • Committer: John Arbash Meinel
  • Date: 2005-11-14 17:02:35 UTC
  • mto: (1587.1.6 bound-branches)
  • mto: This revision was merged to the branch mainline in revision 1590.
  • Revision ID: john@arbash-meinel.com-20051114170235-f85afa458bae956e
Fixing up the error message for a failed bind.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
17
17
 
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
21
 
#                   then!
22
18
 
23
19
"""Black-box tests for bzr.
24
20
 
28
24
"""
29
25
 
30
26
 
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.
35
 
 
36
 
 
37
27
from cStringIO import StringIO
38
28
import os
39
29
import re
 
30
import shutil
40
31
import sys
41
32
 
42
 
import bzrlib
43
33
from bzrlib.branch import Branch
44
 
import bzrlib.bzrdir as bzrdir
 
34
from bzrlib.clone import copy_branch
45
35
from bzrlib.errors import BzrCommandError
46
 
from bzrlib.osutils import (
47
 
    has_symlinks,
48
 
    pathjoin,
49
 
    rmtree,
50
 
    terminal_width,
51
 
    )
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
 
36
from bzrlib.osutils import has_symlinks
 
37
from bzrlib.selftest import TestCaseInTempDir, BzrTestBase
 
38
from bzrlib.selftest.HTTPTestUtil import TestCaseWithWebserver
 
39
 
 
40
 
 
41
class ExternalBase(TestCaseInTempDir):
 
42
 
 
43
    def runbzr(self, args, retcode=0, backtick=False):
 
44
        if isinstance(args, basestring):
 
45
            args = args.split()
 
46
 
 
47
        if backtick:
 
48
            return self.run_bzr_captured(args, retcode=retcode)[0]
 
49
        else:
 
50
            return self.run_bzr_captured(args, retcode=retcode)
56
51
 
57
52
 
58
53
class TestCommands(ExternalBase):
59
54
 
 
55
    def test_help_commands(self):
 
56
        self.runbzr('--help')
 
57
        self.runbzr('help')
 
58
        self.runbzr('help commands')
 
59
        self.runbzr('help help')
 
60
        self.runbzr('commit -h')
 
61
 
 
62
    def test_init_branch(self):
 
63
        self.runbzr(['init'])
 
64
 
 
65
        # Can it handle subdirectories as well?
 
66
        self.runbzr('init subdir1')
 
67
        self.assert_(os.path.exists('subdir1'))
 
68
        self.assert_(os.path.exists('subdir1/.bzr'))
 
69
 
 
70
        self.runbzr('init subdir2/nothere', retcode=2)
 
71
        
 
72
        os.mkdir('subdir2')
 
73
        self.runbzr('init subdir2')
 
74
        self.runbzr('init subdir2', retcode=1)
 
75
 
 
76
        self.runbzr('init subdir2/subsubdir1')
 
77
        self.assert_(os.path.exists('subdir2/subsubdir1/.bzr'))
 
78
 
60
79
    def test_whoami(self):
61
80
        # this should always identify something, if only "john@localhost"
62
81
        self.runbzr("whoami")
68
87
    def test_whoami_branch(self):
69
88
        """branch specific user identity works."""
70
89
        self.runbzr('init')
71
 
        b = bzrlib.branch.Branch.open('.')
72
 
        b.control_files.put_utf8('email', 'Branch Identity <branch@identi.ty>')
 
90
        f = file('.bzr/email', 'wt')
 
91
        f.write('Branch Identity <branch@identi.ty>')
 
92
        f.close()
73
93
        bzr_email = os.environ.get('BZREMAIL')
74
94
        if bzr_email is not None:
75
95
            del os.environ['BZREMAIL']
87
107
        if bzr_email is not None:
88
108
            os.environ['BZREMAIL'] = bzr_email
89
109
 
90
 
    def test_nick_command(self):
91
 
        """bzr nick for viewing, setting nicknames"""
92
 
        os.mkdir('me.dev')
93
 
        os.chdir('me.dev')
94
 
        self.runbzr('init')
95
 
        nick = self.runbzr("nick",backtick=True)
96
 
        self.assertEqual(nick, 'me.dev\n')
97
 
        nick = self.runbzr("nick moo")
98
 
        nick = self.runbzr("nick",backtick=True)
99
 
        self.assertEqual(nick, 'moo\n')
100
 
 
101
110
    def test_invalid_commands(self):
102
 
        self.runbzr("pants", retcode=3)
103
 
        self.runbzr("--pants off", retcode=3)
104
 
        self.runbzr("diff --message foo", retcode=3)
 
111
        self.runbzr("pants", retcode=1)
 
112
        self.runbzr("--pants off", retcode=1)
 
113
        self.runbzr("diff --message foo", retcode=1)
 
114
 
 
115
    def test_empty_commit(self):
 
116
        self.runbzr("init")
 
117
        self.build_tree(['hello.txt'])
 
118
        self.runbzr("commit -m empty", retcode=1)
 
119
        self.runbzr("add hello.txt")
 
120
        self.runbzr("commit -m added")
 
121
 
 
122
    def test_empty_commit_message(self):
 
123
        self.runbzr("init")
 
124
        file('foo.c', 'wt').write('int main() {}')
 
125
        self.runbzr(['add', 'foo.c'])
 
126
        self.runbzr(["commit", "-m", ""] , retcode=1) 
 
127
 
 
128
    def test_other_branch_commit(self):
 
129
        # this branch is to ensure consistent behaviour, whether we're run
 
130
        # inside a branch, or not.
 
131
        os.mkdir('empty_branch')
 
132
        os.chdir('empty_branch')
 
133
        self.runbzr('init')
 
134
        os.mkdir('branch')
 
135
        os.chdir('branch')
 
136
        self.runbzr('init')
 
137
        file('foo.c', 'wt').write('int main() {}')
 
138
        file('bar.c', 'wt').write('int main() {}')
 
139
        os.chdir('..')
 
140
        self.runbzr(['add', 'branch/foo.c'])
 
141
        self.runbzr(['add', 'branch'])
 
142
        # can't commit files in different trees; sane error
 
143
        self.runbzr('commit -m newstuff branch/foo.c .', retcode=1)
 
144
        self.runbzr('commit -m newstuff branch/foo.c')
 
145
        self.runbzr('commit -m newstuff branch')
 
146
        self.runbzr('commit -m newstuff branch', retcode=1)
 
147
 
105
148
 
106
149
    def test_ignore_patterns(self):
107
 
        self.runbzr('init')
108
 
        self.assertEquals(self.capture('unknowns'), '')
 
150
        from bzrlib.branch import Branch
 
151
        
 
152
        b = Branch.initialize('.')
 
153
        self.assertEquals(list(b.unknowns()), [])
109
154
 
110
155
        file('foo.tmp', 'wt').write('tmp files are ignored')
 
156
        self.assertEquals(list(b.unknowns()), [])
111
157
        self.assertEquals(self.capture('unknowns'), '')
112
158
 
113
159
        file('foo.c', 'wt').write('int main() {}')
 
160
        self.assertEquals(list(b.unknowns()), ['foo.c'])
114
161
        self.assertEquals(self.capture('unknowns'), 'foo.c\n')
115
162
 
116
163
        self.runbzr(['add', 'foo.c'])
118
165
 
119
166
        # 'ignore' works when creating the .bzignore file
120
167
        file('foo.blah', 'wt').write('blah')
121
 
        self.assertEquals(self.capture('unknowns'), 'foo.blah\n')
 
168
        self.assertEquals(list(b.unknowns()), ['foo.blah'])
122
169
        self.runbzr('ignore *.blah')
123
 
        self.assertEquals(self.capture('unknowns'), '')
 
170
        self.assertEquals(list(b.unknowns()), [])
124
171
        self.assertEquals(file('.bzrignore', 'rU').read(), '*.blah\n')
125
172
 
126
173
        # 'ignore' works when then .bzrignore file already exists
127
174
        file('garh', 'wt').write('garh')
 
175
        self.assertEquals(list(b.unknowns()), ['garh'])
128
176
        self.assertEquals(self.capture('unknowns'), 'garh\n')
129
177
        self.runbzr('ignore garh')
130
 
        self.assertEquals(self.capture('unknowns'), '')
 
178
        self.assertEquals(list(b.unknowns()), [])
131
179
        self.assertEquals(file('.bzrignore', 'rU').read(), '*.blah\ngarh\n')
132
180
 
 
181
    def test_revert(self):
 
182
        self.runbzr('init')
 
183
 
 
184
        file('hello', 'wt').write('foo')
 
185
        self.runbzr('add hello')
 
186
        self.runbzr('commit -m setup hello')
 
187
 
 
188
        file('goodbye', 'wt').write('baz')
 
189
        self.runbzr('add goodbye')
 
190
        self.runbzr('commit -m setup goodbye')
 
191
 
 
192
        file('hello', 'wt').write('bar')
 
193
        file('goodbye', 'wt').write('qux')
 
194
        self.runbzr('revert hello')
 
195
        self.check_file_contents('hello', 'foo')
 
196
        self.check_file_contents('goodbye', 'qux')
 
197
        self.runbzr('revert')
 
198
        self.check_file_contents('goodbye', 'baz')
 
199
 
 
200
        os.mkdir('revertdir')
 
201
        self.runbzr('add revertdir')
 
202
        self.runbzr('commit -m f')
 
203
        os.rmdir('revertdir')
 
204
        self.runbzr('revert')
 
205
 
 
206
        os.symlink('/unlikely/to/exist', 'symlink')
 
207
        self.runbzr('add symlink')
 
208
        self.runbzr('commit -m f')
 
209
        os.unlink('symlink')
 
210
        self.runbzr('revert')
 
211
        self.failUnlessExists('symlink')
 
212
        os.unlink('symlink')
 
213
        os.symlink('a-different-path', 'symlink')
 
214
        self.runbzr('revert')
 
215
        self.assertEqual('/unlikely/to/exist',
 
216
                         os.readlink('symlink'))
 
217
        
 
218
        file('hello', 'wt').write('xyz')
 
219
        self.runbzr('commit -m xyz hello')
 
220
        self.runbzr('revert -r 1 hello')
 
221
        self.check_file_contents('hello', 'foo')
 
222
        self.runbzr('revert hello')
 
223
        self.check_file_contents('hello', 'xyz')
 
224
        os.chdir('revertdir')
 
225
        self.runbzr('revert')
 
226
        os.chdir('..')
 
227
 
 
228
 
133
229
    def test_mv_modes(self):
134
230
        """Test two modes of operation for mv"""
135
 
        self.runbzr('init')
 
231
        from bzrlib.branch import Branch
 
232
        b = Branch.initialize('.')
136
233
        self.build_tree(['a', 'c', 'subdir/'])
137
234
        self.run_bzr_captured(['add', self.test_dir])
138
235
        self.run_bzr_captured(['mv', 'a', 'b'])
178
275
        self.assertEqual(file('../first.gz/hello', 'rt').read(), 'foo')
179
276
        self.runbzr('export ../first.bz2 -r 1')
180
277
        self.assertEqual(file('../first.bz2/hello', 'rt').read(), 'foo')
181
 
 
182
 
        from tarfile import TarFile
183
278
        self.runbzr('export ../first.tar -r 1')
184
279
        self.assert_(os.path.isfile('../first.tar'))
 
280
        from tarfile import TarFile
185
281
        tf = TarFile('../first.tar')
186
282
        self.assert_('first/hello' in tf.getnames(), tf.getnames())
187
283
        self.assertEqual(tf.extractfile('first/hello').read(), 'foo')
193
289
        self.assert_(os.path.isfile('../first.tar.bz2'))
194
290
        self.runbzr('export ../first.tar.tbz2 -r 1')
195
291
        self.assert_(os.path.isfile('../first.tar.tbz2'))
196
 
 
197
292
        from bz2 import BZ2File
198
293
        tf = TarFile('../first.tar.tbz2', 
199
294
                     fileobj=BZ2File('../first.tar.tbz2', 'r'))
203
298
        tf = TarFile('../first2.tar')
204
299
        self.assert_('pizza/hello' in tf.getnames(), tf.getnames())
205
300
 
206
 
        from zipfile import ZipFile
207
 
        self.runbzr('export ../first.zip -r 1')
208
 
        self.failUnlessExists('../first.zip')
209
 
        zf = ZipFile('../first.zip')
210
 
        self.assert_('first/hello' in zf.namelist(), zf.namelist())
211
 
        self.assertEqual(zf.read('first/hello'), 'foo')
212
 
 
213
 
        self.runbzr('export ../first2.zip -r 1 --root pizza')
214
 
        zf = ZipFile('../first2.zip')
215
 
        self.assert_('pizza/hello' in zf.namelist(), zf.namelist())
 
301
    def test_diff(self):
 
302
        self.example_branch()
 
303
        file('hello', 'wt').write('hello world!')
 
304
        self.runbzr('commit -m fixing hello')
 
305
        output = self.runbzr('diff -r 2..3', backtick=1, retcode=1)
 
306
        self.assert_('\n+hello world!' in output)
 
307
        output = self.runbzr('diff -r last:3..last:1', backtick=1, retcode=1)
 
308
        self.assert_('\n+baz' in output)
 
309
 
 
310
    def test_diff_branches(self):
 
311
        self.build_tree(['branch1/', 'branch1/file', 'branch2/'])
 
312
        branch = Branch.initialize('branch1')
 
313
        branch.add(['file'])
 
314
        branch.working_tree().commit('add file')
 
315
        copy_branch(branch, 'branch2')
 
316
        print >> open('branch2/file', 'w'), 'new content'
 
317
        branch2 = Branch.open('branch2')
 
318
        branch2.working_tree().commit('update file')
 
319
        # should open branch1 and diff against branch2, 
 
320
        output = self.run_bzr_captured(['diff', '-r', 'branch:branch2', 
 
321
                                        'branch1'],
 
322
                                       retcode=1)
 
323
        self.assertEquals(("=== modified file 'file'\n"
 
324
                           "--- file\n"
 
325
                           "+++ file\n"
 
326
                           "@@ -1,1 +1,1 @@\n"
 
327
                           "-new content\n"
 
328
                           "+contents of branch1/file\n"
 
329
                           "\n", ''), output)
 
330
 
 
331
    def test_branch(self):
 
332
        """Branch from one branch to another."""
 
333
        os.mkdir('a')
 
334
        os.chdir('a')
 
335
        self.example_branch()
 
336
        os.chdir('..')
 
337
        self.runbzr('branch a b')
 
338
        self.assertFileEqual('b\n', 'b/.bzr/branch-name')
 
339
        self.runbzr('branch a c -r 1')
 
340
        os.chdir('b')
 
341
        self.runbzr('commit -m foo --unchanged')
 
342
        os.chdir('..')
 
343
        # naughty - abstraction violations RBC 20050928  
 
344
        print "test_branch used to delete the stores, how is this meant to work ?"
 
345
        #shutil.rmtree('a/.bzr/revision-store')
 
346
        #shutil.rmtree('a/.bzr/inventory-store', ignore_errors=True)
 
347
        #shutil.rmtree('a/.bzr/text-store', ignore_errors=True)
 
348
        self.runbzr('branch a d --basis b')
 
349
 
 
350
    def test_merge(self):
 
351
        from bzrlib.branch import Branch
216
352
        
217
 
        self.runbzr('export ../first-zip --format=zip -r 1')
218
 
        zf = ZipFile('../first-zip')
219
 
        self.assert_('first-zip/hello' in zf.namelist(), zf.namelist())
220
 
 
221
 
    def test_inventory(self):
222
 
        bzr = self.runbzr
223
 
        def output_equals(value, *args):
224
 
            out = self.runbzr(['inventory'] + list(args), backtick=True)
225
 
            self.assertEquals(out, value)
226
 
 
227
 
        bzr('init')
228
 
        open('a', 'wb').write('hello\n')
229
 
        os.mkdir('b')
230
 
 
231
 
        bzr('add a b')
232
 
        bzr('commit -m add')
233
 
 
234
 
        output_equals('a\n', '--kind', 'file')
235
 
        output_equals('b\n', '--kind', 'directory')        
 
353
        os.mkdir('a')
 
354
        os.chdir('a')
 
355
        self.example_branch()
 
356
        os.chdir('..')
 
357
        self.runbzr('branch a b')
 
358
        os.chdir('b')
 
359
        file('goodbye', 'wt').write('quux')
 
360
        self.runbzr(['commit',  '-m',  "more u's are always good"])
 
361
 
 
362
        os.chdir('../a')
 
363
        file('hello', 'wt').write('quuux')
 
364
        # We can't merge when there are in-tree changes
 
365
        self.runbzr('merge ../b', retcode=1)
 
366
        self.runbzr(['commit', '-m', "Like an epidemic of u's"])
 
367
        self.runbzr('merge ../b -r last:1..last:1 --merge-type blooof',
 
368
                    retcode=1)
 
369
        self.runbzr('merge ../b -r last:1..last:1 --merge-type merge3')
 
370
        self.runbzr('revert --no-backup')
 
371
        self.runbzr('merge ../b -r last:1..last:1 --merge-type weave')
 
372
        self.runbzr('revert --no-backup')
 
373
        self.runbzr('merge ../b -r last:1..last:1 --reprocess')
 
374
        self.runbzr('revert --no-backup')
 
375
        self.runbzr('merge ../b -r last:1')
 
376
        self.check_file_contents('goodbye', 'quux')
 
377
        # Merging a branch pulls its revision into the tree
 
378
        a = Branch.open('.')
 
379
        b = Branch.open('../b')
 
380
        a.get_revision_xml(b.last_revision())
 
381
        self.log('pending merges: %s', a.working_tree().pending_merges())
 
382
        self.assertEquals(a.working_tree().pending_merges(),
 
383
                          [b.last_revision()])
 
384
        self.runbzr('commit -m merged')
 
385
        self.runbzr('merge ../b -r last:1')
 
386
        self.assertEqual(Branch.open('.').working_tree().pending_merges(), [])
 
387
 
 
388
    def test_merge_with_missing_file(self):
 
389
        """Merge handles missing file conflicts"""
 
390
        os.mkdir('a')
 
391
        os.chdir('a')
 
392
        os.mkdir('sub')
 
393
        print >> file('sub/a.txt', 'wb'), "hello"
 
394
        print >> file('b.txt', 'wb'), "hello"
 
395
        print >> file('sub/c.txt', 'wb'), "hello"
 
396
        self.runbzr('init')
 
397
        self.runbzr('add')
 
398
        self.runbzr(('commit', '-m', 'added a'))
 
399
        self.runbzr('branch . ../b')
 
400
        print >> file('sub/a.txt', 'ab'), "there"
 
401
        print >> file('b.txt', 'ab'), "there"
 
402
        print >> file('sub/c.txt', 'ab'), "there"
 
403
        self.runbzr(('commit', '-m', 'Added there'))
 
404
        os.unlink('sub/a.txt')
 
405
        os.unlink('sub/c.txt')
 
406
        os.rmdir('sub')
 
407
        os.unlink('b.txt')
 
408
        self.runbzr(('commit', '-m', 'Removed a.txt'))
 
409
        os.chdir('../b')
 
410
        print >> file('sub/a.txt', 'ab'), "something"
 
411
        print >> file('b.txt', 'ab'), "something"
 
412
        print >> file('sub/c.txt', 'ab'), "something"
 
413
        self.runbzr(('commit', '-m', 'Modified a.txt'))
 
414
        self.runbzr('merge ../a/', retcode=1)
 
415
        self.assert_(os.path.exists('sub/a.txt.THIS'))
 
416
        self.assert_(os.path.exists('sub/a.txt.BASE'))
 
417
        os.chdir('../a')
 
418
        self.runbzr('merge ../b/', retcode=1)
 
419
        self.assert_(os.path.exists('sub/a.txt.OTHER'))
 
420
        self.assert_(os.path.exists('sub/a.txt.BASE'))
 
421
 
 
422
    def test_pull(self):
 
423
        """Pull changes from one branch to another."""
 
424
        os.mkdir('a')
 
425
        os.chdir('a')
 
426
 
 
427
        self.example_branch()
 
428
        self.runbzr('pull', retcode=1)
 
429
        self.runbzr('missing', retcode=1)
 
430
        self.runbzr('missing .')
 
431
        self.runbzr('missing')
 
432
        self.runbzr('pull')
 
433
        self.runbzr('pull /', retcode=1)
 
434
        self.runbzr('pull')
 
435
 
 
436
        os.chdir('..')
 
437
        self.runbzr('branch a b')
 
438
        os.chdir('b')
 
439
        self.runbzr('pull')
 
440
        os.mkdir('subdir')
 
441
        self.runbzr('add subdir')
 
442
        self.runbzr('commit -m blah --unchanged')
 
443
        os.chdir('../a')
 
444
        a = Branch.open('.')
 
445
        b = Branch.open('../b')
 
446
        self.assertEquals(a.revision_history(), b.revision_history()[:-1])
 
447
        self.runbzr('pull ../b')
 
448
        self.assertEquals(a.revision_history(), b.revision_history())
 
449
        self.runbzr('commit -m blah2 --unchanged')
 
450
        os.chdir('../b')
 
451
        self.runbzr('commit -m blah3 --unchanged')
 
452
        # no overwrite
 
453
        self.runbzr('pull ../a', retcode=1)
 
454
        os.chdir('..')
 
455
        self.runbzr('branch b overwriteme')
 
456
        os.chdir('overwriteme')
 
457
        self.runbzr('pull --overwrite ../a')
 
458
        overwritten = Branch.open('.')
 
459
        self.assertEqual(overwritten.revision_history(),
 
460
                         a.revision_history())
 
461
        os.chdir('../a')
 
462
        self.runbzr('merge ../b')
 
463
        self.runbzr('commit -m blah4 --unchanged')
 
464
        os.chdir('../b/subdir')
 
465
        self.runbzr('pull ../../a')
 
466
        self.assertEquals(a.revision_history()[-1], b.revision_history()[-1])
 
467
        self.runbzr('commit -m blah5 --unchanged')
 
468
        self.runbzr('commit -m blah6 --unchanged')
 
469
        os.chdir('..')
 
470
        self.runbzr('pull ../a')
 
471
        os.chdir('../a')
 
472
        self.runbzr('commit -m blah7 --unchanged')
 
473
        self.runbzr('merge ../b')
 
474
        self.runbzr('commit -m blah8 --unchanged')
 
475
        self.runbzr('pull ../b')
 
476
        self.runbzr('pull ../b')
236
477
 
237
478
    def test_ls(self):
238
479
        """Test the abilities of 'bzr ls'"""
249
490
        open('a', 'wb').write('hello\n')
250
491
 
251
492
        # Can't supply both
252
 
        bzr('ls --verbose --null', retcode=3)
 
493
        bzr('ls --verbose --null', retcode=1)
253
494
 
254
495
        ls_equals('a\n')
255
496
        ls_equals('?        a\n', '--verbose')
335
576
                  'subdir/b\n'
336
577
                  , '--versioned')
337
578
 
338
 
    def test_cat(self):
339
 
        self.runbzr('init')
340
 
        file("myfile", "wb").write("My contents\n")
341
 
        self.runbzr('add')
342
 
        self.runbzr('commit -m myfile')
343
 
        self.run_bzr_captured('cat -r 1 myfile'.split(' '))
344
 
 
345
 
    def test_pull_verbose(self):
346
 
        """Pull changes from one branch to another and watch the output."""
347
 
 
348
 
        os.mkdir('a')
349
 
        os.chdir('a')
350
 
 
351
 
        bzr = self.runbzr
352
 
        self.example_branch()
353
 
 
354
 
        os.chdir('..')
355
 
        bzr('branch a b')
356
 
        os.chdir('b')
357
 
        open('b', 'wb').write('else\n')
358
 
        bzr('add b')
359
 
        bzr(['commit', '-m', 'added b'])
360
 
 
361
 
        os.chdir('../a')
362
 
        out = bzr('pull --verbose ../b', backtick=True)
363
 
        self.failIfEqual(out.find('Added Revisions:'), -1)
364
 
        self.failIfEqual(out.find('message:\n  added b'), -1)
365
 
        self.failIfEqual(out.find('added b'), -1)
366
 
 
367
 
        # Check that --overwrite --verbose prints out the removed entries
368
 
        bzr('commit -m foo --unchanged')
369
 
        os.chdir('../b')
370
 
        bzr('commit -m baz --unchanged')
371
 
        bzr('pull ../a', retcode=3)
372
 
        out = bzr('pull --overwrite --verbose ../a', backtick=1)
373
 
 
374
 
        remove_loc = out.find('Removed Revisions:')
375
 
        self.failIfEqual(remove_loc, -1)
376
 
        added_loc = out.find('Added Revisions:')
377
 
        self.failIfEqual(added_loc, -1)
378
 
 
379
 
        removed_message = out.find('message:\n  baz')
380
 
        self.failIfEqual(removed_message, -1)
381
 
        self.failUnless(remove_loc < removed_message < added_loc)
382
 
 
383
 
        added_message = out.find('message:\n  foo')
384
 
        self.failIfEqual(added_message, -1)
385
 
        self.failUnless(added_loc < added_message)
386
 
        
387
579
    def test_locations(self):
388
580
        """Using and remembering different locations"""
389
581
        os.mkdir('a')
390
582
        os.chdir('a')
391
583
        self.runbzr('init')
392
584
        self.runbzr('commit -m unchanged --unchanged')
393
 
        self.runbzr('pull', retcode=3)
394
 
        self.runbzr('merge', retcode=3)
 
585
        self.runbzr('pull', retcode=1)
 
586
        self.runbzr('merge', retcode=1)
395
587
        self.runbzr('branch . ../b')
396
588
        os.chdir('../b')
397
589
        self.runbzr('pull')
403
595
        self.runbzr('pull')
404
596
        self.runbzr('pull ../c')
405
597
        self.runbzr('branch ../c ../d')
406
 
        rmtree('../c')
 
598
        shutil.rmtree('../c')
407
599
        self.runbzr('pull')
408
600
        os.chdir('../b')
409
601
        self.runbzr('pull')
410
602
        os.chdir('../d')
411
 
        self.runbzr('pull', retcode=3)
 
603
        self.runbzr('pull', retcode=1)
412
604
        self.runbzr('pull ../a --remember')
413
605
        self.runbzr('pull')
414
606
        
 
607
    def test_add_reports(self):
 
608
        """add command prints the names of added files."""
 
609
        b = Branch.initialize('.')
 
610
        self.build_tree(['top.txt', 'dir/', 'dir/sub.txt'])
 
611
        out = self.run_bzr_captured(['add'], retcode = 0)[0]
 
612
        # the ordering is not defined at the moment
 
613
        results = sorted(out.rstrip('\n').split('\n'))
 
614
        self.assertEquals(['added dir',
 
615
                           'added dir'+os.sep+'sub.txt',
 
616
                           'added top.txt',],
 
617
                          results)
 
618
 
 
619
    def test_add_quiet_is(self):
 
620
        """add -q does not print the names of added files."""
 
621
        b = Branch.initialize('.')
 
622
        self.build_tree(['top.txt', 'dir/', 'dir/sub.txt'])
 
623
        out = self.run_bzr_captured(['add', '-q'], retcode = 0)[0]
 
624
        # the ordering is not defined at the moment
 
625
        results = sorted(out.rstrip('\n').split('\n'))
 
626
        self.assertEquals([''], results)
 
627
 
415
628
    def test_unknown_command(self):
416
629
        """Handling of unknown command."""
417
630
        out, err = self.run_bzr_captured(['fluffy-badger'],
418
 
                                         retcode=3)
 
631
                                         retcode=1)
419
632
        self.assertEquals(out, '')
420
633
        err.index('unknown command')
421
634
 
422
 
    def create_conflicts(self):
423
 
        """Create a conflicted tree"""
 
635
    def test_conflicts(self):
 
636
        """Handling of merge conflicts"""
424
637
        os.mkdir('base')
425
638
        os.chdir('base')
426
639
        file('hello', 'wb').write("hi world")
440
653
        file('question', 'wb').write("What do you get when you multiply six"
441
654
                                   "times nine?")
442
655
        self.runbzr('commit -m this')
443
 
 
444
 
    def test_status(self):
445
 
        os.mkdir('branch1')
446
 
        os.chdir('branch1')
447
 
        self.runbzr('init')
448
 
        self.runbzr('commit --unchanged --message f')
449
 
        self.runbzr('branch . ../branch2')
450
 
        self.runbzr('branch . ../branch3')
451
 
        self.runbzr('commit --unchanged --message peter')
452
 
        os.chdir('../branch2')
453
 
        self.runbzr('merge ../branch1')
454
 
        self.runbzr('commit --unchanged --message pumpkin')
455
 
        os.chdir('../branch3')
456
 
        self.runbzr('merge ../branch2')
457
 
        message = self.capture('status')
458
 
 
459
 
 
460
 
    def test_conflicts(self):
461
 
        """Handling of merge conflicts"""
462
 
        self.create_conflicts()
463
656
        self.runbzr('merge ../other --show-base', retcode=1)
464
657
        conflict_text = file('hello').read()
465
658
        self.assert_('<<<<<<<' in conflict_text)
474
667
        self.assert_('|||||||' not in conflict_text)
475
668
        self.assert_('hi world' not in conflict_text)
476
669
        result = self.runbzr('conflicts', backtick=1)
477
 
        self.assertEquals(result, "Text conflict in hello\nText conflict in"
478
 
                                  " question\n")
 
670
        self.assertEquals(result, "hello\nquestion\n")
479
671
        result = self.runbzr('status', backtick=1)
480
 
        self.assert_("conflicts:\n  Text conflict in hello\n"
481
 
                     "  Text conflict in question\n" in result, result)
 
672
        self.assert_("conflicts:\n  hello\n  question\n" in result, result)
482
673
        self.runbzr('resolve hello')
483
674
        result = self.runbzr('conflicts', backtick=1)
484
 
        self.assertEquals(result, "Text conflict in question\n")
485
 
        self.runbzr('commit -m conflicts', retcode=3)
 
675
        self.assertEquals(result, "question\n")
 
676
        self.runbzr('commit -m conflicts', retcode=1)
486
677
        self.runbzr('resolve --all')
487
678
        result = self.runbzr('conflicts', backtick=1)
488
679
        self.runbzr('commit -m conflicts')
489
680
        self.assertEquals(result, "")
490
681
 
 
682
    def test_resign(self):
 
683
        """Test re signing of data."""
 
684
        import bzrlib.gpg
 
685
        oldstrategy = bzrlib.gpg.GPGStrategy
 
686
        branch = Branch.initialize('.')
 
687
        branch.working_tree().commit("base", allow_pointless=True, rev_id='A')
 
688
        try:
 
689
            # monkey patch gpg signing mechanism
 
690
            from bzrlib.testament import Testament
 
691
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
 
692
            self.runbzr('re-sign -r revid:A')
 
693
            self.assertEqual(Testament.from_revision(branch,'A').as_short_text(),
 
694
                             branch.revision_store.get('A', 'sig').read())
 
695
        finally:
 
696
            bzrlib.gpg.GPGStrategy = oldstrategy
 
697
            
 
698
    def test_resign_range(self):
 
699
        import bzrlib.gpg
 
700
        oldstrategy = bzrlib.gpg.GPGStrategy
 
701
        branch = Branch.initialize('.')
 
702
        branch.working_tree().commit("base", allow_pointless=True, rev_id='A')
 
703
        branch.working_tree().commit("base", allow_pointless=True, rev_id='B')
 
704
        branch.working_tree().commit("base", allow_pointless=True, rev_id='C')
 
705
        try:
 
706
            # monkey patch gpg signing mechanism
 
707
            from bzrlib.testament import Testament
 
708
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
 
709
            self.runbzr('re-sign -r 1..')
 
710
            self.assertEqual(Testament.from_revision(branch,'A').as_short_text(),
 
711
                             branch.revision_store.get('A', 'sig').read())
 
712
            self.assertEqual(Testament.from_revision(branch,'B').as_short_text(),
 
713
                             branch.revision_store.get('B', 'sig').read())
 
714
            self.assertEqual(Testament.from_revision(branch,'C').as_short_text(),
 
715
                             branch.revision_store.get('C', 'sig').read())
 
716
        finally:
 
717
            bzrlib.gpg.GPGStrategy = oldstrategy
 
718
 
491
719
    def test_push(self):
492
720
        # create a source branch
493
721
        os.mkdir('my-branch')
495
723
        self.example_branch()
496
724
 
497
725
        # with no push target, fail
498
 
        self.runbzr('push', retcode=3)
 
726
        self.runbzr('push', retcode=1)
499
727
        # with an explicit target work
500
728
        self.runbzr('push ../output-branch')
501
729
        # with an implicit target work
506
734
        self.runbzr('commit --unchanged -m unchanged')
507
735
 
508
736
        os.chdir('../output-branch')
509
 
        # There is no longer a difference as long as we have
510
 
        # access to the working tree
 
737
        # should be a diff as we have not pushed the tree
 
738
        self.runbzr('diff', retcode=1)
 
739
        self.runbzr('revert')
 
740
        # but not now.
511
741
        self.runbzr('diff')
512
 
 
513
 
        # But we should be missing a revision
514
 
        self.runbzr('missing ../my-branch', retcode=1)
515
 
 
516
742
        # diverge the branches
517
743
        self.runbzr('commit --unchanged -m unchanged')
518
744
        os.chdir('../my-branch')
519
745
        # cannot push now
520
 
        self.runbzr('push', retcode=3)
 
746
        self.runbzr('push', retcode=1)
521
747
        # and there are difference
522
748
        self.runbzr('missing ../output-branch', retcode=1)
523
 
        self.runbzr('missing --verbose ../output-branch', retcode=1)
524
749
        # but we can force a push
525
750
        self.runbzr('push --overwrite')
526
751
        # nothing missing
527
752
        self.runbzr('missing ../output-branch')
528
753
        
529
754
        # pushing to a new dir with no parent should fail
530
 
        self.runbzr('push ../missing/new-branch', retcode=3)
 
755
        self.runbzr('push ../missing/new-branch', retcode=1)
531
756
        # unless we provide --create-prefix
532
757
        self.runbzr('push --create-prefix ../missing/new-branch')
533
758
        # nothing missing
534
759
        self.runbzr('missing ../missing/new-branch')
535
760
 
536
 
    def test_external_command(self):
537
 
        """Test that external commands can be run by setting the path
538
 
        """
539
 
        # We don't at present run bzr in a subprocess for blackbox tests, and so 
540
 
        # don't really capture stdout, only the internal python stream.
541
 
        # Therefore we don't use a subcommand that produces any output or does
542
 
        # anything -- we just check that it can be run successfully.  
543
 
        cmd_name = 'test-command'
544
 
        if sys.platform == 'win32':
545
 
            cmd_name += '.bat'
546
 
        oldpath = os.environ.get('BZRPATH', None)
547
 
        bzr = self.capture
548
 
        try:
549
 
            if os.environ.has_key('BZRPATH'):
550
 
                del os.environ['BZRPATH']
551
 
 
552
 
            f = file(cmd_name, 'wb')
553
 
            if sys.platform == 'win32':
554
 
                f.write('@echo off\n')
555
 
            else:
556
 
                f.write('#!/bin/sh\n')
557
 
            # f.write('echo Hello from test-command')
558
 
            f.close()
559
 
            os.chmod(cmd_name, 0755)
560
 
 
561
 
            # It should not find the command in the local 
562
 
            # directory by default, since it is not in my path
563
 
            bzr(cmd_name, retcode=3)
564
 
 
565
 
            # Now put it into my path
566
 
            os.environ['BZRPATH'] = '.'
567
 
 
568
 
            bzr(cmd_name)
569
 
 
570
 
            # Make sure empty path elements are ignored
571
 
            os.environ['BZRPATH'] = os.pathsep
572
 
 
573
 
            bzr(cmd_name, retcode=3)
574
 
 
575
 
        finally:
576
 
            if oldpath:
577
 
                os.environ['BZRPATH'] = oldpath
578
 
 
579
761
 
580
762
def listdir_sorted(dir):
581
763
    L = os.listdir(dir)
600
782
        runbzr('init')
601
783
 
602
784
        self.assertEquals(capture('root').rstrip(),
603
 
                          pathjoin(self.test_dir, 'branch1'))
 
785
                          os.path.join(self.test_dir, 'branch1'))
604
786
 
605
787
        progress("status of new file")
606
788
 
613
795
        out = capture("status")
614
796
        self.assertEquals(out, 'unknown:\n  test.txt\n')
615
797
 
 
798
        out = capture("status --all")
 
799
        self.assertEquals(out, "unknown:\n  test.txt\n")
 
800
 
 
801
        out = capture("status test.txt --all")
 
802
        self.assertEquals(out, "unknown:\n  test.txt\n")
 
803
 
616
804
        f = file('test2.txt', 'wt')
617
805
        f.write('goodbye cruel world...\n')
618
806
        f.close()
626
814
        os.unlink('test2.txt')
627
815
 
628
816
        progress("command aliases")
629
 
        out = capture("st")
 
817
        out = capture("st --all")
630
818
        self.assertEquals(out, ("unknown:\n" "  test.txt\n"))
631
819
 
632
820
        out = capture("stat")
636
824
        runbzr("help st")
637
825
        runbzr("help")
638
826
        runbzr("help commands")
639
 
        runbzr("help slartibartfast", 3)
 
827
        runbzr("help slartibartfast", 1)
640
828
 
641
829
        out = capture("help ci")
642
830
        out.index('aliases: ')
643
831
 
644
832
        progress("can't rename unversioned file")
645
 
        runbzr("rename test.txt new-test.txt", 3)
 
833
        runbzr("rename test.txt new-test.txt", 1)
646
834
 
647
835
        progress("adding a file")
648
836
 
649
837
        runbzr("add test.txt")
650
838
        self.assertEquals(capture("unknowns"), '')
 
839
        self.assertEquals(capture("status --all"), ("added:\n" "  test.txt\n"))
651
840
 
652
841
        progress("rename newly-added file")
653
842
        runbzr("rename test.txt hello.txt")
661
850
 
662
851
        progress("more complex renames")
663
852
        os.mkdir("sub1")
664
 
        runbzr("rename hello.txt sub1", 3)
665
 
        runbzr("rename hello.txt sub1/hello.txt", 3)
666
 
        runbzr("move hello.txt sub1", 3)
 
853
        runbzr("rename hello.txt sub1", 1)
 
854
        runbzr("rename hello.txt sub1/hello.txt", 1)
 
855
        runbzr("move hello.txt sub1", 1)
667
856
 
668
857
        runbzr("add sub1")
669
858
        runbzr("rename sub1 sub2")
670
859
        runbzr("move hello.txt sub2")
671
860
        self.assertEqual(capture("relpath sub2/hello.txt"),
672
 
                         pathjoin("sub2", "hello.txt\n"))
 
861
                         os.path.join("sub2", "hello.txt\n"))
673
862
 
674
863
        self.assert_(exists("sub2"))
675
864
        self.assert_(exists("sub2/hello.txt"))
691
880
 
692
881
        chdir('sub1/sub2')
693
882
        self.assertEquals(capture('root')[:-1],
694
 
                          pathjoin(self.test_dir, 'branch1'))
 
883
                          os.path.join(self.test_dir, 'branch1'))
695
884
        runbzr('move ../hello.txt .')
696
885
        self.assert_(exists('./hello.txt'))
697
886
        self.assertEquals(capture('relpath hello.txt'),
698
 
                          pathjoin('sub1', 'sub2', 'hello.txt') + '\n')
699
 
        self.assertEquals(capture('relpath ../../sub1/sub2/hello.txt'), pathjoin('sub1', 'sub2', 'hello.txt\n'))
 
887
                          os.path.join('sub1', 'sub2', 'hello.txt') + '\n')
 
888
        self.assertEquals(capture('relpath ../../sub1/sub2/hello.txt'), os.path.join('sub1', 'sub2', 'hello.txt\n'))
700
889
        runbzr(['commit', '-m', 'move to parent directory'])
701
890
        chdir('..')
702
 
        self.assertEquals(capture('relpath sub2/hello.txt'), pathjoin('sub1', 'sub2', 'hello.txt\n'))
 
891
        self.assertEquals(capture('relpath sub2/hello.txt'), os.path.join('sub1', 'sub2', 'hello.txt\n'))
703
892
 
704
893
        runbzr('move sub2/hello.txt .')
705
894
        self.assert_(exists('hello.txt'))
721
910
        runbzr('log')
722
911
        runbzr('log -v')
723
912
        runbzr('log -v --forward')
724
 
        runbzr('log -m', retcode=3)
 
913
        runbzr('log -m', retcode=1)
725
914
        log_out = capture('log -m commit')
726
915
        self.assert_("this is my new commit\n  and" in log_out)
727
916
        self.assert_("rename nested" not in log_out)
729
918
        self.assert_('revision-id' in capture('log --show-ids -m commit'))
730
919
 
731
920
        log_out = capture('log --line')
732
 
        # determine the widest line we want
733
 
        max_width = terminal_width() - 1
734
921
        for line in log_out.splitlines():
735
 
            self.assert_(len(line) <= max_width, len(line))
736
 
        self.assert_("this is my new commit and" not in log_out)
737
 
        self.assert_("this is my new commit" in log_out)
 
922
            self.assert_(len(line) <= 79, len(line))
 
923
        self.assert_("this is my new commit and" in log_out)
 
924
 
738
925
 
739
926
        progress("file with spaces in name")
740
927
        mkdir('sub directory')
851
1038
            progress("skipping symlink tests")
852
1039
 
853
1040
 
854
 
class RemoteTests(object):
 
1041
class HttpTests(TestCaseWithWebserver):
855
1042
    """Test bzr ui commands against remote branches."""
856
1043
 
857
1044
    def test_branch(self):
858
1045
        os.mkdir('from')
859
 
        wt = self.make_branch_and_tree('from')
860
 
        branch = wt.branch
861
 
        wt.commit('empty commit for nonsense', allow_pointless=True)
862
 
        url = self.get_readonly_url('from')
 
1046
        branch = Branch.initialize('from')
 
1047
        branch.working_tree().commit('empty commit for nonsense', allow_pointless=True)
 
1048
        url = self.get_remote_url('from')
863
1049
        self.run_bzr('branch', url, 'to')
864
1050
        branch = Branch.open('to')
865
1051
        self.assertEqual(1, len(branch.revision_history()))
866
 
        # the branch should be set in to to from
867
 
        self.assertEqual(url + '/', branch.get_parent())
868
1052
 
869
1053
    def test_log(self):
870
1054
        self.build_tree(['branch/', 'branch/file'])
871
 
        self.capture('init branch')
872
 
        self.capture('add branch/file')
873
 
        self.capture('commit -m foo branch')
874
 
        url = self.get_readonly_url('branch/file')
 
1055
        branch = Branch.initialize('branch')
 
1056
        branch.add(['file'])
 
1057
        branch.working_tree().commit('add file', rev_id='A')
 
1058
        url = self.get_remote_url('branch/file')
875
1059
        output = self.capture('log %s' % url)
876
 
        self.assertEqual(8, len(output.split('\n')))
 
1060
        self.assertEqual(7, len(output.split('\n')))
877
1061
        
878
 
    def test_check(self):
879
 
        self.build_tree(['branch/', 'branch/file'])
880
 
        self.capture('init branch')
881
 
        self.capture('add branch/file')
882
 
        self.capture('commit -m foo branch')
883
 
        url = self.get_readonly_url('branch/')
884
 
        self.run_bzr('check', url)
885
 
    
886
 
    def test_push(self):
887
 
        # create a source branch
888
 
        os.mkdir('my-branch')
889
 
        os.chdir('my-branch')
890
 
        self.run_bzr('init')
891
 
        file('hello', 'wt').write('foo')
892
 
        self.run_bzr('add', 'hello')
893
 
        self.run_bzr('commit', '-m', 'setup')
894
 
 
895
 
        # with an explicit target work
896
 
        self.run_bzr('push', self.get_url('output-branch'))
897
 
 
898
 
    
899
 
class HTTPTests(TestCaseWithWebserver, RemoteTests):
900
 
    """Test various commands against a HTTP server."""
901
 
    
902
 
    
903
 
class SFTPTestsAbsolute(TestCaseWithSFTPServer, RemoteTests):
904
 
    """Test various commands against a SFTP server using abs paths."""
905
 
 
906
 
    
907
 
class SFTPTestsAbsoluteSibling(TestCaseWithSFTPServer, RemoteTests):
908
 
    """Test various commands against a SFTP server using abs paths."""
909
 
 
910
 
    def setUp(self):
911
 
        super(SFTPTestsAbsoluteSibling, self).setUp()
912
 
        self._override_home = '/dev/noone/runs/tests/here'
913
 
 
914
 
    
915
 
class SFTPTestsRelative(TestCaseWithSFTPServer, RemoteTests):
916
 
    """Test various commands against a SFTP server using homedir rel paths."""
917
 
 
918
 
    def setUp(self):
919
 
        super(SFTPTestsRelative, self).setUp()
920
 
        self._get_remote_is_absolute = False
 
1062
 
 
1063
 
 
1064