~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to testbzr

  • Committer: Martin Pool
  • Date: 2005-06-22 06:37:43 UTC
  • Revision ID: mbp@sourcefrog.net-20050622063743-e395f04c4db8977f
- move old blackbox code from testbzr into bzrlib.selftest.blackbox

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
import sys
22
22
sys.exit(1)
23
23
 
24
 
 
25
 
 
26
 
 
27
 
"""External black-box test for bzr.
28
 
 
29
 
This always runs bzr as an external process to try to catch bugs
30
 
related to argument processing, startup, etc.
31
 
 
32
 
usage:
33
 
 
34
 
    testbzr [-p PYTHON] [BZR]
35
 
 
36
 
By default this tests the copy of bzr found in the same directory as
37
 
testbzr, or the first one found on the $PATH.  A copy of bzr may be
38
 
given on the command line to override this, for example when applying
39
 
a new test suite to an old copy of bzr or vice versa.
40
 
 
41
 
testbzr normally invokes bzr using the same version of python as it
42
 
would normally use to run -- that is, the system default python,
43
 
unless that is older than 2.3.  The -p option allows specification of
44
 
a different Python interpreter, such as when testing that bzr still
45
 
works on python2.3.
46
 
 
47
 
This replaces the previous test.sh which was not very portable."""
48
 
 
49
 
import sys, os, traceback
50
 
from os import mkdir
51
 
from os.path import exists
52
 
 
53
 
TESTDIR = "testbzr.tmp"
54
 
 
55
 
 
56
 
# we always invoke bzr as 'python bzr' (or e.g. 'python2.3 bzr')
57
 
# partly so as to cope if the bzr binary is not marked executable
58
 
OVERRIDE_PYTHON = 'python'
59
 
 
60
 
LOGFILENAME = 'testbzr.log'
61
 
 
62
 
try:
63
 
    import shutil
64
 
    from subprocess import call, Popen, PIPE
65
 
except ImportError, e:
66
 
    sys.stderr.write("testbzr: sorry, this test suite requires modules from python2.4\n"
67
 
                     + '    ' + str(e))
68
 
    sys.exit(1)
69
 
 
70
 
 
71
 
 
72
 
 
73
 
def formcmd(cmd):
74
 
    if isinstance(cmd, basestring):
75
 
        cmd = cmd.split()
76
 
 
77
 
    if cmd[0] == 'bzr':
78
 
        cmd[0] = BZRPATH
79
 
        if OVERRIDE_PYTHON:
80
 
            cmd.insert(0, OVERRIDE_PYTHON)
81
 
 
82
 
    logfile.write('$ %r\n' % cmd)
83
 
    
84
 
    return cmd
85
 
 
86
 
 
87
 
def runcmd(cmd, retcode=0):
88
 
    """Run one command and check the return code.
89
 
 
90
 
    Returns a tuple of (stdout,stderr) strings.
91
 
 
92
 
    If a single string is based, it is split into words.
93
 
    For commands that are not simple space-separated words, please
94
 
    pass a list instead."""
95
 
    cmd = formcmd(cmd)
96
 
    log_linenumber()
97
 
    
98
 
    actual_retcode = call(cmd, stdout=logfile, stderr=logfile)
99
 
    
100
 
    if retcode != actual_retcode:
101
 
        raise CommandFailed("test failed: %r returned %d, expected %d"
102
 
                            % (cmd, actual_retcode, retcode))
103
 
 
104
 
 
105
 
 
106
 
def backtick(cmd, retcode=0):
107
 
    cmd = formcmd(cmd)
108
 
    log_linenumber()
109
 
    child = Popen(cmd, stdout=PIPE, stderr=logfile)
110
 
    outd, errd = child.communicate()
111
 
    logfile.write(outd)
112
 
    actual_retcode = child.wait()
113
 
 
114
 
    outd = outd.replace('\r', '')
115
 
    
116
 
    if retcode != actual_retcode:
117
 
        raise CommandFailed("test failed: %r returned %d, expected %d"
118
 
                            % (cmd, actual_retcode, retcode))
119
 
 
120
 
    return outd
121
 
 
122
 
 
123
 
 
124
 
def progress(msg):
125
 
    print '* ' + msg
126
 
    logfile.write('* '+ msg + '\n')
127
 
    log_linenumber()
128
 
 
129
 
 
130
 
def cd(dirname):
131
 
    logfile.write('$ cd %s\n' % dirname)
132
 
    os.chdir(dirname)
133
 
 
134
 
 
135
 
 
136
 
def log_linenumber():
137
 
    """Log the stack frame location two things up."""
138
 
    stack = traceback.extract_stack()[-3]
139
 
    logfile.write('   at %s:%d\n' % stack[:2])
140
 
 
141
 
 
142
 
 
143
 
# prepare an empty scratch directory
144
 
if os.path.exists(TESTDIR):
145
 
    shutil.rmtree(TESTDIR)
146
 
 
147
 
start_dir = os.getcwd()
148
 
 
149
 
 
150
 
logfile = open(LOGFILENAME, 'wt', buffering=1)
151
 
 
152
 
try:
153
 
    from getopt import getopt
154
 
    opts, args = getopt(sys.argv[1:], 'p:')
155
 
 
156
 
    for option, value in opts:
157
 
        if option == '-p':
158
 
            OVERRIDE_PYTHON = value
159
 
            
160
 
    
161
 
    mypath = os.path.abspath(sys.argv[0])
162
 
    print '%-30s %s' % ('running tests from', mypath)
163
 
 
164
 
    global BZRPATH
165
 
 
166
 
    if args:
167
 
        BZRPATH = args[0]
168
 
    else:
169
 
        BZRPATH = os.path.join(os.path.split(mypath)[0], 'bzr')
170
 
 
171
 
    print '%-30s %s' % ('against bzr', BZRPATH)
172
 
    print '%-30s %s' % ('in directory', os.getcwd())
173
 
    print '%-30s %s' % ('with python', (OVERRIDE_PYTHON or '(default)'))
174
 
    print
175
 
    print backtick('bzr version')
176
 
    
177
 
    runcmd(['mkdir', TESTDIR])
178
 
    cd(TESTDIR)
179
 
    # This means that any command that is naively run in this directory
180
 
    # Won't affect the parent directory.
181
 
    runcmd('bzr init')
182
 
    test_root = os.getcwd()
183
 
 
184
 
    progress("introductory commands")
185
 
    runcmd("bzr version")
186
 
    runcmd("bzr --version")
187
 
    runcmd("bzr help")
188
 
    runcmd("bzr --help")
189
 
 
190
 
    progress("internal tests")
191
 
    runcmd("bzr selftest")
192
 
 
193
 
    progress("invalid commands")
194
 
    runcmd("bzr pants", retcode=1)
195
 
    runcmd("bzr --pants off", retcode=1)
196
 
    runcmd("bzr diff --message foo", retcode=1)
197
 
 
198
 
    progress("basic branch creation")
199
 
    runcmd(['mkdir', 'branch1'])
200
 
    cd('branch1')
201
 
    runcmd('bzr init')
202
 
 
203
 
    assert backtick('bzr root')[:-1] == os.path.join(test_root, 'branch1')
204
 
 
205
 
    progress("status of new file")
206
 
    
207
 
    f = file('test.txt', 'wt')
208
 
    f.write('hello world!\n')
209
 
    f.close()
210
 
 
211
 
    out = backtick("bzr unknowns")
212
 
    assert out == 'test.txt\n'
213
 
 
214
 
    out = backtick("bzr status")
215
 
    assert out == 'unknown:\n  test.txt\n'
216
 
 
217
 
    out = backtick("bzr status --all")
218
 
    assert out == "unknown:\n  test.txt\n"
219
 
 
220
 
    out = backtick("bzr status test.txt --all")
221
 
    assert out == "unknown:\n  test.txt\n"
222
 
 
223
 
    f = file('test2.txt', 'wt')
224
 
    f.write('goodbye cruel world...\n')
225
 
    f.close()
226
 
 
227
 
    out = backtick("bzr status test.txt")
228
 
    assert out == "unknown:\n  test.txt\n"
229
 
 
230
 
    out = backtick("bzr status")
231
 
    assert out == ("unknown:\n"
232
 
                   "  test.txt\n"
233
 
                   "  test2.txt\n")
234
 
 
235
 
    os.unlink('test2.txt')
236
 
 
237
 
    progress("command aliases")
238
 
    out = backtick("bzr st --all")
239
 
    assert out == ("unknown:\n"
240
 
                   "  test.txt\n")
241
 
    
242
 
    out = backtick("bzr stat")
243
 
    assert out == ("unknown:\n"
244
 
                   "  test.txt\n")
245
 
 
246
 
    progress("command help")
247
 
    runcmd("bzr help st")
248
 
    runcmd("bzr help")
249
 
    runcmd("bzr help commands")
250
 
    runcmd("bzr help slartibartfast", 1)
251
 
 
252
 
    out = backtick("bzr help ci")
253
 
    out.index('aliases: ')
254
 
 
255
 
    progress("can't rename unversioned file")
256
 
    runcmd("bzr rename test.txt new-test.txt", 1)
257
 
 
258
 
    progress("adding a file")
259
 
 
260
 
    runcmd("bzr add test.txt")
261
 
    assert backtick("bzr unknowns") == ''
262
 
    assert backtick("bzr status --all") == ("added:\n"
263
 
                                            "  test.txt\n")
264
 
 
265
 
    progress("rename newly-added file")
266
 
    runcmd("bzr rename test.txt hello.txt")
267
 
    assert os.path.exists("hello.txt")
268
 
    assert not os.path.exists("test.txt")
269
 
 
270
 
    assert backtick("bzr revno") == '0\n'
271
 
 
272
 
    progress("add first revision")
273
 
    runcmd(["bzr", "commit", "-m", 'add first revision'])
274
 
 
275
 
    progress("more complex renames")
276
 
    os.mkdir("sub1")
277
 
    runcmd("bzr rename hello.txt sub1", 1)
278
 
    runcmd("bzr rename hello.txt sub1/hello.txt", 1)
279
 
    runcmd("bzr move hello.txt sub1", 1)
280
 
 
281
 
    runcmd("bzr add sub1")
282
 
    runcmd("bzr rename sub1 sub2")
283
 
    runcmd("bzr move hello.txt sub2")
284
 
    assert backtick("bzr relpath sub2/hello.txt") == os.path.join("sub2", "hello.txt\n")
285
 
 
286
 
    assert exists("sub2")
287
 
    assert exists("sub2/hello.txt")
288
 
    assert not exists("sub1")
289
 
    assert not exists("hello.txt")
290
 
 
291
 
    runcmd(['bzr', 'commit', '-m', 'commit with some things moved to subdirs'])
292
 
 
293
 
    mkdir("sub1")
294
 
    runcmd('bzr add sub1')
295
 
    runcmd('bzr move sub2/hello.txt sub1')
296
 
    assert not exists('sub2/hello.txt')
297
 
    assert exists('sub1/hello.txt')
298
 
    runcmd('bzr move sub2 sub1')
299
 
    assert not exists('sub2')
300
 
    assert exists('sub1/sub2')
301
 
 
302
 
    runcmd(['bzr', 'commit', '-m', 'rename nested subdirectories'])
303
 
 
304
 
    cd('sub1/sub2')
305
 
    assert backtick('bzr root')[:-1] == os.path.join(test_root, 'branch1')
306
 
    runcmd('bzr move ../hello.txt .')
307
 
    assert exists('./hello.txt')
308
 
    assert backtick('bzr relpath hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
309
 
    assert backtick('bzr relpath ../../sub1/sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
310
 
    runcmd(['bzr', 'commit', '-m', 'move to parent directory'])
311
 
    cd('..')
312
 
    assert backtick('bzr relpath sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
313
 
 
314
 
    runcmd('bzr move sub2/hello.txt .')
315
 
    assert exists('hello.txt')
316
 
 
317
 
    f = file('hello.txt', 'wt')
318
 
    f.write('some nice new content\n')
319
 
    f.close()
320
 
 
321
 
    f = file('msg.tmp', 'wt')
322
 
    f.write('this is my new commit\n')
323
 
    f.close()
324
 
 
325
 
    runcmd('bzr commit -F msg.tmp')
326
 
 
327
 
    assert backtick('bzr revno') == '5\n'
328
 
    runcmd('bzr export -r 5 export-5.tmp')
329
 
    runcmd('bzr export export.tmp')
330
 
 
331
 
    runcmd('bzr log')
332
 
    runcmd('bzr log -v')
333
 
 
334
 
 
335
 
 
336
 
    progress("file with spaces in name")
337
 
    mkdir('sub directory')
338
 
    file('sub directory/file with spaces ', 'wt').write('see how this works\n')
339
 
    runcmd('bzr add .')
340
 
    runcmd('bzr diff')
341
 
    runcmd('bzr commit -m add-spaces')
342
 
    runcmd('bzr check')
343
 
 
344
 
    runcmd('bzr log')
345
 
    runcmd('bzr log --forward')
346
 
 
347
 
    runcmd('bzr info')
348
 
 
349
 
 
350
 
    
351
 
 
352
 
 
353
 
 
354
 
    cd('..')
355
 
    cd('..')
356
 
    progress('branch')
357
 
    # Can't create a branch if it already exists
358
 
    runcmd('bzr branch branch1', retcode=1)
359
 
    # Can't create a branch if its parent doesn't exist
360
 
    runcmd('bzr branch /unlikely/to/exist', retcode=1)
361
 
    runcmd('bzr branch branch1 branch2')
362
 
 
363
 
    progress("pull")
364
 
    cd('branch1')
365
 
    runcmd('bzr pull', retcode=1)
366
 
    runcmd('bzr pull ../branch2')
367
 
    cd('.bzr')
368
 
    runcmd('bzr pull')
369
 
    runcmd('bzr commit -m empty')
370
 
    runcmd('bzr pull')
371
 
    cd('../../branch2')
372
 
    runcmd('bzr pull')
373
 
    runcmd('bzr commit -m empty')
374
 
    cd('../branch1')
375
 
    runcmd('bzr commit -m empty')
376
 
    runcmd('bzr pull', retcode=1)
377
 
    cd ('..')
378
 
 
379
 
    progress('status after remove')
380
 
    mkdir('status-after-remove')
381
 
    # see mail from William Dodé, 2005-05-25
382
 
    # $ bzr init; touch a; bzr add a; bzr commit -m "add a"
383
 
    #     * looking for changes...
384
 
    #     added a
385
 
    #     * commited r1
386
 
    #     $ bzr remove a
387
 
    #     $ bzr status
388
 
    #     bzr: local variable 'kind' referenced before assignment
389
 
    #     at /vrac/python/bazaar-ng/bzrlib/diff.py:286 in compare_trees()
390
 
    #     see ~/.bzr.log for debug information
391
 
    cd('status-after-remove')
392
 
    runcmd('bzr init')
393
 
    file('a', 'w').write('foo')
394
 
    runcmd('bzr add a')
395
 
    runcmd(['bzr', 'commit', '-m', 'add a'])
396
 
    runcmd('bzr remove a')
397
 
    runcmd('bzr status')
398
 
 
399
 
    cd('..')
400
 
 
401
 
    progress('ignore patterns')
402
 
    mkdir('ignorebranch')
403
 
    cd('ignorebranch')
404
 
    runcmd('bzr init')
405
 
    assert backtick('bzr unknowns') == ''
406
 
 
407
 
    file('foo.tmp', 'wt').write('tmp files are ignored')
408
 
    assert backtick('bzr unknowns') == ''
409
 
 
410
 
    file('foo.c', 'wt').write('int main() {}')
411
 
    assert backtick('bzr unknowns') == 'foo.c\n'
412
 
    runcmd('bzr add foo.c')
413
 
    assert backtick('bzr unknowns') == ''
414
 
 
415
 
    # 'ignore' works when creating the .bzignore file
416
 
    file('foo.blah', 'wt').write('blah')
417
 
    assert backtick('bzr unknowns') == 'foo.blah\n'
418
 
    runcmd('bzr ignore *.blah')
419
 
    assert backtick('bzr unknowns') == ''
420
 
    assert file('.bzrignore', 'rb').read() == '*.blah\n'
421
 
 
422
 
    # 'ignore' works when then .bzrignore file already exists
423
 
    file('garh', 'wt').write('garh')
424
 
    assert backtick('bzr unknowns') == 'garh\n'
425
 
    runcmd('bzr ignore garh')
426
 
    assert backtick('bzr unknowns') == ''
427
 
    assert file('.bzrignore', 'rb').read() == '*.blah\ngarh\n'
428
 
 
429
 
    cd('..')
430
 
 
431
 
 
432
 
 
433
 
 
434
 
    progress("recursive and non-recursive add")
435
 
    mkdir('no-recurse')
436
 
    cd('no-recurse')
437
 
    runcmd('bzr init')
438
 
    mkdir('foo')
439
 
    fp = os.path.join('foo', 'test.txt')
440
 
    f = file(fp, 'w')
441
 
    f.write('hello!\n')
442
 
    f.close()
443
 
    runcmd('bzr add --no-recurse foo')
444
 
    runcmd('bzr file-id foo')
445
 
    runcmd('bzr file-id ' + fp, 1)      # not versioned yet
446
 
    runcmd('bzr commit -m add-dir-only')
447
 
 
448
 
    runcmd('bzr file-id ' + fp, 1)      # still not versioned 
449
 
 
450
 
    runcmd('bzr add foo')
451
 
    runcmd('bzr file-id ' + fp)
452
 
    runcmd('bzr commit -m add-sub-file')
453
 
    
454
 
    cd('..')
455
 
 
456
 
 
457
 
 
458
 
 
459
 
    # Run any function in this 
460
 
    g = globals()
461
 
    funcs = g.keys()
462
 
    funcs.sort()
463
 
    for k in funcs:
464
 
        if k.startswith('test_') and callable(g[k]):
465
 
            progress(k[5:].replace('_', ' '))
466
 
            g[k]()
467
 
 
468
 
    progress("all tests passed!")
469
 
except Exception, e:
470
 
    sys.stderr.write('*' * 50 + '\n'
471
 
                     + 'testbzr: tests failed\n'
472
 
                     + 'see ' + LOGFILENAME + ' for more information\n'
473
 
                     + '*' * 50 + '\n')
474
 
    logfile.write('tests failed!\n')
475
 
    traceback.print_exc(None, logfile)
476
 
    logfile.close()
477
 
 
478
 
    sys.stdout.writelines(file(os.path.join(start_dir, LOGFILENAME), 'rt').readlines()[-50:])
479
 
    
480
 
    sys.exit(1)
481