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
20
print 'please use "bzr selftest" instead'
20
"""External black-box test for bzr.
22
This always runs bzr as an external process to try to catch bugs
23
related to argument processing, startup, etc.
27
testbzr [-p PYTHON] [BZR]
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.
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
40
This replaces the previous test.sh which was not very portable."""
42
import sys, os, traceback
44
from os.path import exists
46
TESTDIR = "testbzr.tmp"
48
OVERRIDE_PYTHON = None
50
LOGFILENAME = 'testbzr.log'
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"
61
class CommandFailed(Exception):
66
if isinstance(cmd, basestring):
72
cmd.insert(0, OVERRIDE_PYTHON)
74
logfile.write('$ %r\n' % cmd)
79
def runcmd(cmd, retcode=0):
80
"""Run one command and check the return code.
82
Returns a tuple of (stdout,stderr) strings.
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."""
90
actual_retcode = call(cmd, stdout=logfile, stderr=logfile)
92
if retcode != actual_retcode:
93
raise CommandFailed("test failed: %r returned %d, expected %d"
94
% (cmd, actual_retcode, retcode))
98
def backtick(cmd, retcode=0):
101
child = Popen(cmd, stdout=PIPE, stderr=logfile)
102
outd, errd = child.communicate()
104
actual_retcode = child.wait()
106
outd = outd.replace('\r', '')
108
if retcode != actual_retcode:
109
raise CommandFailed("test failed: %r returned %d, expected %d"
110
% (cmd, actual_retcode, retcode))
118
logfile.write('* '+ msg + '\n')
123
logfile.write('$ cd %s\n' % dirname)
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])
135
# prepare an empty scratch directory
136
if os.path.exists(TESTDIR):
137
shutil.rmtree(TESTDIR)
140
logfile = open(LOGFILENAME, 'wt', buffering=1)
144
from getopt import getopt
145
opts, args = getopt(sys.argv[1:], 'p:')
147
for option, value in opts:
149
OVERRIDE_PYTHON = value
152
mypath = os.path.abspath(sys.argv[0])
153
print '%-30s %s' % ('running tests from', mypath)
160
BZRPATH = os.path.join(os.path.split(mypath)[0], 'bzr')
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)'))
166
print backtick([BZRPATH, 'version'])
168
runcmd(['mkdir', TESTDIR])
170
test_root = os.getcwd()
172
progress("introductory commands")
173
runcmd("bzr version")
174
runcmd("bzr --version")
178
progress("internal tests")
179
runcmd("bzr selftest")
181
progress("user identity")
182
# this should always identify something, if only "john@localhost"
184
runcmd("bzr whoami --email")
185
assert backtick("bzr whoami --email").count('@') == 1
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)
192
progress("basic branch creation")
193
runcmd(['mkdir', 'branch1'])
197
assert backtick('bzr root')[:-1] == os.path.join(test_root, 'branch1')
199
progress("status of new file")
201
f = file('test.txt', 'wt')
202
f.write('hello world!\n')
205
out = backtick("bzr unknowns")
206
assert out == 'test.txt\n'
208
out = backtick("bzr status")
209
assert out == 'unknown:\n test.txt\n'
211
out = backtick("bzr status --all")
212
assert out == "unknown:\n test.txt\n"
214
out = backtick("bzr status test.txt --all")
215
assert out == "unknown:\n test.txt\n"
217
f = file('test2.txt', 'wt')
218
f.write('goodbye cruel world...\n')
221
out = backtick("bzr status test.txt")
222
assert out == "unknown:\n test.txt\n"
224
out = backtick("bzr status")
225
assert out == ("unknown:\n"
229
os.unlink('test2.txt')
231
progress("command aliases")
232
out = backtick("bzr st --all")
233
assert out == ("unknown:\n"
236
out = backtick("bzr stat")
237
assert out == ("unknown:\n"
240
progress("command help")
241
runcmd("bzr help st")
243
runcmd("bzr help commands")
244
runcmd("bzr help slartibartfast", 1)
246
out = backtick("bzr help ci")
247
out.index('aliases: ')
249
progress("can't rename unversioned file")
250
runcmd("bzr rename test.txt new-test.txt", 1)
252
progress("adding a file")
254
runcmd("bzr add test.txt")
255
assert backtick("bzr unknowns") == ''
256
assert backtick("bzr status --all") == ("added:\n"
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")
264
assert backtick("bzr revno") == '0\n'
266
progress("add first revision")
267
runcmd(["bzr", "commit", "-m", 'add first revision'])
269
progress("more complex renames")
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)
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"
280
assert exists("sub2")
281
assert exists("sub2/hello.txt")
282
assert not exists("sub1")
283
assert not exists("hello.txt")
285
runcmd(['bzr', 'commit', '-m', 'commit with some things moved to subdirs'])
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')
296
runcmd(['bzr', 'commit', '-m', 'rename nested subdirectories'])
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'])
306
assert backtick('bzr relpath sub2/hello.txt') == 'sub1/sub2/hello.txt\n'
308
runcmd('bzr move sub2/hello.txt .')
309
assert exists('hello.txt')
311
f = file('hello.txt', 'wt')
312
f.write('some nice new content\n')
315
f = file('msg.tmp', 'wt')
316
f.write('this is my new commit\n')
319
runcmd('bzr commit -F msg.tmp')
321
assert backtick('bzr revno') == '5\n'
322
runcmd('bzr export -r 5 export-5.tmp')
323
runcmd('bzr export export.tmp')
331
progress('ignore patterns')
332
mkdir('ignorebranch')
335
assert backtick('bzr unknowns') == ''
337
file('foo.tmp', 'wt').write('tmp files are ignored')
338
assert backtick('bzr unknowns') == ''
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') == ''
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'
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'
359
progress("all tests passed!")
361
sys.stderr.write('*' * 50 + '\n'
362
+ 'testbzr: tests failed\n'
363
+ 'see ' + LOGFILENAME + ' for more information\n'
365
logfile.write('tests failed!\n')
366
traceback.print_exc(None, logfile)