~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-22 19:16:57 UTC
  • mto: (1393.2.1)
  • mto: This revision was merged to the branch mainline in revision 1396.
  • Revision ID: john@arbash-meinel.com-20050922191657-f94ee98ba0f9f83e
Made it so that we don't loop forever on EAGAIN.

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