~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/blackbox.py

  • Committer: mbp at sourcefrog
  • Date: 2005-03-19 01:41:44 UTC
  • Revision ID: mbp@sourcefrog.net-20050319014144-5298a74caebaf378
fix local-time-offset calculation

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by Canonical Ltd
2
 
# -*- coding: utf-8 -*-
3
 
 
4
 
# This program is free software; you can redistribute it and/or modify
5
 
# it under the terms of the GNU General Public License as published by
6
 
# the Free Software Foundation; either version 2 of the License, or
7
 
# (at your option) any later version.
8
 
 
9
 
# This program is distributed in the hope that it will be useful,
10
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
# GNU General Public License for more details.
13
 
 
14
 
# You should have received a copy of the GNU General Public License
15
 
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 
 
18
 
 
19
 
"""Black-box tests for bzr.
20
 
 
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.
24
 
"""
25
 
 
26
 
 
27
 
from cStringIO import StringIO
28
 
import os
29
 
import re
30
 
import shutil
31
 
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
 
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)
51
 
 
52
 
 
53
 
class TestCommands(ExternalBase):
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
 
    def test_whoami(self):
66
 
        # this should always identify something, if only "john@localhost"
67
 
        self.runbzr("whoami")
68
 
        self.runbzr("whoami --email")
69
 
 
70
 
        self.assertEquals(self.runbzr("whoami --email",
71
 
                                      backtick=True).count('@'), 1)
72
 
        
73
 
    def test_whoami_branch(self):
74
 
        """branch specific user identity works."""
75
 
        self.runbzr('init')
76
 
        f = file('.bzr/email', 'wt')
77
 
        f.write('Branch Identity <branch@identi.ty>')
78
 
        f.close()
79
 
        bzr_email = os.environ.get('BZREMAIL')
80
 
        if bzr_email is not None:
81
 
            del os.environ['BZREMAIL']
82
 
        whoami = self.runbzr("whoami",backtick=True)
83
 
        whoami_email = self.runbzr("whoami --email",backtick=True)
84
 
        self.assertTrue(whoami.startswith('Branch Identity <branch@identi.ty>'))
85
 
        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
 
 
96
 
    def test_invalid_commands(self):
97
 
        self.runbzr("pants", retcode=1)
98
 
        self.runbzr("--pants off", retcode=1)
99
 
        self.runbzr("diff --message foo", retcode=1)
100
 
 
101
 
    def test_empty_commit(self):
102
 
        self.runbzr("init")
103
 
        self.build_tree(['hello.txt'])
104
 
        self.runbzr("commit -m empty", retcode=1)
105
 
        self.runbzr("add hello.txt")
106
 
        self.runbzr("commit -m added")
107
 
 
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
 
    def test_ignore_patterns(self):
136
 
        from bzrlib.branch import Branch
137
 
        
138
 
        b = Branch.initialize('.')
139
 
        self.assertEquals(list(b.unknowns()), [])
140
 
 
141
 
        file('foo.tmp', 'wt').write('tmp files are ignored')
142
 
        self.assertEquals(list(b.unknowns()), [])
143
 
        assert self.capture('unknowns') == ''
144
 
 
145
 
        file('foo.c', 'wt').write('int main() {}')
146
 
        self.assertEquals(list(b.unknowns()), ['foo.c'])
147
 
        assert self.capture('unknowns') == 'foo.c\n'
148
 
 
149
 
        self.runbzr(['add', 'foo.c'])
150
 
        assert self.capture('unknowns') == ''
151
 
 
152
 
        # 'ignore' works when creating the .bzignore file
153
 
        file('foo.blah', 'wt').write('blah')
154
 
        self.assertEquals(list(b.unknowns()), ['foo.blah'])
155
 
        self.runbzr('ignore *.blah')
156
 
        self.assertEquals(list(b.unknowns()), [])
157
 
        assert file('.bzrignore', 'rU').read() == '*.blah\n'
158
 
 
159
 
        # 'ignore' works when then .bzrignore file already exists
160
 
        file('garh', 'wt').write('garh')
161
 
        self.assertEquals(list(b.unknowns()), ['garh'])
162
 
        assert self.capture('unknowns') == 'garh\n'
163
 
        self.runbzr('ignore garh')
164
 
        self.assertEquals(list(b.unknowns()), [])
165
 
        assert file('.bzrignore', 'rU').read() == '*.blah\ngarh\n'
166
 
 
167
 
    def test_revert(self):
168
 
        self.runbzr('init')
169
 
 
170
 
        file('hello', 'wt').write('foo')
171
 
        self.runbzr('add hello')
172
 
        self.runbzr('commit -m setup hello')
173
 
 
174
 
        file('goodbye', 'wt').write('baz')
175
 
        self.runbzr('add goodbye')
176
 
        self.runbzr('commit -m setup goodbye')
177
 
 
178
 
        file('hello', 'wt').write('bar')
179
 
        file('goodbye', 'wt').write('qux')
180
 
        self.runbzr('revert hello')
181
 
        self.check_file_contents('hello', 'foo')
182
 
        self.check_file_contents('goodbye', 'qux')
183
 
        self.runbzr('revert')
184
 
        self.check_file_contents('goodbye', 'baz')
185
 
 
186
 
        os.mkdir('revertdir')
187
 
        self.runbzr('add revertdir')
188
 
        self.runbzr('commit -m f')
189
 
        os.rmdir('revertdir')
190
 
        self.runbzr('revert')
191
 
 
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):
216
 
        """Test two modes of operation for mv"""
217
 
        from bzrlib.branch import Branch
218
 
        b = Branch.initialize('.')
219
 
        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'])
226
 
 
227
 
    def test_main_version(self):
228
 
        """Check output from version command and master option is reasonable"""
229
 
        # output is intentionally passed through to stdout so that we
230
 
        # can see the version being tested
231
 
        output = self.runbzr('version', backtick=1)
232
 
        self.log('bzr version output:')
233
 
        self.log(output)
234
 
        self.assert_(output.startswith('bzr (bazaar-ng) '))
235
 
        self.assertNotEqual(output.index('Canonical'), -1)
236
 
        # make sure --version is consistent
237
 
        tmp_output = self.runbzr('--version', backtick=1)
238
 
        self.log('bzr --version output:')
239
 
        self.log(tmp_output)
240
 
        self.assertEquals(output, tmp_output)
241
 
 
242
 
    def example_branch(test):
243
 
        test.runbzr('init')
244
 
        file('hello', 'wt').write('foo')
245
 
        test.runbzr('add hello')
246
 
        test.runbzr('commit -m setup hello')
247
 
        file('goodbye', 'wt').write('baz')
248
 
        test.runbzr('add goodbye')
249
 
        test.runbzr('commit -m setup goodbye')
250
 
 
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')
335
 
 
336
 
    def test_merge(self):
337
 
        from bzrlib.branch import Branch
338
 
        
339
 
        os.mkdir('a')
340
 
        os.chdir('a')
341
 
        self.example_branch()
342
 
        os.chdir('..')
343
 
        self.runbzr('branch a b')
344
 
        os.chdir('b')
345
 
        file('goodbye', 'wt').write('quux')
346
 
        self.runbzr(['commit',  '-m',  "more u's are always good"])
347
 
 
348
 
        os.chdir('../a')
349
 
        file('hello', 'wt').write('quuux')
350
 
        # We can't merge when there are in-tree changes
351
 
        self.runbzr('merge ../b', retcode=1)
352
 
        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')
362
 
        self.check_file_contents('goodbye', 'quux')
363
 
        # 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())
367
 
        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
 
 
748
 
 
749
 
class OldTests(ExternalBase):
750
 
    """old tests moved from ./testbzr."""
751
 
 
752
 
    def test_bzr(self):
753
 
        from os import chdir, mkdir
754
 
        from os.path import exists
755
 
 
756
 
        runbzr = self.runbzr
757
 
        capture = self.capture
758
 
        progress = self.log
759
 
 
760
 
        progress("basic branch creation")
761
 
        mkdir('branch1')
762
 
        chdir('branch1')
763
 
        runbzr('init')
764
 
 
765
 
        self.assertEquals(capture('root').rstrip(),
766
 
                          os.path.join(self.test_dir, 'branch1'))
767
 
 
768
 
        progress("status of new file")
769
 
 
770
 
        f = file('test.txt', 'wt')
771
 
        f.write('hello world!\n')
772
 
        f.close()
773
 
 
774
 
        self.assertEquals(capture('unknowns'), 'test.txt\n')
775
 
 
776
 
        out = capture("status")
777
 
        assert out == 'unknown:\n  test.txt\n'
778
 
 
779
 
        out = capture("status --all")
780
 
        assert out == "unknown:\n  test.txt\n"
781
 
 
782
 
        out = capture("status test.txt --all")
783
 
        assert out == "unknown:\n  test.txt\n"
784
 
 
785
 
        f = file('test2.txt', 'wt')
786
 
        f.write('goodbye cruel world...\n')
787
 
        f.close()
788
 
 
789
 
        out = capture("status test.txt")
790
 
        assert out == "unknown:\n  test.txt\n"
791
 
 
792
 
        out = capture("status")
793
 
        assert out == ("unknown:\n"
794
 
                       "  test.txt\n"
795
 
                       "  test2.txt\n")
796
 
 
797
 
        os.unlink('test2.txt')
798
 
 
799
 
        progress("command aliases")
800
 
        out = capture("st --all")
801
 
        assert out == ("unknown:\n"
802
 
                       "  test.txt\n")
803
 
 
804
 
        out = capture("stat")
805
 
        assert out == ("unknown:\n"
806
 
                       "  test.txt\n")
807
 
 
808
 
        progress("command help")
809
 
        runbzr("help st")
810
 
        runbzr("help")
811
 
        runbzr("help commands")
812
 
        runbzr("help slartibartfast", 1)
813
 
 
814
 
        out = capture("help ci")
815
 
        out.index('aliases: ')
816
 
 
817
 
        progress("can't rename unversioned file")
818
 
        runbzr("rename test.txt new-test.txt", 1)
819
 
 
820
 
        progress("adding a file")
821
 
 
822
 
        runbzr("add test.txt")
823
 
        assert capture("unknowns") == ''
824
 
        assert capture("status --all") == ("added:\n"
825
 
                                                "  test.txt\n")
826
 
 
827
 
        progress("rename newly-added file")
828
 
        runbzr("rename test.txt hello.txt")
829
 
        assert os.path.exists("hello.txt")
830
 
        assert not os.path.exists("test.txt")
831
 
 
832
 
        assert capture("revno") == '0\n'
833
 
 
834
 
        progress("add first revision")
835
 
        runbzr(['commit', '-m', 'add first revision'])
836
 
 
837
 
        progress("more complex renames")
838
 
        os.mkdir("sub1")
839
 
        runbzr("rename hello.txt sub1", 1)
840
 
        runbzr("rename hello.txt sub1/hello.txt", 1)
841
 
        runbzr("move hello.txt sub1", 1)
842
 
 
843
 
        runbzr("add sub1")
844
 
        runbzr("rename sub1 sub2")
845
 
        runbzr("move hello.txt sub2")
846
 
        self.assertEqual(capture("relpath sub2/hello.txt"),
847
 
                         os.path.join("sub2", "hello.txt\n"))
848
 
 
849
 
        assert exists("sub2")
850
 
        assert exists("sub2/hello.txt")
851
 
        assert not exists("sub1")
852
 
        assert not exists("hello.txt")
853
 
 
854
 
        runbzr(['commit', '-m', 'commit with some things moved to subdirs'])
855
 
 
856
 
        mkdir("sub1")
857
 
        runbzr('add sub1')
858
 
        runbzr('move sub2/hello.txt sub1')
859
 
        assert not exists('sub2/hello.txt')
860
 
        assert exists('sub1/hello.txt')
861
 
        runbzr('move sub2 sub1')
862
 
        assert not exists('sub2')
863
 
        assert exists('sub1/sub2')
864
 
 
865
 
        runbzr(['commit', '-m', 'rename nested subdirectories'])
866
 
 
867
 
        chdir('sub1/sub2')
868
 
        self.assertEquals(capture('root')[:-1],
869
 
                          os.path.join(self.test_dir, 'branch1'))
870
 
        runbzr('move ../hello.txt .')
871
 
        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')
875
 
        runbzr(['commit', '-m', 'move to parent directory'])
876
 
        chdir('..')
877
 
        assert capture('relpath sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
878
 
 
879
 
        runbzr('move sub2/hello.txt .')
880
 
        assert exists('hello.txt')
881
 
 
882
 
        f = file('hello.txt', 'wt')
883
 
        f.write('some nice new content\n')
884
 
        f.close()
885
 
 
886
 
        f = file('msg.tmp', 'wt')
887
 
        f.write('this is my new commit\nand it has multiple lines, for fun')
888
 
        f.close()
889
 
 
890
 
        runbzr('commit -F msg.tmp')
891
 
 
892
 
        assert capture('revno') == '5\n'
893
 
        runbzr('export -r 5 export-5.tmp')
894
 
        runbzr('export export.tmp')
895
 
 
896
 
        runbzr('log')
897
 
        runbzr('log -v')
898
 
        runbzr('log -v --forward')
899
 
        runbzr('log -m', retcode=1)
900
 
        log_out = capture('log -m commit')
901
 
        assert "this is my new commit\n  and" in log_out
902
 
        assert "rename nested" not in log_out
903
 
        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
910
 
 
911
 
 
912
 
        progress("file with spaces in name")
913
 
        mkdir('sub directory')
914
 
        file('sub directory/file with spaces ', 'wt').write('see how this works\n')
915
 
        runbzr('add .')
916
 
        runbzr('diff', retcode=1)
917
 
        runbzr('commit -m add-spaces')
918
 
        runbzr('check')
919
 
 
920
 
        runbzr('log')
921
 
        runbzr('log --forward')
922
 
 
923
 
        runbzr('info')
924
 
 
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