~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/blackbox.py

  • Committer: John Arbash Meinel
  • Date: 2005-09-15 21:35:53 UTC
  • mfrom: (907.1.57)
  • mto: (1393.2.1)
  • mto: This revision was merged to the branch mainline in revision 1396.
  • Revision ID: john@arbash-meinel.com-20050915213552-a6c83a5ef1e20897
(broken) Transport work is merged in. Tests do not pass yet.

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