~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/blackbox.py

  • Committer: Aaron Bentley
  • Date: 2005-09-21 15:33:23 UTC
  • mto: (1185.1.37)
  • mto: This revision was merged to the branch mainline in revision 1390.
  • Revision ID: abentley@panoramicfeedback.com-20050921153323-5db674d572d7649d
Fixed bug in distance-from-root graph operation

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.
 
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.
 
27
"""
 
28
 
 
29
from cStringIO import StringIO
 
30
import sys
 
31
import os
 
32
 
 
33
from bzrlib.selftest import TestCaseInTempDir, BzrTestBase
 
34
from bzrlib.branch import Branch
 
35
 
 
36
 
 
37
class ExternalBase(TestCaseInTempDir):
 
38
 
 
39
    def runbzr(self, args, retcode=0, backtick=False):
 
40
        if isinstance(args, basestring):
 
41
            args = args.split()
 
42
 
 
43
        if backtick:
 
44
            return self.run_bzr_captured(args, retcode=retcode)[0]
 
45
        else:
 
46
            return self.run_bzr_captured(args, retcode=retcode)
 
47
 
 
48
 
 
49
class TestCommands(ExternalBase):
 
50
 
 
51
    def test_help_commands(self):
 
52
        self.runbzr('--help')
 
53
        self.runbzr('help')
 
54
        self.runbzr('help commands')
 
55
        self.runbzr('help help')
 
56
        self.runbzr('commit -h')
 
57
 
 
58
    def test_init_branch(self):
 
59
        self.runbzr(['init'])
 
60
 
 
61
    def test_whoami(self):
 
62
        # this should always identify something, if only "john@localhost"
 
63
        self.runbzr("whoami")
 
64
        self.runbzr("whoami --email")
 
65
 
 
66
        self.assertEquals(self.runbzr("whoami --email",
 
67
                                      backtick=True).count('@'), 1)
 
68
        
 
69
    def test_whoami_branch(self):
 
70
        """branch specific user identity works."""
 
71
        self.runbzr('init')
 
72
        f = file('.bzr/email', 'wt')
 
73
        f.write('Branch Identity <branch@identi.ty>')
 
74
        f.close()
 
75
        bzr_email = os.environ.get('BZREMAIL')
 
76
        if bzr_email is not None:
 
77
            del os.environ['BZREMAIL']
 
78
        whoami = self.runbzr("whoami",backtick=True)
 
79
        whoami_email = self.runbzr("whoami --email",backtick=True)
 
80
        self.assertTrue(whoami.startswith('Branch Identity <branch@identi.ty>'))
 
81
        self.assertTrue(whoami_email.startswith('branch@identi.ty'))
 
82
        # Verify that the environment variable overrides the value 
 
83
        # in the file
 
84
        os.environ['BZREMAIL'] = 'Different ID <other@environ.ment>'
 
85
        whoami = self.runbzr("whoami",backtick=True)
 
86
        whoami_email = self.runbzr("whoami --email",backtick=True)
 
87
        self.assertTrue(whoami.startswith('Different ID <other@environ.ment>'))
 
88
        self.assertTrue(whoami_email.startswith('other@environ.ment'))
 
89
        if bzr_email is not None:
 
90
            os.environ['BZREMAIL'] = bzr_email
 
91
 
 
92
    def test_invalid_commands(self):
 
93
        self.runbzr("pants", retcode=1)
 
94
        self.runbzr("--pants off", retcode=1)
 
95
        self.runbzr("diff --message foo", retcode=1)
 
96
 
 
97
    def test_empty_commit(self):
 
98
        self.runbzr("init")
 
99
        self.build_tree(['hello.txt'])
 
100
        self.runbzr("commit -m empty", retcode=1)
 
101
        self.runbzr("add hello.txt")
 
102
        self.runbzr("commit -m added")
 
103
 
 
104
    def test_ignore_patterns(self):
 
105
        from bzrlib.branch import Branch
 
106
        
 
107
        b = Branch.initialize('.')
 
108
        self.assertEquals(list(b.unknowns()), [])
 
109
 
 
110
        file('foo.tmp', 'wt').write('tmp files are ignored')
 
111
        self.assertEquals(list(b.unknowns()), [])
 
112
        assert self.capture('unknowns') == ''
 
113
 
 
114
        file('foo.c', 'wt').write('int main() {}')
 
115
        self.assertEquals(list(b.unknowns()), ['foo.c'])
 
116
        assert self.capture('unknowns') == 'foo.c\n'
 
117
 
 
118
        self.runbzr(['add', 'foo.c'])
 
119
        assert self.capture('unknowns') == ''
 
120
 
 
121
        # 'ignore' works when creating the .bzignore file
 
122
        file('foo.blah', 'wt').write('blah')
 
123
        self.assertEquals(list(b.unknowns()), ['foo.blah'])
 
124
        self.runbzr('ignore *.blah')
 
125
        self.assertEquals(list(b.unknowns()), [])
 
126
        assert file('.bzrignore', 'rb').read() == '*.blah\n'
 
127
 
 
128
        # 'ignore' works when then .bzrignore file already exists
 
129
        file('garh', 'wt').write('garh')
 
130
        self.assertEquals(list(b.unknowns()), ['garh'])
 
131
        assert self.capture('unknowns') == 'garh\n'
 
132
        self.runbzr('ignore garh')
 
133
        self.assertEquals(list(b.unknowns()), [])
 
134
        assert file('.bzrignore', 'rb').read() == '*.blah\ngarh\n'
 
135
 
 
136
    def test_revert(self):
 
137
        self.runbzr('init')
 
138
 
 
139
        file('hello', 'wt').write('foo')
 
140
        self.runbzr('add hello')
 
141
        self.runbzr('commit -m setup hello')
 
142
 
 
143
        file('goodbye', 'wt').write('baz')
 
144
        self.runbzr('add goodbye')
 
145
        self.runbzr('commit -m setup goodbye')
 
146
        
 
147
        file('hello', 'wt').write('bar')
 
148
        file('goodbye', 'wt').write('qux')
 
149
        self.runbzr('revert hello')
 
150
        self.check_file_contents('hello', 'foo')
 
151
        self.check_file_contents('goodbye', 'qux')
 
152
        self.runbzr('revert')
 
153
        self.check_file_contents('goodbye', 'baz')
 
154
 
 
155
        os.mkdir('revertdir')
 
156
        self.runbzr('add revertdir')
 
157
        self.runbzr('commit -m f')
 
158
        os.rmdir('revertdir')
 
159
        self.runbzr('revert')
 
160
 
 
161
        file('hello', 'wt').write('xyz')
 
162
        self.runbzr('commit -m xyz hello')
 
163
        self.runbzr('revert -r 1 hello')
 
164
        self.check_file_contents('hello', 'foo')
 
165
        self.runbzr('revert hello')
 
166
        self.check_file_contents('hello', 'xyz')
 
167
 
 
168
    def test_mv_modes(self):
 
169
        """Test two modes of operation for mv"""
 
170
        from bzrlib.branch import Branch
 
171
        b = Branch.initialize('.')
 
172
        self.build_tree(['a', 'c', 'subdir/'])
 
173
        self.run_bzr_captured(['add', self.test_dir])
 
174
        self.run_bzr_captured(['mv', 'a', 'b'])
 
175
        self.run_bzr_captured(['mv', 'b', 'subdir'])
 
176
        self.run_bzr_captured(['mv', 'subdir/b', 'a'])
 
177
        self.run_bzr_captured(['mv', 'a', 'c', 'subdir'])
 
178
        self.run_bzr_captured(['mv', 'subdir/a', 'subdir/newa'])
 
179
 
 
180
 
 
181
    def test_main_version(self):
 
182
        """Check output from version command and master option is reasonable"""
 
183
        # output is intentionally passed through to stdout so that we
 
184
        # can see the version being tested
 
185
        output = self.runbzr('version', backtick=1)
 
186
        self.log('bzr version output:')
 
187
        self.log(output)
 
188
        self.assert_(output.startswith('bzr (bazaar-ng) '))
 
189
        self.assertNotEqual(output.index('Canonical'), -1)
 
190
        # make sure --version is consistent
 
191
        tmp_output = self.runbzr('--version', backtick=1)
 
192
        self.log('bzr --version output:')
 
193
        self.log(tmp_output)
 
194
        self.assertEquals(output, tmp_output)
 
195
 
 
196
    def example_branch(test):
 
197
        test.runbzr('init')
 
198
        file('hello', 'wt').write('foo')
 
199
        test.runbzr('add hello')
 
200
        test.runbzr('commit -m setup hello')
 
201
        file('goodbye', 'wt').write('baz')
 
202
        test.runbzr('add goodbye')
 
203
        test.runbzr('commit -m setup goodbye')
 
204
 
 
205
    def test_diff(self):
 
206
        self.example_branch()
 
207
        file('hello', 'wt').write('hello world!')
 
208
        self.runbzr('commit -m fixing hello')
 
209
        output = self.runbzr('diff -r 2..3', backtick=1)
 
210
        self.assert_('\n+hello world!' in output)
 
211
        output = self.runbzr('diff -r last:3..last:1', backtick=1)
 
212
        self.assert_('\n+baz' in output)
 
213
 
 
214
    def test_diff(self):
 
215
        self.example_branch()
 
216
        file('hello', 'wt').write('hello world!')
 
217
        self.runbzr('commit -m fixing hello')
 
218
        output = self.runbzr('diff -r 2..3', backtick=1)
 
219
        self.assert_('\n+hello world!' in output)
 
220
        output = self.runbzr('diff -r last:3..last:1', backtick=1)
 
221
        self.assert_('\n+baz' in output)
 
222
 
 
223
    def test_merge(self):
 
224
        from bzrlib.branch import Branch
 
225
        
 
226
        os.mkdir('a')
 
227
        os.chdir('a')
 
228
        self.example_branch()
 
229
        os.chdir('..')
 
230
        self.runbzr('branch a b')
 
231
        os.chdir('b')
 
232
        file('goodbye', 'wt').write('quux')
 
233
        self.runbzr(['commit',  '-m',  "more u's are always good"])
 
234
 
 
235
        os.chdir('../a')
 
236
        file('hello', 'wt').write('quuux')
 
237
        # We can't merge when there are in-tree changes
 
238
        self.runbzr('merge ../b', retcode=1)
 
239
        self.runbzr(['commit', '-m', "Like an epidemic of u's"])
 
240
        self.runbzr('merge ../b')
 
241
        self.check_file_contents('goodbye', 'quux')
 
242
        # Merging a branch pulls its revision into the tree
 
243
        a = Branch.open('.')
 
244
        b = Branch.open('../b')
 
245
        a.get_revision_xml(b.last_patch())
 
246
        self.log('pending merges: %s', a.pending_merges())
 
247
        #        assert a.pending_merges() == [b.last_patch()], "Assertion %s %s" \
 
248
        #        % (a.pending_merges(), b.last_patch())
 
249
 
 
250
    def test_pull(self):
 
251
        """Pull changes from one branch to another."""
 
252
        os.mkdir('a')
 
253
        os.chdir('a')
 
254
 
 
255
        self.example_branch()
 
256
        self.runbzr('pull', retcode=1)
 
257
        self.runbzr('missing', retcode=1)
 
258
        self.runbzr('missing .')
 
259
        self.runbzr('missing')
 
260
        self.runbzr('pull')
 
261
        self.runbzr('pull /', retcode=1)
 
262
        self.runbzr('pull')
 
263
 
 
264
        os.chdir('..')
 
265
        self.runbzr('branch a b')
 
266
        os.chdir('b')
 
267
        self.runbzr('pull')
 
268
        self.runbzr('commit -m blah --unchanged')
 
269
        os.chdir('../a')
 
270
        a = Branch.open('.')
 
271
        b = Branch.open('../b')
 
272
        assert a.revision_history() == b.revision_history()[:-1]
 
273
        self.runbzr('pull ../b')
 
274
        assert a.revision_history() == b.revision_history()
 
275
        self.runbzr('commit -m blah2 --unchanged')
 
276
        os.chdir('../b')
 
277
        self.runbzr('commit -m blah3 --unchanged')
 
278
        self.runbzr('pull ../a', retcode=1)
 
279
        os.chdir('../a')
 
280
        self.runbzr('merge ../b')
 
281
        self.runbzr('commit -m blah4 --unchanged')
 
282
        os.chdir('../b')
 
283
        self.runbzr('pull ../a')
 
284
        assert a.revision_history()[-1] == b.revision_history()[-1]
 
285
        
 
286
    def test_add_reports(self):
 
287
        """add command prints the names of added files."""
 
288
        b = Branch.initialize('.')
 
289
        self.build_tree(['top.txt', 'dir/', 'dir/sub.txt'])
 
290
        out = self.run_bzr_captured(['add'], retcode = 0)[0]
 
291
        # the ordering is not defined at the moment
 
292
        results = sorted(out.rstrip('\n').split('\n'))
 
293
        self.assertEquals(['added dir',
 
294
                           'added dir/sub.txt',
 
295
                           'added top.txt',],
 
296
                          results)
 
297
 
 
298
    def test_unknown_command(self):
 
299
        """Handling of unknown command."""
 
300
        out, err = self.run_bzr_captured(['fluffy-badger'],
 
301
                                         retcode=1)
 
302
        self.assertEquals(out, '')
 
303
        err.index('unknown command')
 
304
        
 
305
 
 
306
 
 
307
class OldTests(ExternalBase):
 
308
    """old tests moved from ./testbzr."""
 
309
 
 
310
    def test_bzr(self):
 
311
        from os import chdir, mkdir
 
312
        from os.path import exists
 
313
 
 
314
        runbzr = self.runbzr
 
315
        capture = self.capture
 
316
        progress = self.log
 
317
 
 
318
        progress("basic branch creation")
 
319
        mkdir('branch1')
 
320
        chdir('branch1')
 
321
        runbzr('init')
 
322
 
 
323
        self.assertEquals(capture('root').rstrip(),
 
324
                          os.path.join(self.test_dir, 'branch1'))
 
325
 
 
326
        progress("status of new file")
 
327
 
 
328
        f = file('test.txt', 'wt')
 
329
        f.write('hello world!\n')
 
330
        f.close()
 
331
 
 
332
        self.assertEquals(capture('unknowns'), 'test.txt\n')
 
333
 
 
334
        out = capture("status")
 
335
        assert out == 'unknown:\n  test.txt\n'
 
336
 
 
337
        out = capture("status --all")
 
338
        assert out == "unknown:\n  test.txt\n"
 
339
 
 
340
        out = capture("status test.txt --all")
 
341
        assert out == "unknown:\n  test.txt\n"
 
342
 
 
343
        f = file('test2.txt', 'wt')
 
344
        f.write('goodbye cruel world...\n')
 
345
        f.close()
 
346
 
 
347
        out = capture("status test.txt")
 
348
        assert out == "unknown:\n  test.txt\n"
 
349
 
 
350
        out = capture("status")
 
351
        assert out == ("unknown:\n"
 
352
                       "  test.txt\n"
 
353
                       "  test2.txt\n")
 
354
 
 
355
        os.unlink('test2.txt')
 
356
 
 
357
        progress("command aliases")
 
358
        out = capture("st --all")
 
359
        assert out == ("unknown:\n"
 
360
                       "  test.txt\n")
 
361
 
 
362
        out = capture("stat")
 
363
        assert out == ("unknown:\n"
 
364
                       "  test.txt\n")
 
365
 
 
366
        progress("command help")
 
367
        runbzr("help st")
 
368
        runbzr("help")
 
369
        runbzr("help commands")
 
370
        runbzr("help slartibartfast", 1)
 
371
 
 
372
        out = capture("help ci")
 
373
        out.index('aliases: ')
 
374
 
 
375
        progress("can't rename unversioned file")
 
376
        runbzr("rename test.txt new-test.txt", 1)
 
377
 
 
378
        progress("adding a file")
 
379
 
 
380
        runbzr("add test.txt")
 
381
        assert capture("unknowns") == ''
 
382
        assert capture("status --all") == ("added:\n"
 
383
                                                "  test.txt\n")
 
384
 
 
385
        progress("rename newly-added file")
 
386
        runbzr("rename test.txt hello.txt")
 
387
        assert os.path.exists("hello.txt")
 
388
        assert not os.path.exists("test.txt")
 
389
 
 
390
        assert capture("revno") == '0\n'
 
391
 
 
392
        progress("add first revision")
 
393
        runbzr(['commit', '-m', 'add first revision'])
 
394
 
 
395
        progress("more complex renames")
 
396
        os.mkdir("sub1")
 
397
        runbzr("rename hello.txt sub1", 1)
 
398
        runbzr("rename hello.txt sub1/hello.txt", 1)
 
399
        runbzr("move hello.txt sub1", 1)
 
400
 
 
401
        runbzr("add sub1")
 
402
        runbzr("rename sub1 sub2")
 
403
        runbzr("move hello.txt sub2")
 
404
        assert capture("relpath sub2/hello.txt") == os.path.join("sub2", "hello.txt\n")
 
405
 
 
406
        assert exists("sub2")
 
407
        assert exists("sub2/hello.txt")
 
408
        assert not exists("sub1")
 
409
        assert not exists("hello.txt")
 
410
 
 
411
        runbzr(['commit', '-m', 'commit with some things moved to subdirs'])
 
412
 
 
413
        mkdir("sub1")
 
414
        runbzr('add sub1')
 
415
        runbzr('move sub2/hello.txt sub1')
 
416
        assert not exists('sub2/hello.txt')
 
417
        assert exists('sub1/hello.txt')
 
418
        runbzr('move sub2 sub1')
 
419
        assert not exists('sub2')
 
420
        assert exists('sub1/sub2')
 
421
 
 
422
        runbzr(['commit', '-m', 'rename nested subdirectories'])
 
423
 
 
424
        chdir('sub1/sub2')
 
425
        self.assertEquals(capture('root')[:-1],
 
426
                          os.path.join(self.test_dir, 'branch1'))
 
427
        runbzr('move ../hello.txt .')
 
428
        assert exists('./hello.txt')
 
429
        self.assertEquals(capture('relpath hello.txt'),
 
430
                          os.path.join('sub1', 'sub2', 'hello.txt') + '\n')
 
431
        assert capture('relpath ../../sub1/sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
 
432
        runbzr(['commit', '-m', 'move to parent directory'])
 
433
        chdir('..')
 
434
        assert capture('relpath sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
 
435
 
 
436
        runbzr('move sub2/hello.txt .')
 
437
        assert exists('hello.txt')
 
438
 
 
439
        f = file('hello.txt', 'wt')
 
440
        f.write('some nice new content\n')
 
441
        f.close()
 
442
 
 
443
        f = file('msg.tmp', 'wt')
 
444
        f.write('this is my new commit\n')
 
445
        f.close()
 
446
 
 
447
        runbzr('commit -F msg.tmp')
 
448
 
 
449
        assert capture('revno') == '5\n'
 
450
        runbzr('export -r 5 export-5.tmp')
 
451
        runbzr('export export.tmp')
 
452
 
 
453
        runbzr('log')
 
454
        runbzr('log -v')
 
455
        runbzr('log -v --forward')
 
456
        runbzr('log -m', retcode=1)
 
457
        log_out = capture('log -m commit')
 
458
        assert "this is my new commit" in log_out
 
459
        assert "rename nested" not in log_out
 
460
        assert 'revision-id' not in log_out
 
461
        assert 'revision-id' in capture('log --show-ids -m commit')
 
462
 
 
463
 
 
464
        progress("file with spaces in name")
 
465
        mkdir('sub directory')
 
466
        file('sub directory/file with spaces ', 'wt').write('see how this works\n')
 
467
        runbzr('add .')
 
468
        runbzr('diff')
 
469
        runbzr('commit -m add-spaces')
 
470
        runbzr('check')
 
471
 
 
472
        runbzr('log')
 
473
        runbzr('log --forward')
 
474
 
 
475
        runbzr('info')
 
476