/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to testbzr

  • Committer: Martin Pool
  • Date: 2005-06-22 06:04:43 UTC
  • Revision ID: mbp@sourcefrog.net-20050622060443-12fe7e3443dde3bb
- merge plugin patch from john

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#! /usr/bin/python
 
2
# -*- coding: utf-8 -*-
 
3
 
 
4
# Copyright (C) 2005 Canonical Ltd
 
5
 
 
6
# This program is free software; you can redistribute it and/or modify
 
7
# it under the terms of the GNU General Public License as published by
 
8
# the Free Software Foundation; either version 2 of the License, or
 
9
# (at your option) any later version.
 
10
 
 
11
# This program is distributed in the hope that it will be useful,
 
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
# GNU General Public License for more details.
 
15
 
 
16
# You should have received a copy of the GNU General Public License
 
17
# along with this program; if not, write to the Free Software
 
18
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
 
 
20
print 'please use "bzr selftest" instead'
 
21
import sys
 
22
sys.exit(1)
 
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
def test_plugins():
 
153
    """Run a test involving creating a plugin to load,
 
154
    and making sure it is seen properly.
 
155
    """
 
156
    orig_help = backtick('bzr help commands') # No plugins yet
 
157
    mkdir('plugin_test')
 
158
    f = open(os.path.join('plugin_test', 'myplug.py'), 'wb')
 
159
    f.write("""import bzrlib, bzrlib.commands
 
160
class cmd_myplug(bzrlib.commands.Command):
 
161
    '''Just a simple test plugin.'''
 
162
    aliases = ['mplg']
 
163
    def run(self):
 
164
        print 'Hello from my plugin'
 
165
""")
 
166
    f.close()
 
167
 
 
168
    os.environ['BZRPLUGINPATH'] = os.path.abspath('plugin_test')
 
169
    help = backtick('bzr help commands')
 
170
    assert help.find('myplug') != -1
 
171
    assert help.find('Just a simple test plugin.') != -1
 
172
 
 
173
    
 
174
    assert backtick('bzr myplug') == 'Hello from my plugin\n'
 
175
    assert backtick('bzr mplg') == 'Hello from my plugin\n'
 
176
 
 
177
    f = open(os.path.join('plugin_test', 'override.py'), 'wb')
 
178
    f.write("""import bzrlib, bzrlib.commands
 
179
class cmd_commit(bzrlib.commands.cmd_commit):
 
180
    '''Commit changes into a new revision.'''
 
181
    def run(self, *args, **kwargs):
 
182
        print "I'm sorry dave, you can't do that"
 
183
 
 
184
class cmd_help(bzrlib.commands.cmd_help):
 
185
    '''Show help on a command or other topic.'''
 
186
    def run(self, *args, **kwargs):
 
187
        print "You have been overridden"
 
188
        bzrlib.commands.cmd_help.run(self, *args, **kwargs)
 
189
 
 
190
""")
 
191
    f.close()
 
192
 
 
193
    newhelp = backtick('bzr help commands')
 
194
    assert newhelp.startswith('You have been overridden\n')
 
195
    # We added a line, but the rest should work
 
196
    assert newhelp[25:] == help
 
197
 
 
198
    assert backtick('bzr commit -m test') == "I'm sorry dave, you can't do that\n"
 
199
    
 
200
    shutil.rmtree('plugin_test')
 
201
 
 
202
try:
 
203
    from getopt import getopt
 
204
    opts, args = getopt(sys.argv[1:], 'p:')
 
205
 
 
206
    for option, value in opts:
 
207
        if option == '-p':
 
208
            OVERRIDE_PYTHON = value
 
209
            
 
210
    
 
211
    mypath = os.path.abspath(sys.argv[0])
 
212
    print '%-30s %s' % ('running tests from', mypath)
 
213
 
 
214
    global BZRPATH
 
215
 
 
216
    if args:
 
217
        BZRPATH = args[0]
 
218
    else:
 
219
        BZRPATH = os.path.join(os.path.split(mypath)[0], 'bzr')
 
220
 
 
221
    print '%-30s %s' % ('against bzr', BZRPATH)
 
222
    print '%-30s %s' % ('in directory', os.getcwd())
 
223
    print '%-30s %s' % ('with python', (OVERRIDE_PYTHON or '(default)'))
 
224
    print
 
225
    print backtick('bzr version')
 
226
    
 
227
    runcmd(['mkdir', TESTDIR])
 
228
    cd(TESTDIR)
 
229
    # This means that any command that is naively run in this directory
 
230
    # Won't affect the parent directory.
 
231
    runcmd('bzr init')
 
232
    test_root = os.getcwd()
 
233
 
 
234
    progress("introductory commands")
 
235
    runcmd("bzr version")
 
236
    runcmd("bzr --version")
 
237
    runcmd("bzr help")
 
238
    runcmd("bzr --help")
 
239
 
 
240
    progress("internal tests")
 
241
    runcmd("bzr selftest")
 
242
 
 
243
    progress("user identity")
 
244
    # this should always identify something, if only "john@localhost"
 
245
    runcmd("bzr whoami")
 
246
    runcmd("bzr whoami --email")
 
247
    assert backtick("bzr whoami --email").count('@') == 1
 
248
 
 
249
    progress("invalid commands")
 
250
    runcmd("bzr pants", retcode=1)
 
251
    runcmd("bzr --pants off", retcode=1)
 
252
    runcmd("bzr diff --message foo", retcode=1)
 
253
 
 
254
    progress("basic branch creation")
 
255
    runcmd(['mkdir', 'branch1'])
 
256
    cd('branch1')
 
257
    runcmd('bzr init')
 
258
 
 
259
    assert backtick('bzr root')[:-1] == os.path.join(test_root, 'branch1')
 
260
 
 
261
    progress("status of new file")
 
262
    
 
263
    f = file('test.txt', 'wt')
 
264
    f.write('hello world!\n')
 
265
    f.close()
 
266
 
 
267
    out = backtick("bzr unknowns")
 
268
    assert out == 'test.txt\n'
 
269
 
 
270
    out = backtick("bzr status")
 
271
    assert out == 'unknown:\n  test.txt\n'
 
272
 
 
273
    out = backtick("bzr status --all")
 
274
    assert out == "unknown:\n  test.txt\n"
 
275
 
 
276
    out = backtick("bzr status test.txt --all")
 
277
    assert out == "unknown:\n  test.txt\n"
 
278
 
 
279
    f = file('test2.txt', 'wt')
 
280
    f.write('goodbye cruel world...\n')
 
281
    f.close()
 
282
 
 
283
    out = backtick("bzr status test.txt")
 
284
    assert out == "unknown:\n  test.txt\n"
 
285
 
 
286
    out = backtick("bzr status")
 
287
    assert out == ("unknown:\n"
 
288
                   "  test.txt\n"
 
289
                   "  test2.txt\n")
 
290
 
 
291
    os.unlink('test2.txt')
 
292
 
 
293
    progress("command aliases")
 
294
    out = backtick("bzr st --all")
 
295
    assert out == ("unknown:\n"
 
296
                   "  test.txt\n")
 
297
    
 
298
    out = backtick("bzr stat")
 
299
    assert out == ("unknown:\n"
 
300
                   "  test.txt\n")
 
301
 
 
302
    progress("command help")
 
303
    runcmd("bzr help st")
 
304
    runcmd("bzr help")
 
305
    runcmd("bzr help commands")
 
306
    runcmd("bzr help slartibartfast", 1)
 
307
 
 
308
    out = backtick("bzr help ci")
 
309
    out.index('aliases: ')
 
310
 
 
311
    progress("can't rename unversioned file")
 
312
    runcmd("bzr rename test.txt new-test.txt", 1)
 
313
 
 
314
    progress("adding a file")
 
315
 
 
316
    runcmd("bzr add test.txt")
 
317
    assert backtick("bzr unknowns") == ''
 
318
    assert backtick("bzr status --all") == ("added:\n"
 
319
                                            "  test.txt\n")
 
320
 
 
321
    progress("rename newly-added file")
 
322
    runcmd("bzr rename test.txt hello.txt")
 
323
    assert os.path.exists("hello.txt")
 
324
    assert not os.path.exists("test.txt")
 
325
 
 
326
    assert backtick("bzr revno") == '0\n'
 
327
 
 
328
    progress("add first revision")
 
329
    runcmd(["bzr", "commit", "-m", 'add first revision'])
 
330
 
 
331
    progress("more complex renames")
 
332
    os.mkdir("sub1")
 
333
    runcmd("bzr rename hello.txt sub1", 1)
 
334
    runcmd("bzr rename hello.txt sub1/hello.txt", 1)
 
335
    runcmd("bzr move hello.txt sub1", 1)
 
336
 
 
337
    runcmd("bzr add sub1")
 
338
    runcmd("bzr rename sub1 sub2")
 
339
    runcmd("bzr move hello.txt sub2")
 
340
    assert backtick("bzr relpath sub2/hello.txt") == os.path.join("sub2", "hello.txt\n")
 
341
 
 
342
    assert exists("sub2")
 
343
    assert exists("sub2/hello.txt")
 
344
    assert not exists("sub1")
 
345
    assert not exists("hello.txt")
 
346
 
 
347
    runcmd(['bzr', 'commit', '-m', 'commit with some things moved to subdirs'])
 
348
 
 
349
    mkdir("sub1")
 
350
    runcmd('bzr add sub1')
 
351
    runcmd('bzr move sub2/hello.txt sub1')
 
352
    assert not exists('sub2/hello.txt')
 
353
    assert exists('sub1/hello.txt')
 
354
    runcmd('bzr move sub2 sub1')
 
355
    assert not exists('sub2')
 
356
    assert exists('sub1/sub2')
 
357
 
 
358
    runcmd(['bzr', 'commit', '-m', 'rename nested subdirectories'])
 
359
 
 
360
    cd('sub1/sub2')
 
361
    assert backtick('bzr root')[:-1] == os.path.join(test_root, 'branch1')
 
362
    runcmd('bzr move ../hello.txt .')
 
363
    assert exists('./hello.txt')
 
364
    assert backtick('bzr relpath hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
 
365
    assert backtick('bzr relpath ../../sub1/sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
 
366
    runcmd(['bzr', 'commit', '-m', 'move to parent directory'])
 
367
    cd('..')
 
368
    assert backtick('bzr relpath sub2/hello.txt') == os.path.join('sub1', 'sub2', 'hello.txt\n')
 
369
 
 
370
    runcmd('bzr move sub2/hello.txt .')
 
371
    assert exists('hello.txt')
 
372
 
 
373
    f = file('hello.txt', 'wt')
 
374
    f.write('some nice new content\n')
 
375
    f.close()
 
376
 
 
377
    f = file('msg.tmp', 'wt')
 
378
    f.write('this is my new commit\n')
 
379
    f.close()
 
380
 
 
381
    runcmd('bzr commit -F msg.tmp')
 
382
 
 
383
    assert backtick('bzr revno') == '5\n'
 
384
    runcmd('bzr export -r 5 export-5.tmp')
 
385
    runcmd('bzr export export.tmp')
 
386
 
 
387
    runcmd('bzr log')
 
388
    runcmd('bzr log -v')
 
389
 
 
390
 
 
391
 
 
392
    progress("file with spaces in name")
 
393
    mkdir('sub directory')
 
394
    file('sub directory/file with spaces ', 'wt').write('see how this works\n')
 
395
    runcmd('bzr add .')
 
396
    runcmd('bzr diff')
 
397
    runcmd('bzr commit -m add-spaces')
 
398
    runcmd('bzr check')
 
399
 
 
400
    runcmd('bzr log')
 
401
    runcmd('bzr log --forward')
 
402
 
 
403
    runcmd('bzr info')
 
404
 
 
405
 
 
406
    
 
407
 
 
408
 
 
409
 
 
410
    cd('..')
 
411
    cd('..')
 
412
    progress('branch')
 
413
    # Can't create a branch if it already exists
 
414
    runcmd('bzr branch branch1', retcode=1)
 
415
    # Can't create a branch if its parent doesn't exist
 
416
    runcmd('bzr branch /unlikely/to/exist', retcode=1)
 
417
    runcmd('bzr branch branch1 branch2')
 
418
 
 
419
    progress("pull")
 
420
    cd('branch1')
 
421
    runcmd('bzr pull', retcode=1)
 
422
    runcmd('bzr pull ../branch2')
 
423
    cd('.bzr')
 
424
    runcmd('bzr pull')
 
425
    runcmd('bzr commit -m empty')
 
426
    runcmd('bzr pull')
 
427
    cd('../../branch2')
 
428
    runcmd('bzr pull')
 
429
    runcmd('bzr commit -m empty')
 
430
    cd('../branch1')
 
431
    runcmd('bzr commit -m empty')
 
432
    runcmd('bzr pull', retcode=1)
 
433
    cd ('..')
 
434
 
 
435
    progress('status after remove')
 
436
    mkdir('status-after-remove')
 
437
    # see mail from William Dodé, 2005-05-25
 
438
    # $ bzr init; touch a; bzr add a; bzr commit -m "add a"
 
439
    #     * looking for changes...
 
440
    #     added a
 
441
    #     * commited r1
 
442
    #     $ bzr remove a
 
443
    #     $ bzr status
 
444
    #     bzr: local variable 'kind' referenced before assignment
 
445
    #     at /vrac/python/bazaar-ng/bzrlib/diff.py:286 in compare_trees()
 
446
    #     see ~/.bzr.log for debug information
 
447
    cd('status-after-remove')
 
448
    runcmd('bzr init')
 
449
    file('a', 'w').write('foo')
 
450
    runcmd('bzr add a')
 
451
    runcmd(['bzr', 'commit', '-m', 'add a'])
 
452
    runcmd('bzr remove a')
 
453
    runcmd('bzr status')
 
454
 
 
455
    cd('..')
 
456
 
 
457
    progress('ignore patterns')
 
458
    mkdir('ignorebranch')
 
459
    cd('ignorebranch')
 
460
    runcmd('bzr init')
 
461
    assert backtick('bzr unknowns') == ''
 
462
 
 
463
    file('foo.tmp', 'wt').write('tmp files are ignored')
 
464
    assert backtick('bzr unknowns') == ''
 
465
 
 
466
    file('foo.c', 'wt').write('int main() {}')
 
467
    assert backtick('bzr unknowns') == 'foo.c\n'
 
468
    runcmd('bzr add foo.c')
 
469
    assert backtick('bzr unknowns') == ''
 
470
 
 
471
    # 'ignore' works when creating the .bzignore file
 
472
    file('foo.blah', 'wt').write('blah')
 
473
    assert backtick('bzr unknowns') == 'foo.blah\n'
 
474
    runcmd('bzr ignore *.blah')
 
475
    assert backtick('bzr unknowns') == ''
 
476
    assert file('.bzrignore', 'rb').read() == '*.blah\n'
 
477
 
 
478
    # 'ignore' works when then .bzrignore file already exists
 
479
    file('garh', 'wt').write('garh')
 
480
    assert backtick('bzr unknowns') == 'garh\n'
 
481
    runcmd('bzr ignore garh')
 
482
    assert backtick('bzr unknowns') == ''
 
483
    assert file('.bzrignore', 'rb').read() == '*.blah\ngarh\n'
 
484
 
 
485
    cd('..')
 
486
 
 
487
 
 
488
 
 
489
 
 
490
    progress("recursive and non-recursive add")
 
491
    mkdir('no-recurse')
 
492
    cd('no-recurse')
 
493
    runcmd('bzr init')
 
494
    mkdir('foo')
 
495
    fp = os.path.join('foo', 'test.txt')
 
496
    f = file(fp, 'w')
 
497
    f.write('hello!\n')
 
498
    f.close()
 
499
    runcmd('bzr add --no-recurse foo')
 
500
    runcmd('bzr file-id foo')
 
501
    runcmd('bzr file-id ' + fp, 1)      # not versioned yet
 
502
    runcmd('bzr commit -m add-dir-only')
 
503
 
 
504
    runcmd('bzr file-id ' + fp, 1)      # still not versioned 
 
505
 
 
506
    runcmd('bzr add foo')
 
507
    runcmd('bzr file-id ' + fp)
 
508
    runcmd('bzr commit -m add-sub-file')
 
509
    
 
510
    cd('..')
 
511
 
 
512
 
 
513
 
 
514
 
 
515
    # Run any function in this 
 
516
    g = globals()
 
517
    funcs = g.keys()
 
518
    funcs.sort()
 
519
    for k in funcs:
 
520
        if k.startswith('test_') and callable(g[k]):
 
521
            progress(k[5:].replace('_', ' '))
 
522
            g[k]()
 
523
 
 
524
    progress("all tests passed!")
 
525
except Exception, e:
 
526
    sys.stderr.write('*' * 50 + '\n'
 
527
                     + 'testbzr: tests failed\n'
 
528
                     + 'see ' + LOGFILENAME + ' for more information\n'
 
529
                     + '*' * 50 + '\n')
 
530
    logfile.write('tests failed!\n')
 
531
    traceback.print_exc(None, logfile)
 
532
    logfile.close()
 
533
 
 
534
    sys.stdout.writelines(file(os.path.join(start_dir, LOGFILENAME), 'rt').readlines()[-50:])
 
535
    
 
536
    sys.exit(1)
 
537