~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/blackbox.py

  • Committer: Martin Pool
  • Date: 2005-09-01 02:34:38 UTC
  • Revision ID: mbp@sourcefrog.net-20050901023437-bf791a0ef5edae8d
- old docs: clarify that this is not mainly descended from arch anymore

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
"""Black-box tests for bzr.
20
20
 
21
21
These check that it behaves properly when it's invoked through the regular
22
 
command-line interface. This doesn't actually run a new interpreter but 
23
 
rather starts again from the run_bzr function.
 
22
command-line interface.
 
23
 
 
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.
24
27
"""
25
28
 
26
 
 
27
 
from cStringIO import StringIO
28
 
import os
29
 
import re
30
 
import shutil
31
29
import sys
32
 
 
33
 
from bzrlib.branch import Branch
34
 
from bzrlib.clone import copy_branch
35
 
from bzrlib.errors import BzrCommandError
36
 
from bzrlib.osutils import has_symlinks
37
30
from bzrlib.selftest import TestCaseInTempDir, BzrTestBase
38
 
from bzrlib.selftest.HTTPTestUtil import TestCaseWithWebserver
39
 
 
40
31
 
41
32
class ExternalBase(TestCaseInTempDir):
42
 
 
43
 
    def runbzr(self, args, retcode=0, backtick=False):
 
33
    def runbzr(self, args, retcode=0,backtick=False):
44
34
        if isinstance(args, basestring):
45
35
            args = args.split()
46
36
 
47
37
        if backtick:
48
 
            return self.run_bzr_captured(args, retcode=retcode)[0]
 
38
            return self.backtick(['python', self.BZRPATH,] + args,
 
39
                           retcode=retcode)
49
40
        else:
50
 
            return self.run_bzr_captured(args, retcode=retcode)
 
41
            return self.runcmd(['python', self.BZRPATH,] + args,
 
42
                           retcode=retcode)
51
43
 
52
44
 
53
45
class TestCommands(ExternalBase):
76
68
        f = file('.bzr/email', 'wt')
77
69
        f.write('Branch Identity <branch@identi.ty>')
78
70
        f.close()
79
 
        bzr_email = os.environ.get('BZREMAIL')
80
 
        if bzr_email is not None:
81
 
            del os.environ['BZREMAIL']
82
71
        whoami = self.runbzr("whoami",backtick=True)
83
72
        whoami_email = self.runbzr("whoami --email",backtick=True)
84
73
        self.assertTrue(whoami.startswith('Branch Identity <branch@identi.ty>'))
85
74
        self.assertTrue(whoami_email.startswith('branch@identi.ty'))
86
 
        # Verify that the environment variable overrides the value 
87
 
        # in the file
88
 
        os.environ['BZREMAIL'] = 'Different ID <other@environ.ment>'
89
 
        whoami = self.runbzr("whoami",backtick=True)
90
 
        whoami_email = self.runbzr("whoami --email",backtick=True)
91
 
        self.assertTrue(whoami.startswith('Different ID <other@environ.ment>'))
92
 
        self.assertTrue(whoami_email.startswith('other@environ.ment'))
93
 
        if bzr_email is not None:
94
 
            os.environ['BZREMAIL'] = bzr_email
95
75
 
96
76
    def test_invalid_commands(self):
97
77
        self.runbzr("pants", retcode=1)
105
85
        self.runbzr("add hello.txt")
106
86
        self.runbzr("commit -m added")
107
87
 
108
 
    def test_empty_commit_message(self):
109
 
        self.runbzr("init")
110
 
        file('foo.c', 'wt').write('int main() {}')
111
 
        self.runbzr(['add', 'foo.c'])
112
 
        self.runbzr(["commit", "-m", ""] , retcode=1) 
113
 
 
114
 
    def test_other_branch_commit(self):
115
 
        # this branch is to ensure consistent behaviour, whether we're run
116
 
        # inside a branch, or not.
117
 
        os.mkdir('empty_branch')
118
 
        os.chdir('empty_branch')
119
 
        self.runbzr('init')
120
 
        os.mkdir('branch')
121
 
        os.chdir('branch')
122
 
        self.runbzr('init')
123
 
        file('foo.c', 'wt').write('int main() {}')
124
 
        file('bar.c', 'wt').write('int main() {}')
125
 
        os.chdir('..')
126
 
        self.runbzr(['add', 'branch/foo.c'])
127
 
        self.runbzr(['add', 'branch'])
128
 
        # can't commit files in different trees; sane error
129
 
        self.runbzr('commit -m newstuff branch/foo.c .', retcode=1)
130
 
        self.runbzr('commit -m newstuff branch/foo.c')
131
 
        self.runbzr('commit -m newstuff branch')
132
 
        self.runbzr('commit -m newstuff branch', retcode=1)
133
 
 
134
 
 
135
88
    def test_ignore_patterns(self):
136
89
        from bzrlib.branch import Branch
137
90
        
138
 
        b = Branch.initialize('.')
 
91
        b = Branch('.', init=True)
139
92
        self.assertEquals(list(b.unknowns()), [])
140
93
 
141
94
        file('foo.tmp', 'wt').write('tmp files are ignored')
142
95
        self.assertEquals(list(b.unknowns()), [])
143
 
        assert self.capture('unknowns') == ''
 
96
        assert self.backtick('bzr unknowns') == ''
144
97
 
145
98
        file('foo.c', 'wt').write('int main() {}')
146
99
        self.assertEquals(list(b.unknowns()), ['foo.c'])
147
 
        assert self.capture('unknowns') == 'foo.c\n'
 
100
        assert self.backtick('bzr unknowns') == 'foo.c\n'
148
101
 
149
102
        self.runbzr(['add', 'foo.c'])
150
 
        assert self.capture('unknowns') == ''
 
103
        assert self.backtick('bzr unknowns') == ''
151
104
 
152
105
        # 'ignore' works when creating the .bzignore file
153
106
        file('foo.blah', 'wt').write('blah')
154
107
        self.assertEquals(list(b.unknowns()), ['foo.blah'])
155
108
        self.runbzr('ignore *.blah')
156
109
        self.assertEquals(list(b.unknowns()), [])
157
 
        assert file('.bzrignore', 'rU').read() == '*.blah\n'
 
110
        assert file('.bzrignore', 'rb').read() == '*.blah\n'
158
111
 
159
112
        # 'ignore' works when then .bzrignore file already exists
160
113
        file('garh', 'wt').write('garh')
161
114
        self.assertEquals(list(b.unknowns()), ['garh'])
162
 
        assert self.capture('unknowns') == 'garh\n'
 
115
        assert self.backtick('bzr unknowns') == 'garh\n'
163
116
        self.runbzr('ignore garh')
164
117
        self.assertEquals(list(b.unknowns()), [])
165
 
        assert file('.bzrignore', 'rU').read() == '*.blah\ngarh\n'
 
118
        assert file('.bzrignore', 'rb').read() == '*.blah\ngarh\n'
166
119
 
167
120
    def test_revert(self):
 
121
        import os
168
122
        self.runbzr('init')
169
123
 
170
124
        file('hello', 'wt').write('foo')
174
128
        file('goodbye', 'wt').write('baz')
175
129
        self.runbzr('add goodbye')
176
130
        self.runbzr('commit -m setup goodbye')
177
 
 
 
131
        
178
132
        file('hello', 'wt').write('bar')
179
133
        file('goodbye', 'wt').write('qux')
180
134
        self.runbzr('revert hello')
189
143
        os.rmdir('revertdir')
190
144
        self.runbzr('revert')
191
145
 
192
 
        os.symlink('/unlikely/to/exist', 'symlink')
193
 
        self.runbzr('add symlink')
194
 
        self.runbzr('commit -m f')
195
 
        os.unlink('symlink')
196
 
        self.runbzr('revert')
197
 
        self.failUnlessExists('symlink')
198
 
        os.unlink('symlink')
199
 
        os.symlink('a-different-path', 'symlink')
200
 
        self.runbzr('revert')
201
 
        self.assertEqual('/unlikely/to/exist',
202
 
                         os.readlink('symlink'))
203
 
        
204
 
        file('hello', 'wt').write('xyz')
205
 
        self.runbzr('commit -m xyz hello')
206
 
        self.runbzr('revert -r 1 hello')
207
 
        self.check_file_contents('hello', 'foo')
208
 
        self.runbzr('revert hello')
209
 
        self.check_file_contents('hello', 'xyz')
210
 
        os.chdir('revertdir')
211
 
        self.runbzr('revert')
212
 
        os.chdir('..')
213
 
 
214
 
 
215
 
    def test_mv_modes(self):
 
146
    def skipped_test_mv_modes(self):
216
147
        """Test two modes of operation for mv"""
217
148
        from bzrlib.branch import Branch
218
 
        b = Branch.initialize('.')
 
149
        b = Branch('.', init=True)
219
150
        self.build_tree(['a', 'c', 'subdir/'])
220
 
        self.run_bzr_captured(['add', self.test_dir])
221
 
        self.run_bzr_captured(['mv', 'a', 'b'])
222
 
        self.run_bzr_captured(['mv', 'b', 'subdir'])
223
 
        self.run_bzr_captured(['mv', 'subdir/b', 'a'])
224
 
        self.run_bzr_captured(['mv', 'a', 'c', 'subdir'])
225
 
        self.run_bzr_captured(['mv', 'subdir/a', 'subdir/newa'])
 
151
        self.run_bzr('mv', 'a', 'b')
 
152
        self.run_bzr('mv', 'b', 'subdir')
 
153
        self.run_bzr('mv', 'subdir/b', 'a')
 
154
        self.run_bzr('mv', 'a', 'b', 'subdir')
 
155
        self.run_bzr('mv', 'subdir/a', 'subdir/newa')
226
156
 
227
157
    def test_main_version(self):
228
158
        """Check output from version command and master option is reasonable"""
248
178
        test.runbzr('add goodbye')
249
179
        test.runbzr('commit -m setup goodbye')
250
180
 
251
 
    def test_export(self):
252
 
        os.mkdir('branch')
253
 
        os.chdir('branch')
254
 
        self.example_branch()
255
 
        self.runbzr('export ../latest')
256
 
        self.assertEqual(file('../latest/goodbye', 'rt').read(), 'baz')
257
 
        self.runbzr('export ../first -r 1')
258
 
        assert not os.path.exists('../first/goodbye')
259
 
        self.assertEqual(file('../first/hello', 'rt').read(), 'foo')
260
 
        self.runbzr('export ../first.gz -r 1')
261
 
        self.assertEqual(file('../first.gz/hello', 'rt').read(), 'foo')
262
 
        self.runbzr('export ../first.bz2 -r 1')
263
 
        self.assertEqual(file('../first.bz2/hello', 'rt').read(), 'foo')
264
 
        self.runbzr('export ../first.tar -r 1')
265
 
        assert os.path.isfile('../first.tar')
266
 
        from tarfile import TarFile
267
 
        tf = TarFile('../first.tar')
268
 
        assert 'first/hello' in tf.getnames(), tf.getnames()
269
 
        self.assertEqual(tf.extractfile('first/hello').read(), 'foo')
270
 
        self.runbzr('export ../first.tar.gz -r 1')
271
 
        assert os.path.isfile('../first.tar.gz')
272
 
        self.runbzr('export ../first.tbz2 -r 1')
273
 
        assert os.path.isfile('../first.tbz2')
274
 
        self.runbzr('export ../first.tar.bz2 -r 1')
275
 
        assert os.path.isfile('../first.tar.bz2')
276
 
        self.runbzr('export ../first.tar.tbz2 -r 1')
277
 
        assert os.path.isfile('../first.tar.tbz2')
278
 
        from bz2 import BZ2File
279
 
        tf = TarFile('../first.tar.tbz2', 
280
 
                     fileobj=BZ2File('../first.tar.tbz2', 'r'))
281
 
        assert 'first.tar/hello' in tf.getnames(), tf.getnames()
282
 
        self.assertEqual(tf.extractfile('first.tar/hello').read(), 'foo')
283
 
        self.runbzr('export ../first2.tar -r 1 --root pizza')
284
 
        tf = TarFile('../first2.tar')
285
 
        assert 'pizza/hello' in tf.getnames(), tf.getnames()
286
 
 
287
 
    def test_diff(self):
288
 
        self.example_branch()
289
 
        file('hello', 'wt').write('hello world!')
290
 
        self.runbzr('commit -m fixing hello')
291
 
        output = self.runbzr('diff -r 2..3', backtick=1, retcode=1)
292
 
        self.assert_('\n+hello world!' in output)
293
 
        output = self.runbzr('diff -r last:3..last:1', backtick=1, retcode=1)
294
 
        self.assert_('\n+baz' in output)
295
 
 
296
 
    def test_diff_branches(self):
297
 
        self.build_tree(['branch1/', 'branch1/file', 'branch2/'])
298
 
        branch = Branch.initialize('branch1')
299
 
        branch.add(['file'])
300
 
        branch.commit('add file')
301
 
        copy_branch(branch, 'branch2')
302
 
        print >> open('branch2/file', 'w'), 'new content'
303
 
        branch2 = Branch.open('branch2')
304
 
        branch2.commit('update file')
305
 
        # should open branch1 and diff against branch2, 
306
 
        output = self.run_bzr_captured(['diff', '-r', 'branch:branch2', 
307
 
                                        'branch1'],
308
 
                                       retcode=1)
309
 
        self.assertEquals(("=== modified file 'file'\n"
310
 
                           "--- file\n"
311
 
                           "+++ file\n"
312
 
                           "@@ -1,1 +1,1 @@\n"
313
 
                           "-new content\n"
314
 
                           "+contents of branch1/file\n"
315
 
                           "\n", ''), output)
316
 
 
317
 
    def test_branch(self):
318
 
        """Branch from one branch to another."""
319
 
        os.mkdir('a')
320
 
        os.chdir('a')
321
 
        self.example_branch()
322
 
        os.chdir('..')
323
 
        self.runbzr('branch a b')
324
 
        self.assertFileEqual('b\n', 'b/.bzr/branch-name')
325
 
        self.runbzr('branch a c -r 1')
326
 
        os.chdir('b')
327
 
        self.runbzr('commit -m foo --unchanged')
328
 
        os.chdir('..')
329
 
        # naughty - abstraction violations RBC 20050928  
330
 
        print "test_branch used to delete the stores, how is this meant to work ?"
331
 
        #shutil.rmtree('a/.bzr/revision-store')
332
 
        #shutil.rmtree('a/.bzr/inventory-store', ignore_errors=True)
333
 
        #shutil.rmtree('a/.bzr/text-store', ignore_errors=True)
334
 
        self.runbzr('branch a d --basis b')
 
181
    def test_revert(self):
 
182
        self.example_branch()
 
183
        file('hello', 'wt').write('bar')
 
184
        file('goodbye', 'wt').write('qux')
 
185
        self.runbzr('revert hello')
 
186
        self.check_file_contents('hello', 'foo')
 
187
        self.check_file_contents('goodbye', 'qux')
 
188
        self.runbzr('revert')
 
189
        self.check_file_contents('goodbye', 'baz')
335
190
 
336
191
    def test_merge(self):
337
192
        from bzrlib.branch import Branch
 
193
        import os
338
194
        
339
195
        os.mkdir('a')
340
196
        os.chdir('a')
 
197
 
341
198
        self.example_branch()
342
199
        os.chdir('..')
343
200
        self.runbzr('branch a b')
350
207
        # We can't merge when there are in-tree changes
351
208
        self.runbzr('merge ../b', retcode=1)
352
209
        self.runbzr(['commit', '-m', "Like an epidemic of u's"])
353
 
        self.runbzr('merge ../b -r last:1..last:1 --merge-type blooof',
354
 
                    retcode=1)
355
 
        self.runbzr('merge ../b -r last:1..last:1 --merge-type merge3')
356
 
        self.runbzr('revert --no-backup')
357
 
        self.runbzr('merge ../b -r last:1..last:1 --merge-type weave')
358
 
        self.runbzr('revert --no-backup')
359
 
        self.runbzr('merge ../b -r last:1..last:1 --reprocess')
360
 
        self.runbzr('revert --no-backup')
361
 
        self.runbzr('merge ../b -r last:1')
 
210
        self.runbzr('merge ../b')
362
211
        self.check_file_contents('goodbye', 'quux')
363
212
        # Merging a branch pulls its revision into the tree
364
 
        a = Branch.open('.')
365
 
        b = Branch.open('../b')
366
 
        a.get_revision_xml(b.last_revision())
 
213
        a = Branch('.')
 
214
        b = Branch('../b')
 
215
        a.get_revision_xml(b.last_patch())
 
216
 
367
217
        self.log('pending merges: %s', a.pending_merges())
368
 
        assert a.pending_merges() == [b.last_revision()], "Assertion %s %s" \
369
 
            % (a.pending_merges(), b.last_patch())
370
 
        self.runbzr('commit -m merged')
371
 
        self.runbzr('merge ../b -r last:1')
372
 
        self.assertEqual(Branch.open('.').pending_merges(), [])
373
 
 
374
 
 
375
 
    def test_merge_with_missing_file(self):
376
 
        """Merge handles missing file conflicts"""
377
 
        os.mkdir('a')
378
 
        os.chdir('a')
379
 
        os.mkdir('sub')
380
 
        print >> file('sub/a.txt', 'wb'), "hello"
381
 
        print >> file('b.txt', 'wb'), "hello"
382
 
        print >> file('sub/c.txt', 'wb'), "hello"
383
 
        self.runbzr('init')
384
 
        self.runbzr('add')
385
 
        self.runbzr(('commit', '-m', 'added a'))
386
 
        self.runbzr('branch . ../b')
387
 
        print >> file('sub/a.txt', 'ab'), "there"
388
 
        print >> file('b.txt', 'ab'), "there"
389
 
        print >> file('sub/c.txt', 'ab'), "there"
390
 
        self.runbzr(('commit', '-m', 'Added there'))
391
 
        os.unlink('sub/a.txt')
392
 
        os.unlink('sub/c.txt')
393
 
        os.rmdir('sub')
394
 
        os.unlink('b.txt')
395
 
        self.runbzr(('commit', '-m', 'Removed a.txt'))
396
 
        os.chdir('../b')
397
 
        print >> file('sub/a.txt', 'ab'), "something"
398
 
        print >> file('b.txt', 'ab'), "something"
399
 
        print >> file('sub/c.txt', 'ab'), "something"
400
 
        self.runbzr(('commit', '-m', 'Modified a.txt'))
401
 
        self.runbzr('merge ../a/', retcode=1)
402
 
        assert os.path.exists('sub/a.txt.THIS')
403
 
        assert os.path.exists('sub/a.txt.BASE')
404
 
        os.chdir('../a')
405
 
        self.runbzr('merge ../b/', retcode=1)
406
 
        assert os.path.exists('sub/a.txt.OTHER')
407
 
        assert os.path.exists('sub/a.txt.BASE')
408
 
 
409
 
    def test_pull(self):
410
 
        """Pull changes from one branch to another."""
411
 
        os.mkdir('a')
412
 
        os.chdir('a')
413
 
 
414
 
        self.example_branch()
415
 
        self.runbzr('pull', retcode=1)
416
 
        self.runbzr('missing', retcode=1)
417
 
        self.runbzr('missing .')
418
 
        self.runbzr('missing')
419
 
        self.runbzr('pull')
420
 
        self.runbzr('pull /', retcode=1)
421
 
        self.runbzr('pull')
422
 
 
423
 
        os.chdir('..')
424
 
        self.runbzr('branch a b')
425
 
        os.chdir('b')
426
 
        self.runbzr('pull')
427
 
        os.mkdir('subdir')
428
 
        self.runbzr('add subdir')
429
 
        self.runbzr('commit -m blah --unchanged')
430
 
        os.chdir('../a')
431
 
        a = Branch.open('.')
432
 
        b = Branch.open('../b')
433
 
        assert a.revision_history() == b.revision_history()[:-1]
434
 
        self.runbzr('pull ../b')
435
 
        assert a.revision_history() == b.revision_history()
436
 
        self.runbzr('commit -m blah2 --unchanged')
437
 
        os.chdir('../b')
438
 
        self.runbzr('commit -m blah3 --unchanged')
439
 
        # no overwrite
440
 
        self.runbzr('pull ../a', retcode=1)
441
 
        os.chdir('..')
442
 
        self.runbzr('branch b overwriteme')
443
 
        os.chdir('overwriteme')
444
 
        self.runbzr('pull --overwrite ../a')
445
 
        overwritten = Branch.open('.')
446
 
        self.assertEqual(overwritten.revision_history(),
447
 
                         a.revision_history())
448
 
        os.chdir('../a')
449
 
        self.runbzr('merge ../b')
450
 
        self.runbzr('commit -m blah4 --unchanged')
451
 
        os.chdir('../b/subdir')
452
 
        self.runbzr('pull ../../a')
453
 
        assert a.revision_history()[-1] == b.revision_history()[-1]
454
 
        self.runbzr('commit -m blah5 --unchanged')
455
 
        self.runbzr('commit -m blah6 --unchanged')
456
 
        os.chdir('..')
457
 
        self.runbzr('pull ../a')
458
 
        os.chdir('../a')
459
 
        self.runbzr('commit -m blah7 --unchanged')
460
 
        self.runbzr('merge ../b')
461
 
        self.runbzr('commit -m blah8 --unchanged')
462
 
        self.runbzr('pull ../b')
463
 
        self.runbzr('pull ../b')
464
 
 
465
 
    def test_ls(self):
466
 
        """Test the abilities of 'bzr ls'"""
467
 
        bzr = self.runbzr
468
 
        def bzrout(*args, **kwargs):
469
 
            kwargs['backtick'] = True
470
 
            return self.runbzr(*args, **kwargs)
471
 
 
472
 
        def ls_equals(value, *args):
473
 
            out = self.runbzr(['ls'] + list(args), backtick=True)
474
 
            self.assertEquals(out, value)
475
 
 
476
 
        bzr('init')
477
 
        open('a', 'wb').write('hello\n')
478
 
 
479
 
        # Can't supply both
480
 
        bzr('ls --verbose --null', retcode=1)
481
 
 
482
 
        ls_equals('a\n')
483
 
        ls_equals('?        a\n', '--verbose')
484
 
        ls_equals('a\n', '--unknown')
485
 
        ls_equals('', '--ignored')
486
 
        ls_equals('', '--versioned')
487
 
        ls_equals('a\n', '--unknown', '--ignored', '--versioned')
488
 
        ls_equals('', '--ignored', '--versioned')
489
 
        ls_equals('a\0', '--null')
490
 
 
491
 
        bzr('add a')
492
 
        ls_equals('V        a\n', '--verbose')
493
 
        bzr('commit -m add')
494
 
        
495
 
        os.mkdir('subdir')
496
 
        ls_equals('V        a\n'
497
 
                  '?        subdir/\n'
498
 
                  , '--verbose')
499
 
        open('subdir/b', 'wb').write('b\n')
500
 
        bzr('add')
501
 
        ls_equals('V        a\n'
502
 
                  'V        subdir/\n'
503
 
                  'V        subdir/b\n'
504
 
                  , '--verbose')
505
 
        bzr('commit -m subdir')
506
 
 
507
 
        ls_equals('a\n'
508
 
                  'subdir\n'
509
 
                  , '--non-recursive')
510
 
 
511
 
        ls_equals('V        a\n'
512
 
                  'V        subdir/\n'
513
 
                  , '--verbose', '--non-recursive')
514
 
 
515
 
        # Check what happens in a sub-directory
516
 
        os.chdir('subdir')
517
 
        ls_equals('b\n')
518
 
        ls_equals('b\0'
519
 
                  , '--null')
520
 
        ls_equals('a\n'
521
 
                  'subdir\n'
522
 
                  'subdir/b\n'
523
 
                  , '--from-root')
524
 
        ls_equals('a\0'
525
 
                  'subdir\0'
526
 
                  'subdir/b\0'
527
 
                  , '--from-root', '--null')
528
 
        ls_equals('a\n'
529
 
                  'subdir\n'
530
 
                  , '--from-root', '--non-recursive')
531
 
 
532
 
        os.chdir('..')
533
 
 
534
 
        # Check what happens when we supply a specific revision
535
 
        ls_equals('a\n', '--revision', '1')
536
 
        ls_equals('V        a\n'
537
 
                  , '--verbose', '--revision', '1')
538
 
 
539
 
        os.chdir('subdir')
540
 
        ls_equals('', '--revision', '1')
541
 
 
542
 
        # Now try to do ignored files.
543
 
        os.chdir('..')
544
 
        open('blah.py', 'wb').write('unknown\n')
545
 
        open('blah.pyo', 'wb').write('ignored\n')
546
 
        ls_equals('a\n'
547
 
                  'blah.py\n'
548
 
                  'blah.pyo\n'
549
 
                  'subdir\n'
550
 
                  'subdir/b\n')
551
 
        ls_equals('V        a\n'
552
 
                  '?        blah.py\n'
553
 
                  'I        blah.pyo\n'
554
 
                  'V        subdir/\n'
555
 
                  'V        subdir/b\n'
556
 
                  , '--verbose')
557
 
        ls_equals('blah.pyo\n'
558
 
                  , '--ignored')
559
 
        ls_equals('blah.py\n'
560
 
                  , '--unknown')
561
 
        ls_equals('a\n'
562
 
                  'subdir\n'
563
 
                  'subdir/b\n'
564
 
                  , '--versioned')
565
 
 
566
 
 
567
 
    def test_locations(self):
568
 
        """Using and remembering different locations"""
569
 
        os.mkdir('a')
570
 
        os.chdir('a')
571
 
        self.runbzr('init')
572
 
        self.runbzr('commit -m unchanged --unchanged')
573
 
        self.runbzr('pull', retcode=1)
574
 
        self.runbzr('merge', retcode=1)
575
 
        self.runbzr('branch . ../b')
576
 
        os.chdir('../b')
577
 
        self.runbzr('pull')
578
 
        self.runbzr('branch . ../c')
579
 
        self.runbzr('pull ../c')
580
 
        self.runbzr('merge')
581
 
        os.chdir('../a')
582
 
        self.runbzr('pull ../b')
583
 
        self.runbzr('pull')
584
 
        self.runbzr('pull ../c')
585
 
        self.runbzr('branch ../c ../d')
586
 
        shutil.rmtree('../c')
587
 
        self.runbzr('pull')
588
 
        os.chdir('../b')
589
 
        self.runbzr('pull')
590
 
        os.chdir('../d')
591
 
        self.runbzr('pull', retcode=1)
592
 
        self.runbzr('pull ../a --remember')
593
 
        self.runbzr('pull')
594
 
        
595
 
    def test_add_reports(self):
596
 
        """add command prints the names of added files."""
597
 
        b = Branch.initialize('.')
598
 
        self.build_tree(['top.txt', 'dir/', 'dir/sub.txt'])
599
 
        out = self.run_bzr_captured(['add'], retcode = 0)[0]
600
 
        # the ordering is not defined at the moment
601
 
        results = sorted(out.rstrip('\n').split('\n'))
602
 
        self.assertEquals(['added dir',
603
 
                           'added dir'+os.sep+'sub.txt',
604
 
                           'added top.txt',],
605
 
                          results)
606
 
 
607
 
    def test_add_quiet_is(self):
608
 
        """add -q does not print 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', '-q'], retcode = 0)[0]
612
 
        # the ordering is not defined at the moment
613
 
        results = sorted(out.rstrip('\n').split('\n'))
614
 
        self.assertEquals([''], results)
615
 
 
616
 
    def test_unknown_command(self):
617
 
        """Handling of unknown command."""
618
 
        out, err = self.run_bzr_captured(['fluffy-badger'],
619
 
                                         retcode=1)
620
 
        self.assertEquals(out, '')
621
 
        err.index('unknown command')
622
 
 
623
 
    def test_conflicts(self):
624
 
        """Handling of merge conflicts"""
625
 
        os.mkdir('base')
626
 
        os.chdir('base')
627
 
        file('hello', 'wb').write("hi world")
628
 
        file('answer', 'wb').write("42")
629
 
        self.runbzr('init')
630
 
        self.runbzr('add')
631
 
        self.runbzr('commit -m base')
632
 
        self.runbzr('branch . ../other')
633
 
        self.runbzr('branch . ../this')
634
 
        os.chdir('../other')
635
 
        file('hello', 'wb').write("Hello.")
636
 
        file('answer', 'wb').write("Is anyone there?")
637
 
        self.runbzr('commit -m other')
638
 
        os.chdir('../this')
639
 
        file('hello', 'wb').write("Hello, world")
640
 
        self.runbzr('mv answer question')
641
 
        file('question', 'wb').write("What do you get when you multiply six"
642
 
                                   "times nine?")
643
 
        self.runbzr('commit -m this')
644
 
        self.runbzr('merge ../other --show-base', retcode=1)
645
 
        conflict_text = file('hello').read()
646
 
        assert '<<<<<<<' in conflict_text
647
 
        assert '>>>>>>>' in conflict_text
648
 
        assert '=======' in conflict_text
649
 
        assert '|||||||' in conflict_text
650
 
        assert 'hi world' in conflict_text
651
 
        self.runbzr('revert')
652
 
        self.runbzr('resolve --all')
653
 
        self.runbzr('merge ../other', retcode=1)
654
 
        conflict_text = file('hello').read()
655
 
        assert '|||||||' not in conflict_text
656
 
        assert 'hi world' not in conflict_text
657
 
        result = self.runbzr('conflicts', backtick=1)
658
 
        self.assertEquals(result, "hello\nquestion\n")
659
 
        result = self.runbzr('status', backtick=1)
660
 
        assert "conflicts:\n  hello\n  question\n" in result, result
661
 
        self.runbzr('resolve hello')
662
 
        result = self.runbzr('conflicts', backtick=1)
663
 
        self.assertEquals(result, "question\n")
664
 
        self.runbzr('commit -m conflicts', retcode=1)
665
 
        self.runbzr('resolve --all')
666
 
        result = self.runbzr('conflicts', backtick=1)
667
 
        self.runbzr('commit -m conflicts')
668
 
        self.assertEquals(result, "")
669
 
 
670
 
    def test_resign(self):
671
 
        """Test re signing of data."""
672
 
        import bzrlib.gpg
673
 
        oldstrategy = bzrlib.gpg.GPGStrategy
674
 
        branch = Branch.initialize('.')
675
 
        branch.commit("base", allow_pointless=True, rev_id='A')
676
 
        try:
677
 
            # monkey patch gpg signing mechanism
678
 
            from bzrlib.testament import Testament
679
 
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
680
 
            self.runbzr('re-sign -r revid:A')
681
 
            self.assertEqual(Testament.from_revision(branch,'A').as_short_text(),
682
 
                             branch.revision_store.get('A', 'sig').read())
683
 
        finally:
684
 
            bzrlib.gpg.GPGStrategy = oldstrategy
685
 
            
686
 
    def test_resign_range(self):
687
 
        import bzrlib.gpg
688
 
        oldstrategy = bzrlib.gpg.GPGStrategy
689
 
        branch = Branch.initialize('.')
690
 
        branch.commit("base", allow_pointless=True, rev_id='A')
691
 
        branch.commit("base", allow_pointless=True, rev_id='B')
692
 
        branch.commit("base", allow_pointless=True, rev_id='C')
693
 
        try:
694
 
            # monkey patch gpg signing mechanism
695
 
            from bzrlib.testament import Testament
696
 
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
697
 
            self.runbzr('re-sign -r 1..')
698
 
            self.assertEqual(Testament.from_revision(branch,'A').as_short_text(),
699
 
                             branch.revision_store.get('A', 'sig').read())
700
 
            self.assertEqual(Testament.from_revision(branch,'B').as_short_text(),
701
 
                             branch.revision_store.get('B', 'sig').read())
702
 
            self.assertEqual(Testament.from_revision(branch,'C').as_short_text(),
703
 
                             branch.revision_store.get('C', 'sig').read())
704
 
        finally:
705
 
            bzrlib.gpg.GPGStrategy = oldstrategy
706
 
 
707
 
    def test_push(self):
708
 
        # create a source branch
709
 
        os.mkdir('my-branch')
710
 
        os.chdir('my-branch')
711
 
        self.example_branch()
712
 
 
713
 
        # with no push target, fail
714
 
        self.runbzr('push', retcode=1)
715
 
        # with an explicit target work
716
 
        self.runbzr('push ../output-branch')
717
 
        # with an implicit target work
718
 
        self.runbzr('push')
719
 
        # nothing missing
720
 
        self.runbzr('missing ../output-branch')
721
 
        # advance this branch
722
 
        self.runbzr('commit --unchanged -m unchanged')
723
 
 
724
 
        os.chdir('../output-branch')
725
 
        # should be a diff as we have not pushed the tree
726
 
        self.runbzr('diff', retcode=1)
727
 
        self.runbzr('revert')
728
 
        # but not now.
729
 
        self.runbzr('diff')
730
 
        # diverge the branches
731
 
        self.runbzr('commit --unchanged -m unchanged')
732
 
        os.chdir('../my-branch')
733
 
        # cannot push now
734
 
        self.runbzr('push', retcode=1)
735
 
        # and there are difference
736
 
        self.runbzr('missing ../output-branch', retcode=1)
737
 
        # but we can force a push
738
 
        self.runbzr('push --overwrite')
739
 
        # nothing missing
740
 
        self.runbzr('missing ../output-branch')
741
 
 
742
 
 
743
 
def listdir_sorted(dir):
744
 
    L = os.listdir(dir)
745
 
    L.sort()
746
 
    return L
747
 
 
 
218
#        assert a.pending_merges() == [b.last_patch()], "Assertion %s %s" \
 
219
#        % (a.pending_merges(), b.last_patch())
748
220
 
749
221
class OldTests(ExternalBase):
750
222
    """old tests moved from ./testbzr."""
752
224
    def test_bzr(self):
753
225
        from os import chdir, mkdir
754
226
        from os.path import exists
 
227
        import os
755
228
 
756
229
        runbzr = self.runbzr
757
 
        capture = self.capture
 
230
        backtick = self.backtick
758
231
        progress = self.log
759
232
 
760
233
        progress("basic branch creation")
762
235
        chdir('branch1')
763
236
        runbzr('init')
764
237
 
765
 
        self.assertEquals(capture('root').rstrip(),
 
238
        self.assertEquals(backtick('bzr root').rstrip(),
766
239
                          os.path.join(self.test_dir, 'branch1'))
767
240
 
768
241
        progress("status of new file")
771
244
        f.write('hello world!\n')
772
245
        f.close()
773
246
 
774
 
        self.assertEquals(capture('unknowns'), 'test.txt\n')
 
247
        out = backtick("bzr unknowns")
 
248
        self.assertEquals(out, 'test.txt\n')
775
249
 
776
 
        out = capture("status")
 
250
        out = backtick("bzr status")
777
251
        assert out == 'unknown:\n  test.txt\n'
778
252
 
779
 
        out = capture("status --all")
 
253
        out = backtick("bzr status --all")
780
254
        assert out == "unknown:\n  test.txt\n"
781
255
 
782
 
        out = capture("status test.txt --all")
 
256
        out = backtick("bzr status test.txt --all")
783
257
        assert out == "unknown:\n  test.txt\n"
784
258
 
785
259
        f = file('test2.txt', 'wt')
786
260
        f.write('goodbye cruel world...\n')
787
261
        f.close()
788
262
 
789
 
        out = capture("status test.txt")
 
263
        out = backtick("bzr status test.txt")
790
264
        assert out == "unknown:\n  test.txt\n"
791
265
 
792
 
        out = capture("status")
 
266
        out = backtick("bzr status")
793
267
        assert out == ("unknown:\n"
794
268
                       "  test.txt\n"
795
269
                       "  test2.txt\n")
797
271
        os.unlink('test2.txt')
798
272
 
799
273
        progress("command aliases")
800
 
        out = capture("st --all")
 
274
        out = backtick("bzr st --all")
801
275
        assert out == ("unknown:\n"
802
276
                       "  test.txt\n")
803
277
 
804
 
        out = capture("stat")
 
278
        out = backtick("bzr stat")
805
279
        assert out == ("unknown:\n"
806
280
                       "  test.txt\n")
807
281
 
811
285
        runbzr("help commands")
812
286
        runbzr("help slartibartfast", 1)
813
287
 
814
 
        out = capture("help ci")
 
288
        out = backtick("bzr help ci")
815
289
        out.index('aliases: ')
816
290
 
817
291
        progress("can't rename unversioned file")
820
294
        progress("adding a file")
821
295
 
822
296
        runbzr("add test.txt")
823
 
        assert capture("unknowns") == ''
824
 
        assert capture("status --all") == ("added:\n"
 
297
        assert backtick("bzr unknowns") == ''
 
298
        assert backtick("bzr status --all") == ("added:\n"
825
299
                                                "  test.txt\n")
826
300
 
827
301
        progress("rename newly-added file")
829
303
        assert os.path.exists("hello.txt")
830
304
        assert not os.path.exists("test.txt")
831
305
 
832
 
        assert capture("revno") == '0\n'
 
306
        assert backtick("bzr revno") == '0\n'
833
307
 
834
308
        progress("add first revision")
835
309
        runbzr(['commit', '-m', 'add first revision'])
843
317
        runbzr("add sub1")
844
318
        runbzr("rename sub1 sub2")
845
319
        runbzr("move hello.txt sub2")
846
 
        self.assertEqual(capture("relpath sub2/hello.txt"),
847
 
                         os.path.join("sub2", "hello.txt\n"))
 
320
        assert backtick("bzr relpath sub2/hello.txt") == os.path.join("sub2", "hello.txt\n")
848
321
 
849
322
        assert exists("sub2")
850
323
        assert exists("sub2/hello.txt")
865
338
        runbzr(['commit', '-m', 'rename nested subdirectories'])
866
339
 
867
340
        chdir('sub1/sub2')
868
 
        self.assertEquals(capture('root')[:-1],
 
341
        self.assertEquals(backtick('bzr root')[:-1],
869
342
                          os.path.join(self.test_dir, 'branch1'))
870
343
        runbzr('move ../hello.txt .')
871
344
        assert exists('./hello.txt')
872
 
        self.assertEquals(capture('relpath hello.txt'),
873
 
                          os.path.join('sub1', 'sub2', 'hello.txt') + '\n')
874
 
        assert capture('relpath ../../sub1/sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
 
345
        assert backtick('bzr relpath hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
 
346
        assert backtick('bzr relpath ../../sub1/sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
875
347
        runbzr(['commit', '-m', 'move to parent directory'])
876
348
        chdir('..')
877
 
        assert capture('relpath sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
 
349
        assert backtick('bzr relpath sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
878
350
 
879
351
        runbzr('move sub2/hello.txt .')
880
352
        assert exists('hello.txt')
884
356
        f.close()
885
357
 
886
358
        f = file('msg.tmp', 'wt')
887
 
        f.write('this is my new commit\nand it has multiple lines, for fun')
 
359
        f.write('this is my new commit\n')
888
360
        f.close()
889
361
 
890
362
        runbzr('commit -F msg.tmp')
891
363
 
892
 
        assert capture('revno') == '5\n'
 
364
        assert backtick('bzr revno') == '5\n'
893
365
        runbzr('export -r 5 export-5.tmp')
894
366
        runbzr('export export.tmp')
895
367
 
897
369
        runbzr('log -v')
898
370
        runbzr('log -v --forward')
899
371
        runbzr('log -m', retcode=1)
900
 
        log_out = capture('log -m commit')
901
 
        assert "this is my new commit\n  and" in log_out
 
372
        log_out = backtick('bzr log -m commit')
 
373
        assert "this is my new commit" in log_out
902
374
        assert "rename nested" not in log_out
903
375
        assert 'revision-id' not in log_out
904
 
        assert 'revision-id' in capture('log --show-ids -m commit')
905
 
 
906
 
        log_out = capture('log --line')
907
 
        for line in log_out.splitlines():
908
 
            assert len(line) <= 79, len(line)
909
 
        assert "this is my new commit and" in log_out
 
376
        assert 'revision-id' in backtick('bzr log --show-ids -m commit')
910
377
 
911
378
 
912
379
        progress("file with spaces in name")
913
380
        mkdir('sub directory')
914
381
        file('sub directory/file with spaces ', 'wt').write('see how this works\n')
915
382
        runbzr('add .')
916
 
        runbzr('diff', retcode=1)
 
383
        runbzr('diff')
917
384
        runbzr('commit -m add-spaces')
918
385
        runbzr('check')
919
386
 
922
389
 
923
390
        runbzr('info')
924
391
 
925
 
        if has_symlinks():
926
 
            progress("symlinks")
927
 
            mkdir('symlinks')
928
 
            chdir('symlinks')
929
 
            runbzr('init')
930
 
            os.symlink("NOWHERE1", "link1")
931
 
            runbzr('add link1')
932
 
            assert self.capture('unknowns') == ''
933
 
            runbzr(['commit', '-m', '1: added symlink link1'])
934
 
    
935
 
            mkdir('d1')
936
 
            runbzr('add d1')
937
 
            assert self.capture('unknowns') == ''
938
 
            os.symlink("NOWHERE2", "d1/link2")
939
 
            assert self.capture('unknowns') == 'd1/link2\n'
940
 
            # is d1/link2 found when adding d1
941
 
            runbzr('add d1')
942
 
            assert self.capture('unknowns') == ''
943
 
            os.symlink("NOWHERE3", "d1/link3")
944
 
            assert self.capture('unknowns') == 'd1/link3\n'
945
 
            runbzr(['commit', '-m', '2: added dir, symlink'])
946
 
    
947
 
            runbzr('rename d1 d2')
948
 
            runbzr('move d2/link2 .')
949
 
            runbzr('move link1 d2')
950
 
            assert os.readlink("./link2") == "NOWHERE2"
951
 
            assert os.readlink("d2/link1") == "NOWHERE1"
952
 
            runbzr('add d2/link3')
953
 
            runbzr('diff', retcode=1)
954
 
            runbzr(['commit', '-m', '3: rename of dir, move symlinks, add link3'])
955
 
    
956
 
            os.unlink("link2")
957
 
            os.symlink("TARGET 2", "link2")
958
 
            os.unlink("d2/link1")
959
 
            os.symlink("TARGET 1", "d2/link1")
960
 
            runbzr('diff', retcode=1)
961
 
            assert self.capture("relpath d2/link1") == "d2/link1\n"
962
 
            runbzr(['commit', '-m', '4: retarget of two links'])
963
 
    
964
 
            runbzr('remove d2/link1')
965
 
            assert self.capture('unknowns') == 'd2/link1\n'
966
 
            runbzr(['commit', '-m', '5: remove d2/link1'])
967
 
            # try with the rm alias
968
 
            runbzr('add d2/link1')
969
 
            runbzr(['commit', '-m', '6: add d2/link1'])
970
 
            runbzr('rm d2/link1')
971
 
            assert self.capture('unknowns') == 'd2/link1\n'
972
 
            runbzr(['commit', '-m', '7: remove d2/link1'])
973
 
    
974
 
            os.mkdir("d1")
975
 
            runbzr('add d1')
976
 
            runbzr('rename d2/link3 d1/link3new')
977
 
            assert self.capture('unknowns') == 'd2/link1\n'
978
 
            runbzr(['commit', '-m', '8: remove d2/link1, move/rename link3'])
979
 
            
980
 
            runbzr(['check'])
981
 
            
982
 
            runbzr(['export', '-r', '1', 'exp1.tmp'])
983
 
            chdir("exp1.tmp")
984
 
            assert listdir_sorted(".") == [ "link1" ]
985
 
            assert os.readlink("link1") == "NOWHERE1"
986
 
            chdir("..")
987
 
            
988
 
            runbzr(['export', '-r', '2', 'exp2.tmp'])
989
 
            chdir("exp2.tmp")
990
 
            assert listdir_sorted(".") == [ "d1", "link1" ]
991
 
            chdir("..")
992
 
            
993
 
            runbzr(['export', '-r', '3', 'exp3.tmp'])
994
 
            chdir("exp3.tmp")
995
 
            assert listdir_sorted(".") == [ "d2", "link2" ]
996
 
            assert listdir_sorted("d2") == [ "link1", "link3" ]
997
 
            assert os.readlink("d2/link1") == "NOWHERE1"
998
 
            assert os.readlink("link2")    == "NOWHERE2"
999
 
            chdir("..")
1000
 
            
1001
 
            runbzr(['export', '-r', '4', 'exp4.tmp'])
1002
 
            chdir("exp4.tmp")
1003
 
            assert listdir_sorted(".") == [ "d2", "link2" ]
1004
 
            assert os.readlink("d2/link1") == "TARGET 1"
1005
 
            assert os.readlink("link2")    == "TARGET 2"
1006
 
            assert listdir_sorted("d2") == [ "link1", "link3" ]
1007
 
            chdir("..")
1008
 
            
1009
 
            runbzr(['export', '-r', '5', 'exp5.tmp'])
1010
 
            chdir("exp5.tmp")
1011
 
            assert listdir_sorted(".") == [ "d2", "link2" ]
1012
 
            assert os.path.islink("link2")
1013
 
            assert listdir_sorted("d2")== [ "link3" ]
1014
 
            chdir("..")
1015
 
            
1016
 
            runbzr(['export', '-r', '8', 'exp6.tmp'])
1017
 
            chdir("exp6.tmp")
1018
 
            self.assertEqual(listdir_sorted("."), [ "d1", "d2", "link2"])
1019
 
            assert listdir_sorted("d1") == [ "link3new" ]
1020
 
            assert listdir_sorted("d2") == []
1021
 
            assert os.readlink("d1/link3new") == "NOWHERE3"
1022
 
            chdir("..")
1023
 
        else:
1024
 
            progress("skipping symlink tests")
1025
 
 
1026
 
 
1027
 
class HttpTests(TestCaseWithWebserver):
1028
 
    """Test bzr ui commands against remote branches."""
1029
 
 
1030
 
    def test_branch(self):
1031
 
        os.mkdir('from')
1032
 
        branch = Branch.initialize('from')
1033
 
        branch.commit('empty commit for nonsense', allow_pointless=True)
1034
 
        url = self.get_remote_url('from')
1035
 
        self.run_bzr('branch', url, 'to')
1036
 
        branch = Branch.open('to')
1037
 
        self.assertEqual(1, len(branch.revision_history()))
1038
 
 
1039
 
    def test_log(self):
1040
 
        self.build_tree(['branch/', 'branch/file'])
1041
 
        branch = Branch.initialize('branch')
1042
 
        branch.add(['file'])
1043
 
        branch.commit('add file', rev_id='A')
1044
 
        url = self.get_remote_url('branch/file')
1045
 
        output = self.capture('log %s' % url)
1046
 
        self.assertEqual(7, len(output.split('\n')))
1047
 
        
1048
 
 
1049
 
 
1050