~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to testbzr

  • Committer: Martin Pool
  • Date: 2005-05-16 04:10:11 UTC
  • Revision ID: mbp@sourcefrog.net-20050516041010-3da9519817d73b20
- new -p option for testbzr to use a different version of python 
  to run the bzr under test

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#! /usr/bin/python
2
 
# -*- coding: utf-8 -*-
3
2
 
4
3
# Copyright (C) 2005 Canonical Ltd
5
4
 
17
16
# along with this program; if not, write to the Free Software
18
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
18
 
20
 
print 'please use "bzr selftest" instead'
21
 
import sys
22
 
sys.exit(1)
23
 
 
 
19
 
 
20
"""External black-box test for bzr.
 
21
 
 
22
This always runs bzr as an external process to try to catch bugs
 
23
related to argument processing, startup, etc.
 
24
 
 
25
usage:
 
26
 
 
27
    testbzr [-p PYTHON] [BZR]
 
28
 
 
29
By default this tests the copy of bzr found in the same directory as
 
30
testbzr, or the first one found on the $PATH.  A copy of bzr may be
 
31
given on the command line to override this, for example when applying
 
32
a new test suite to an old copy of bzr or vice versa.
 
33
 
 
34
testbzr normally invokes bzr using the same version of python as it
 
35
would normally use to run -- that is, the system default python,
 
36
unless that is older than 2.3.  The -p option allows specification of
 
37
a different Python interpreter, such as when testing that bzr still
 
38
works on python2.3.
 
39
 
 
40
This replaces the previous test.sh which was not very portable."""
 
41
 
 
42
import sys, os, traceback
 
43
from os import mkdir
 
44
from os.path import exists
 
45
 
 
46
TESTDIR = "testbzr.tmp"
 
47
 
 
48
OVERRIDE_PYTHON = None
 
49
 
 
50
LOGFILENAME = 'testbzr.log'
 
51
 
 
52
try:
 
53
    import shutil
 
54
    from subprocess import call, Popen, PIPE
 
55
except ImportError, e:
 
56
    sys.stderr.write("testbzr: sorry, this test suite requires modules from python2.4\n"
 
57
                     + '    ' + str(e))
 
58
    sys.exit(1)
 
59
 
 
60
 
 
61
class CommandFailed(Exception):
 
62
    pass
 
63
 
 
64
 
 
65
def formcmd(cmd):
 
66
    if isinstance(cmd, basestring):
 
67
        cmd = cmd.split()
 
68
 
 
69
    if cmd[0] == 'bzr':
 
70
        cmd[0] = BZRPATH
 
71
        if OVERRIDE_PYTHON:
 
72
            cmd.insert(0, OVERRIDE_PYTHON)
 
73
 
 
74
    logfile.write('$ %r\n' % cmd)
 
75
    
 
76
    return cmd
 
77
 
 
78
 
 
79
def runcmd(cmd, retcode=0):
 
80
    """Run one command and check the return code.
 
81
 
 
82
    Returns a tuple of (stdout,stderr) strings.
 
83
 
 
84
    If a single string is based, it is split into words.
 
85
    For commands that are not simple space-separated words, please
 
86
    pass a list instead."""
 
87
    cmd = formcmd(cmd)
 
88
    log_linenumber()
 
89
    
 
90
    actual_retcode = call(cmd, stdout=logfile, stderr=logfile)
 
91
    
 
92
    if retcode != actual_retcode:
 
93
        raise CommandFailed("test failed: %r returned %d, expected %d"
 
94
                            % (cmd, actual_retcode, retcode))
 
95
 
 
96
 
 
97
 
 
98
def backtick(cmd, retcode=0):
 
99
    cmd = formcmd(cmd)
 
100
    log_linenumber()
 
101
    child = Popen(cmd, stdout=PIPE, stderr=logfile)
 
102
    outd, errd = child.communicate()
 
103
    logfile.write(outd)
 
104
    actual_retcode = child.wait()
 
105
 
 
106
    outd = outd.replace('\r', '')
 
107
    
 
108
    if retcode != actual_retcode:
 
109
        raise CommandFailed("test failed: %r returned %d, expected %d"
 
110
                            % (cmd, actual_retcode, retcode))
 
111
 
 
112
    return outd
 
113
 
 
114
 
 
115
 
 
116
def progress(msg):
 
117
    print '* ' + msg
 
118
    logfile.write('* '+ msg + '\n')
 
119
    log_linenumber()
 
120
 
 
121
 
 
122
def cd(dirname):
 
123
    logfile.write('$ cd %s\n' % dirname)
 
124
    os.chdir(dirname)
 
125
 
 
126
 
 
127
 
 
128
def log_linenumber():
 
129
    """Log the stack frame location two things up."""
 
130
    stack = traceback.extract_stack()[-3]
 
131
    logfile.write('   at %s:%d\n' % stack[:2])
 
132
 
 
133
 
 
134
 
 
135
# prepare an empty scratch directory
 
136
if os.path.exists(TESTDIR):
 
137
    shutil.rmtree(TESTDIR)
 
138
 
 
139
 
 
140
logfile = open(LOGFILENAME, 'wt', buffering=1)
 
141
 
 
142
 
 
143
try:
 
144
    from getopt import getopt
 
145
    opts, args = getopt(sys.argv[1:], 'p:')
 
146
 
 
147
    for option, value in opts:
 
148
        if option == '-p':
 
149
            OVERRIDE_PYTHON = value
 
150
            
 
151
    
 
152
    mypath = os.path.abspath(sys.argv[0])
 
153
    print '%-30s %s' % ('running tests from', mypath)
 
154
 
 
155
    global BZRPATH
 
156
 
 
157
    if args:
 
158
        BZRPATH = args[1]
 
159
    else:
 
160
        BZRPATH = os.path.join(os.path.split(mypath)[0], 'bzr')
 
161
 
 
162
    print '%-30s %s' % ('against bzr', BZRPATH)
 
163
    print '%-30s %s' % ('in directory', os.getcwd())
 
164
    print '%-30s %s' % ('with python', (OVERRIDE_PYTHON or '(default)'))
 
165
    print
 
166
    print backtick([BZRPATH, 'version'])
 
167
    
 
168
    runcmd(['mkdir', TESTDIR])
 
169
    cd(TESTDIR)
 
170
    test_root = os.getcwd()
 
171
 
 
172
    progress("introductory commands")
 
173
    runcmd("bzr version")
 
174
    runcmd("bzr --version")
 
175
    runcmd("bzr help")
 
176
    runcmd("bzr --help")
 
177
 
 
178
    progress("internal tests")
 
179
    runcmd("bzr selftest")
 
180
 
 
181
    progress("user identity")
 
182
    # this should always identify something, if only "john@localhost"
 
183
    runcmd("bzr whoami")
 
184
    runcmd("bzr whoami --email")
 
185
    assert backtick("bzr whoami --email").count('@') == 1
 
186
 
 
187
    progress("invalid commands")
 
188
    runcmd("bzr pants", retcode=1)
 
189
    runcmd("bzr --pants off", retcode=1)
 
190
    runcmd("bzr diff --message foo", retcode=1)
 
191
 
 
192
    progress("basic branch creation")
 
193
    runcmd(['mkdir', 'branch1'])
 
194
    cd('branch1')
 
195
    runcmd('bzr init')
 
196
 
 
197
    assert backtick('bzr root')[:-1] == os.path.join(test_root, 'branch1')
 
198
 
 
199
    progress("status of new file")
 
200
    
 
201
    f = file('test.txt', 'wt')
 
202
    f.write('hello world!\n')
 
203
    f.close()
 
204
 
 
205
    out = backtick("bzr unknowns")
 
206
    assert out == 'test.txt\n'
 
207
 
 
208
    out = backtick("bzr status")
 
209
    assert out == 'unknown:\n  test.txt\n'
 
210
 
 
211
    out = backtick("bzr status --all")
 
212
    assert out == "unknown:\n  test.txt\n"
 
213
 
 
214
    out = backtick("bzr status test.txt --all")
 
215
    assert out == "unknown:\n  test.txt\n"
 
216
 
 
217
    f = file('test2.txt', 'wt')
 
218
    f.write('goodbye cruel world...\n')
 
219
    f.close()
 
220
 
 
221
    out = backtick("bzr status test.txt")
 
222
    assert out == "unknown:\n  test.txt\n"
 
223
 
 
224
    out = backtick("bzr status")
 
225
    assert out == ("unknown:\n"
 
226
                   "  test.txt\n"
 
227
                   "  test2.txt\n")
 
228
 
 
229
    os.unlink('test2.txt')
 
230
 
 
231
    progress("command aliases")
 
232
    out = backtick("bzr st --all")
 
233
    assert out == ("unknown:\n"
 
234
                   "  test.txt\n")
 
235
    
 
236
    out = backtick("bzr stat")
 
237
    assert out == ("unknown:\n"
 
238
                   "  test.txt\n")
 
239
 
 
240
    progress("command help")
 
241
    runcmd("bzr help st")
 
242
    runcmd("bzr help")
 
243
    runcmd("bzr help commands")
 
244
    runcmd("bzr help slartibartfast", 1)
 
245
 
 
246
    out = backtick("bzr help ci")
 
247
    out.index('aliases: ')
 
248
 
 
249
    progress("can't rename unversioned file")
 
250
    runcmd("bzr rename test.txt new-test.txt", 1)
 
251
 
 
252
    progress("adding a file")
 
253
 
 
254
    runcmd("bzr add test.txt")
 
255
    assert backtick("bzr unknowns") == ''
 
256
    assert backtick("bzr status --all") == ("added:\n"
 
257
                                            "  test.txt\n")
 
258
 
 
259
    progress("rename newly-added file")
 
260
    runcmd("bzr rename test.txt hello.txt")
 
261
    assert os.path.exists("hello.txt")
 
262
    assert not os.path.exists("test.txt")
 
263
 
 
264
    assert backtick("bzr revno") == '0\n'
 
265
 
 
266
    progress("add first revision")
 
267
    runcmd(["bzr", "commit", "-m", 'add first revision'])
 
268
 
 
269
    progress("more complex renames")
 
270
    os.mkdir("sub1")
 
271
    runcmd("bzr rename hello.txt sub1", 1)
 
272
    runcmd("bzr rename hello.txt sub1/hello.txt", 1)
 
273
    runcmd("bzr move hello.txt sub1", 1)
 
274
 
 
275
    runcmd("bzr add sub1")
 
276
    runcmd("bzr rename sub1 sub2")
 
277
    runcmd("bzr move hello.txt sub2")
 
278
    assert backtick("bzr relpath sub2/hello.txt") == "sub2/hello.txt\n"
 
279
 
 
280
    assert exists("sub2")
 
281
    assert exists("sub2/hello.txt")
 
282
    assert not exists("sub1")
 
283
    assert not exists("hello.txt")
 
284
 
 
285
    runcmd(['bzr', 'commit', '-m', 'commit with some things moved to subdirs'])
 
286
 
 
287
    mkdir("sub1")
 
288
    runcmd('bzr add sub1')
 
289
    runcmd('bzr move sub2/hello.txt sub1')
 
290
    assert not exists('sub2/hello.txt')
 
291
    assert exists('sub1/hello.txt')
 
292
    runcmd('bzr move sub2 sub1')
 
293
    assert not exists('sub2')
 
294
    assert exists('sub1/sub2')
 
295
 
 
296
    runcmd(['bzr', 'commit', '-m', 'rename nested subdirectories'])
 
297
 
 
298
    cd('sub1/sub2')
 
299
    assert backtick('bzr root')[:-1] == os.path.join(test_root, 'branch1')
 
300
    runcmd('bzr move ../hello.txt .')
 
301
    assert exists('./hello.txt')
 
302
    assert backtick('bzr relpath hello.txt') == 'sub1/sub2/hello.txt\n'
 
303
    assert backtick('bzr relpath ../../sub1/sub2/hello.txt') == 'sub1/sub2/hello.txt\n'
 
304
    runcmd(['bzr', 'commit', '-m', 'move to parent directory'])
 
305
    cd('..')
 
306
    assert backtick('bzr relpath sub2/hello.txt') == 'sub1/sub2/hello.txt\n'
 
307
 
 
308
    runcmd('bzr move sub2/hello.txt .')
 
309
    assert exists('hello.txt')
 
310
 
 
311
    f = file('hello.txt', 'wt')
 
312
    f.write('some nice new content\n')
 
313
    f.close()
 
314
 
 
315
    f = file('msg.tmp', 'wt')
 
316
    f.write('this is my new commit\n')
 
317
    f.close()
 
318
 
 
319
    runcmd('bzr commit -F msg.tmp')
 
320
 
 
321
    assert backtick('bzr revno') == '5\n'
 
322
    runcmd('bzr export -r 5 export-5.tmp')
 
323
    runcmd('bzr export export.tmp')
 
324
 
 
325
    runcmd('bzr log')
 
326
    runcmd('bzr log -v')
 
327
    
 
328
    cd('..')
 
329
    cd('..')
 
330
 
 
331
    progress('ignore patterns')
 
332
    mkdir('ignorebranch')
 
333
    cd('ignorebranch')
 
334
    runcmd('bzr init')
 
335
    assert backtick('bzr unknowns') == ''
 
336
 
 
337
    file('foo.tmp', 'wt').write('tmp files are ignored')
 
338
    assert backtick('bzr unknowns') == ''
 
339
 
 
340
    file('foo.c', 'wt').write('int main() {}')
 
341
    assert backtick('bzr unknowns') == 'foo.c\n'
 
342
    runcmd('bzr add foo.c')
 
343
    assert backtick('bzr unknowns') == ''
 
344
 
 
345
    # 'ignore' works when creating the .bzignore file
 
346
    file('foo.blah', 'wt').write('blah')
 
347
    assert backtick('bzr unknowns') == 'foo.blah\n'
 
348
    runcmd('bzr ignore *.blah')
 
349
    assert backtick('bzr unknowns') == ''
 
350
    assert file('.bzrignore', 'rb').read() == '*.blah\n'
 
351
 
 
352
    # 'ignore' works when then .bzrignore file already exists
 
353
    file('garh', 'wt').write('garh')
 
354
    assert backtick('bzr unknowns') == 'garh\n'
 
355
    runcmd('bzr ignore garh')
 
356
    assert backtick('bzr unknowns') == ''
 
357
    assert file('.bzrignore', 'rb').read() == '*.blah\ngarh\n'
 
358
 
 
359
    progress("all tests passed!")
 
360
except Exception, e:
 
361
    sys.stderr.write('*' * 50 + '\n'
 
362
                     + 'testbzr: tests failed\n'
 
363
                     + 'see ' + LOGFILENAME + ' for more information\n'
 
364
                     + '*' * 50 + '\n')
 
365
    logfile.write('tests failed!\n')
 
366
    traceback.print_exc(None, logfile)
 
367
    sys.exit(1)