~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/selftest/blackbox.py

  • Committer: aaron.bentley at utoronto
  • Date: 2005-09-04 02:59:56 UTC
  • mfrom: (1172)
  • mto: (1185.3.4)
  • mto: This revision was merged to the branch mainline in revision 1178.
  • Revision ID: aaron.bentley@utoronto.ca-20050904025956-776ba4f07de97700
Merged mpool's latest changes (~0.0.7)

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
it's normally invoked.
27
27
"""
28
28
 
29
 
# this code was previously in testbzr
30
 
 
31
 
from unittest import TestCase
32
 
from bzrlib.selftest import TestBase, InTempDir
33
 
 
34
 
class TestVersion(TestBase):
35
 
    def runTest(self):
 
29
import sys
 
30
 
 
31
from bzrlib.selftest import TestCaseInTempDir, BzrTestBase
 
32
from bzrlib.branch import Branch
 
33
from bzrlib.commands import run_bzr
 
34
 
 
35
 
 
36
class ExternalBase(TestCaseInTempDir):
 
37
    def runbzr(self, args, retcode=0,backtick=False):
 
38
        if isinstance(args, basestring):
 
39
            args = args.split()
 
40
 
 
41
        if backtick:
 
42
            return self.backtick(['python', self.BZRPATH,] + args,
 
43
                           retcode=retcode)
 
44
        else:
 
45
            return self.runcmd(['python', self.BZRPATH,] + args,
 
46
                           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
        whoami = self.runbzr("whoami",backtick=True)
 
76
        whoami_email = self.runbzr("whoami --email",backtick=True)
 
77
        self.assertTrue(whoami.startswith('Branch Identity <branch@identi.ty>'))
 
78
        self.assertTrue(whoami_email.startswith('branch@identi.ty'))
 
79
 
 
80
    def test_invalid_commands(self):
 
81
        self.runbzr("pants", retcode=1)
 
82
        self.runbzr("--pants off", retcode=1)
 
83
        self.runbzr("diff --message foo", retcode=1)
 
84
 
 
85
    def test_empty_commit(self):
 
86
        self.runbzr("init")
 
87
        self.build_tree(['hello.txt'])
 
88
        self.runbzr("commit -m empty", retcode=1)
 
89
        self.runbzr("add hello.txt")
 
90
        self.runbzr("commit -m added")
 
91
 
 
92
    def test_ignore_patterns(self):
 
93
        from bzrlib.branch import Branch
 
94
        
 
95
        b = Branch('.', init=True)
 
96
        self.assertEquals(list(b.unknowns()), [])
 
97
 
 
98
        file('foo.tmp', 'wt').write('tmp files are ignored')
 
99
        self.assertEquals(list(b.unknowns()), [])
 
100
        assert self.backtick('bzr unknowns') == ''
 
101
 
 
102
        file('foo.c', 'wt').write('int main() {}')
 
103
        self.assertEquals(list(b.unknowns()), ['foo.c'])
 
104
        assert self.backtick('bzr unknowns') == 'foo.c\n'
 
105
 
 
106
        self.runbzr(['add', 'foo.c'])
 
107
        assert self.backtick('bzr unknowns') == ''
 
108
 
 
109
        # 'ignore' works when creating the .bzignore file
 
110
        file('foo.blah', 'wt').write('blah')
 
111
        self.assertEquals(list(b.unknowns()), ['foo.blah'])
 
112
        self.runbzr('ignore *.blah')
 
113
        self.assertEquals(list(b.unknowns()), [])
 
114
        assert file('.bzrignore', 'rb').read() == '*.blah\n'
 
115
 
 
116
        # 'ignore' works when then .bzrignore file already exists
 
117
        file('garh', 'wt').write('garh')
 
118
        self.assertEquals(list(b.unknowns()), ['garh'])
 
119
        assert self.backtick('bzr unknowns') == 'garh\n'
 
120
        self.runbzr('ignore garh')
 
121
        self.assertEquals(list(b.unknowns()), [])
 
122
        assert file('.bzrignore', 'rb').read() == '*.blah\ngarh\n'
 
123
 
 
124
    def test_revert(self):
 
125
        import os
 
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 skipped_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('mv', 'a', 'b')
 
156
        self.run_bzr('mv', 'b', 'subdir')
 
157
        self.run_bzr('mv', 'subdir/b', 'a')
 
158
        self.run_bzr('mv', 'a', 'b', 'subdir')
 
159
        self.run_bzr('mv', 'subdir/a', 'subdir/newa')
 
160
 
 
161
    def test_main_version(self):
 
162
        """Check output from version command and master option is reasonable"""
36
163
        # output is intentionally passed through to stdout so that we
37
164
        # can see the version being tested
38
 
        self.runcmd(['bzr', 'version'])
39
 
 
40
 
 
41
 
 
42
 
class HelpCommands(TestBase):
43
 
    def runTest(self):
44
 
        self.runcmd('bzr --help')
45
 
        self.runcmd('bzr help')
46
 
        self.runcmd('bzr help commands')
47
 
        self.runcmd('bzr help help')
48
 
        self.runcmd('bzr commit -h')
49
 
 
50
 
 
51
 
class InitBranch(InTempDir):
52
 
    def runTest(self):
 
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
53
197
        import os
54
 
        self.runcmd(['bzr', 'init'])
55
 
 
56
 
 
57
 
 
58
 
class UserIdentity(InTempDir):
59
 
    def runTest(self):
60
 
        # this should always identify something, if only "john@localhost"
61
 
        self.runcmd("bzr whoami")
62
 
        self.runcmd("bzr whoami --email")
63
 
        self.assertEquals(self.backtick("bzr whoami --email").count('@'),
64
 
                          1)
65
 
 
66
 
 
67
 
class InvalidCommands(InTempDir):
68
 
    def runTest(self):
69
 
        self.runcmd("bzr pants", retcode=1)
70
 
        self.runcmd("bzr --pants off", retcode=1)
71
 
        self.runcmd("bzr diff --message foo", retcode=1)
72
 
 
73
 
 
74
 
 
75
 
class OldTests(InTempDir):
76
 
    # old tests moved from ./testbzr
77
 
    def runTest(self):
 
198
        
 
199
        os.mkdir('a')
 
200
        os.chdir('a')
 
201
 
 
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
 
 
221
        self.log('pending merges: %s', a.pending_merges())
 
222
        #        assert a.pending_merges() == [b.last_patch()], "Assertion %s %s" \
 
223
        #        % (a.pending_merges(), b.last_patch())
 
224
 
 
225
 
 
226
    def test_add_reports(self):
 
227
        """add command prints the names of added files."""
 
228
        b = Branch('.', init=True)
 
229
        self.build_tree(['top.txt', 'dir/', 'dir/sub.txt'])
 
230
 
 
231
        from cStringIO import StringIO
 
232
        out = StringIO()
 
233
 
 
234
        ret = self.apply_redirected(None, out, None,
 
235
                                    run_bzr,
 
236
                                    ['add'])
 
237
        self.assertEquals(ret, 0)
 
238
 
 
239
        # the ordering is not defined at the moment
 
240
        results = sorted(out.getvalue().rstrip('\n').split('\n'))
 
241
        self.assertEquals(['added dir',
 
242
                           'added dir/sub.txt',
 
243
                           'added top.txt',],
 
244
                          results)
 
245
 
 
246
 
 
247
class OldTests(ExternalBase):
 
248
    """old tests moved from ./testbzr."""
 
249
 
 
250
    def test_bzr(self):
78
251
        from os import chdir, mkdir
79
252
        from os.path import exists
80
253
        import os
81
254
 
82
 
        runcmd = self.runcmd
 
255
        runbzr = self.runbzr
83
256
        backtick = self.backtick
84
257
        progress = self.log
85
258
 
86
259
        progress("basic branch creation")
87
 
        runcmd(['mkdir', 'branch1'])
 
260
        mkdir('branch1')
88
261
        chdir('branch1')
89
 
        runcmd('bzr init')
 
262
        runbzr('init')
90
263
 
91
264
        self.assertEquals(backtick('bzr root').rstrip(),
92
265
                          os.path.join(self.test_dir, 'branch1'))
98
271
        f.close()
99
272
 
100
273
        out = backtick("bzr unknowns")
101
 
        assert out == 'test.txt\n'
 
274
        self.assertEquals(out, 'test.txt\n')
102
275
 
103
276
        out = backtick("bzr status")
104
277
        assert out == 'unknown:\n  test.txt\n'
133
306
                       "  test.txt\n")
134
307
 
135
308
        progress("command help")
136
 
        runcmd("bzr help st")
137
 
        runcmd("bzr help")
138
 
        runcmd("bzr help commands")
139
 
        runcmd("bzr help slartibartfast", 1)
 
309
        runbzr("help st")
 
310
        runbzr("help")
 
311
        runbzr("help commands")
 
312
        runbzr("help slartibartfast", 1)
140
313
 
141
314
        out = backtick("bzr help ci")
142
315
        out.index('aliases: ')
143
316
 
144
317
        progress("can't rename unversioned file")
145
 
        runcmd("bzr rename test.txt new-test.txt", 1)
 
318
        runbzr("rename test.txt new-test.txt", 1)
146
319
 
147
320
        progress("adding a file")
148
321
 
149
 
        runcmd("bzr add test.txt")
 
322
        runbzr("add test.txt")
150
323
        assert backtick("bzr unknowns") == ''
151
324
        assert backtick("bzr status --all") == ("added:\n"
152
325
                                                "  test.txt\n")
153
326
 
154
327
        progress("rename newly-added file")
155
 
        runcmd("bzr rename test.txt hello.txt")
 
328
        runbzr("rename test.txt hello.txt")
156
329
        assert os.path.exists("hello.txt")
157
330
        assert not os.path.exists("test.txt")
158
331
 
159
332
        assert backtick("bzr revno") == '0\n'
160
333
 
161
334
        progress("add first revision")
162
 
        runcmd(["bzr", "commit", "-m", 'add first revision'])
 
335
        runbzr(['commit', '-m', 'add first revision'])
163
336
 
164
337
        progress("more complex renames")
165
338
        os.mkdir("sub1")
166
 
        runcmd("bzr rename hello.txt sub1", 1)
167
 
        runcmd("bzr rename hello.txt sub1/hello.txt", 1)
168
 
        runcmd("bzr move hello.txt sub1", 1)
 
339
        runbzr("rename hello.txt sub1", 1)
 
340
        runbzr("rename hello.txt sub1/hello.txt", 1)
 
341
        runbzr("move hello.txt sub1", 1)
169
342
 
170
 
        runcmd("bzr add sub1")
171
 
        runcmd("bzr rename sub1 sub2")
172
 
        runcmd("bzr move hello.txt sub2")
 
343
        runbzr("add sub1")
 
344
        runbzr("rename sub1 sub2")
 
345
        runbzr("move hello.txt sub2")
173
346
        assert backtick("bzr relpath sub2/hello.txt") == os.path.join("sub2", "hello.txt\n")
174
347
 
175
348
        assert exists("sub2")
177
350
        assert not exists("sub1")
178
351
        assert not exists("hello.txt")
179
352
 
180
 
        runcmd(['bzr', 'commit', '-m', 'commit with some things moved to subdirs'])
 
353
        runbzr(['commit', '-m', 'commit with some things moved to subdirs'])
181
354
 
182
355
        mkdir("sub1")
183
 
        runcmd('bzr add sub1')
184
 
        runcmd('bzr move sub2/hello.txt sub1')
 
356
        runbzr('add sub1')
 
357
        runbzr('move sub2/hello.txt sub1')
185
358
        assert not exists('sub2/hello.txt')
186
359
        assert exists('sub1/hello.txt')
187
 
        runcmd('bzr move sub2 sub1')
 
360
        runbzr('move sub2 sub1')
188
361
        assert not exists('sub2')
189
362
        assert exists('sub1/sub2')
190
363
 
191
 
        runcmd(['bzr', 'commit', '-m', 'rename nested subdirectories'])
 
364
        runbzr(['commit', '-m', 'rename nested subdirectories'])
192
365
 
193
366
        chdir('sub1/sub2')
194
367
        self.assertEquals(backtick('bzr root')[:-1],
195
368
                          os.path.join(self.test_dir, 'branch1'))
196
 
        runcmd('bzr move ../hello.txt .')
 
369
        runbzr('move ../hello.txt .')
197
370
        assert exists('./hello.txt')
198
371
        assert backtick('bzr relpath hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
199
372
        assert backtick('bzr relpath ../../sub1/sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
200
 
        runcmd(['bzr', 'commit', '-m', 'move to parent directory'])
 
373
        runbzr(['commit', '-m', 'move to parent directory'])
201
374
        chdir('..')
202
375
        assert backtick('bzr relpath sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
203
376
 
204
 
        runcmd('bzr move sub2/hello.txt .')
 
377
        runbzr('move sub2/hello.txt .')
205
378
        assert exists('hello.txt')
206
379
 
207
380
        f = file('hello.txt', 'wt')
212
385
        f.write('this is my new commit\n')
213
386
        f.close()
214
387
 
215
 
        runcmd('bzr commit -F msg.tmp')
 
388
        runbzr('commit -F msg.tmp')
216
389
 
217
390
        assert backtick('bzr revno') == '5\n'
218
 
        runcmd('bzr export -r 5 export-5.tmp')
219
 
        runcmd('bzr export export.tmp')
220
 
 
221
 
        runcmd('bzr log')
222
 
        runcmd('bzr log -v')
223
 
 
 
391
        runbzr('export -r 5 export-5.tmp')
 
392
        runbzr('export export.tmp')
 
393
 
 
394
        runbzr('log')
 
395
        runbzr('log -v')
 
396
        runbzr('log -v --forward')
 
397
        runbzr('log -m', retcode=1)
 
398
        log_out = backtick('bzr log -m commit')
 
399
        assert "this is my new commit" in log_out
 
400
        assert "rename nested" not in log_out
 
401
        assert 'revision-id' not in log_out
 
402
        assert 'revision-id' in backtick('bzr log --show-ids -m commit')
224
403
 
225
404
 
226
405
        progress("file with spaces in name")
227
406
        mkdir('sub directory')
228
407
        file('sub directory/file with spaces ', 'wt').write('see how this works\n')
229
 
        runcmd('bzr add .')
230
 
        runcmd('bzr diff')
231
 
        runcmd('bzr commit -m add-spaces')
232
 
        runcmd('bzr check')
233
 
 
234
 
        runcmd('bzr log')
235
 
        runcmd('bzr log --forward')
236
 
 
237
 
        runcmd('bzr info')
238
 
 
239
 
 
240
 
 
241
 
 
242
 
 
243
 
 
244
 
        chdir('..')
245
 
        chdir('..')
246
 
        progress('branch')
247
 
        # Can't create a branch if it already exists
248
 
        runcmd('bzr branch branch1', retcode=1)
249
 
        # Can't create a branch if its parent doesn't exist
250
 
        runcmd('bzr branch /unlikely/to/exist', retcode=1)
251
 
        runcmd('bzr branch branch1 branch2')
252
 
 
253
 
        progress("pull")
254
 
        chdir('branch1')
255
 
        runcmd('bzr pull', retcode=1)
256
 
        runcmd('bzr pull ../branch2')
257
 
        chdir('.bzr')
258
 
        runcmd('bzr pull')
259
 
        runcmd('bzr commit -m empty')
260
 
        runcmd('bzr pull')
261
 
        chdir('../../branch2')
262
 
        runcmd('bzr pull')
263
 
        runcmd('bzr commit -m empty')
264
 
        chdir('../branch1')
265
 
        runcmd('bzr commit -m empty')
266
 
        runcmd('bzr pull', retcode=1)
267
 
        chdir ('..')
268
 
 
269
 
        progress('status after remove')
270
 
        mkdir('status-after-remove')
271
 
        # see mail from William Dodé, 2005-05-25
272
 
        # $ bzr init; touch a; bzr add a; bzr commit -m "add a"
273
 
        #     * looking for changes...
274
 
        #     added a
275
 
        #     * commited r1
276
 
        #     $ bzr remove a
277
 
        #     $ bzr status
278
 
        #     bzr: local variable 'kind' referenced before assignment
279
 
        #     at /vrac/python/bazaar-ng/bzrlib/diff.py:286 in compare_trees()
280
 
        #     see ~/.bzr.log for debug information
281
 
        chdir('status-after-remove')
282
 
        runcmd('bzr init')
283
 
        file('a', 'w').write('foo')
284
 
        runcmd('bzr add a')
285
 
        runcmd(['bzr', 'commit', '-m', 'add a'])
286
 
        runcmd('bzr remove a')
287
 
        runcmd('bzr status')
288
 
 
289
 
        chdir('..')
290
 
 
291
 
        progress('ignore patterns')
292
 
        mkdir('ignorebranch')
293
 
        chdir('ignorebranch')
294
 
        runcmd('bzr init')
295
 
        assert backtick('bzr unknowns') == ''
296
 
 
297
 
        file('foo.tmp', 'wt').write('tmp files are ignored')
298
 
        assert backtick('bzr unknowns') == ''
299
 
 
300
 
        file('foo.c', 'wt').write('int main() {}')
301
 
        assert backtick('bzr unknowns') == 'foo.c\n'
302
 
        runcmd('bzr add foo.c')
303
 
        assert backtick('bzr unknowns') == ''
304
 
 
305
 
        # 'ignore' works when creating the .bzignore file
306
 
        file('foo.blah', 'wt').write('blah')
307
 
        assert backtick('bzr unknowns') == 'foo.blah\n'
308
 
        runcmd('bzr ignore *.blah')
309
 
        assert backtick('bzr unknowns') == ''
310
 
        assert file('.bzrignore', 'rb').read() == '*.blah\n'
311
 
 
312
 
        # 'ignore' works when then .bzrignore file already exists
313
 
        file('garh', 'wt').write('garh')
314
 
        assert backtick('bzr unknowns') == 'garh\n'
315
 
        runcmd('bzr ignore garh')
316
 
        assert backtick('bzr unknowns') == ''
317
 
        assert file('.bzrignore', 'rb').read() == '*.blah\ngarh\n'
318
 
 
319
 
        chdir('..')
320
 
 
321
 
 
322
 
 
323
 
 
324
 
        progress("recursive and non-recursive add")
325
 
        mkdir('no-recurse')
326
 
        chdir('no-recurse')
327
 
        runcmd('bzr init')
328
 
        mkdir('foo')
329
 
        fp = os.path.join('foo', 'test.txt')
330
 
        f = file(fp, 'w')
331
 
        f.write('hello!\n')
332
 
        f.close()
333
 
        runcmd('bzr add --no-recurse foo')
334
 
        runcmd('bzr file-id foo')
335
 
        runcmd('bzr file-id ' + fp, 1)      # not versioned yet
336
 
        runcmd('bzr commit -m add-dir-only')
337
 
 
338
 
        runcmd('bzr file-id ' + fp, 1)      # still not versioned 
339
 
 
340
 
        runcmd('bzr add foo')
341
 
        runcmd('bzr file-id ' + fp)
342
 
        runcmd('bzr commit -m add-sub-file')
343
 
 
344
 
        chdir('..')
345
 
 
346
 
 
347
 
 
348
 
    
349
 
        
350
 
 
351
 
 
352
 
# lists all tests from this module in the best order to run them.  we
353
 
# do it this way rather than just discovering them all because it
354
 
# allows us to test more basic functions first where failures will be
355
 
# easiest to understand.
356
 
 
357
 
def suite():
358
 
    from unittest import TestSuite
359
 
    s = TestSuite()
360
 
    s.addTests([TestVersion(),
361
 
                InitBranch(),
362
 
                HelpCommands(),
363
 
                UserIdentity(),
364
 
                InvalidCommands(),
365
 
                OldTests()])
366
 
    return s
 
408
        runbzr('add .')
 
409
        runbzr('diff')
 
410
        runbzr('commit -m add-spaces')
 
411
        runbzr('check')
 
412
 
 
413
        runbzr('log')
 
414
        runbzr('log --forward')
 
415
 
 
416
        runbzr('info')
 
417