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)
139
start_dir = os.getcwd()
142
logfile = open(LOGFILENAME, 'wt', buffering=1)
146
from getopt import getopt
147
opts, args = getopt(sys.argv[1:], 'p:')
149
for option, value in opts:
151
OVERRIDE_PYTHON = value
154
mypath = os.path.abspath(sys.argv[0])
155
print '%-30s %s' % ('running tests from', mypath)
162
BZRPATH = os.path.join(os.path.split(mypath)[0], 'bzr')
164
print '%-30s %s' % ('against bzr', BZRPATH)
165
print '%-30s %s' % ('in directory', os.getcwd())
166
print '%-30s %s' % ('with python', (OVERRIDE_PYTHON or '(default)'))
168
print backtick([BZRPATH, 'version'])
170
runcmd(['mkdir', TESTDIR])
172
test_root = os.getcwd()
174
progress("introductory commands")
175
runcmd("bzr version")
176
runcmd("bzr --version")
180
progress("internal tests")
181
runcmd("bzr selftest")
183
progress("user identity")
184
# this should always identify something, if only "john@localhost"
186
runcmd("bzr whoami --email")
187
assert backtick("bzr whoami --email").count('@') == 1
189
progress("invalid commands")
190
runcmd("bzr pants", retcode=1)
191
runcmd("bzr --pants off", retcode=1)
192
runcmd("bzr diff --message foo", retcode=1)
194
progress("basic branch creation")
195
runcmd(['mkdir', 'branch1'])
199
assert backtick('bzr root')[:-1] == os.path.join(test_root, 'branch1')
201
progress("status of new file")
203
f = file('test.txt', 'wt')
204
f.write('hello world!\n')
207
out = backtick("bzr unknowns")
208
assert out == 'test.txt\n'
210
out = backtick("bzr status")
211
assert out == 'unknown:\n test.txt\n'
213
out = backtick("bzr status --all")
214
assert out == "unknown:\n test.txt\n"
216
out = backtick("bzr status test.txt --all")
217
assert out == "unknown:\n test.txt\n"
219
f = file('test2.txt', 'wt')
220
f.write('goodbye cruel world...\n')
223
out = backtick("bzr status test.txt")
224
assert out == "unknown:\n test.txt\n"
226
out = backtick("bzr status")
227
assert out == ("unknown:\n"
231
os.unlink('test2.txt')
233
progress("command aliases")
234
out = backtick("bzr st --all")
235
assert out == ("unknown:\n"
238
out = backtick("bzr stat")
239
assert out == ("unknown:\n"
242
progress("command help")
243
runcmd("bzr help st")
245
runcmd("bzr help commands")
246
runcmd("bzr help slartibartfast", 1)
248
out = backtick("bzr help ci")
249
out.index('aliases: ')
251
progress("can't rename unversioned file")
252
runcmd("bzr rename test.txt new-test.txt", 1)
254
progress("adding a file")
256
runcmd("bzr add test.txt")
257
assert backtick("bzr unknowns") == ''
258
assert backtick("bzr status --all") == ("added:\n"
261
progress("rename newly-added file")
262
runcmd("bzr rename test.txt hello.txt")
263
assert os.path.exists("hello.txt")
264
assert not os.path.exists("test.txt")
266
assert backtick("bzr revno") == '0\n'
268
progress("add first revision")
269
runcmd(["bzr", "commit", "-m", 'add first revision'])
271
progress("more complex renames")
273
runcmd("bzr rename hello.txt sub1", 1)
274
runcmd("bzr rename hello.txt sub1/hello.txt", 1)
275
runcmd("bzr move hello.txt sub1", 1)
277
runcmd("bzr add sub1")
278
runcmd("bzr rename sub1 sub2")
279
runcmd("bzr move hello.txt sub2")
280
assert backtick("bzr relpath sub2/hello.txt") == "sub2/hello.txt\n"
282
assert exists("sub2")
283
assert exists("sub2/hello.txt")
284
assert not exists("sub1")
285
assert not exists("hello.txt")
287
runcmd(['bzr', 'commit', '-m', 'commit with some things moved to subdirs'])
290
runcmd('bzr add sub1')
291
runcmd('bzr move sub2/hello.txt sub1')
292
assert not exists('sub2/hello.txt')
293
assert exists('sub1/hello.txt')
294
runcmd('bzr move sub2 sub1')
295
assert not exists('sub2')
296
assert exists('sub1/sub2')
298
runcmd(['bzr', 'commit', '-m', 'rename nested subdirectories'])
301
assert backtick('bzr root')[:-1] == os.path.join(test_root, 'branch1')
302
runcmd('bzr move ../hello.txt .')
303
assert exists('./hello.txt')
304
assert backtick('bzr relpath hello.txt') == 'sub1/sub2/hello.txt\n'
305
assert backtick('bzr relpath ../../sub1/sub2/hello.txt') == 'sub1/sub2/hello.txt\n'
306
runcmd(['bzr', 'commit', '-m', 'move to parent directory'])
308
assert backtick('bzr relpath sub2/hello.txt') == 'sub1/sub2/hello.txt\n'
310
runcmd('bzr move sub2/hello.txt .')
311
assert exists('hello.txt')
313
f = file('hello.txt', 'wt')
314
f.write('some nice new content\n')
317
f = file('msg.tmp', 'wt')
318
f.write('this is my new commit\n')
321
runcmd('bzr commit -F msg.tmp')
323
assert backtick('bzr revno') == '5\n'
324
runcmd('bzr export -r 5 export-5.tmp')
325
runcmd('bzr export export.tmp')
332
progress("file with spaces in name")
333
mkdir('sub directory')
334
file('sub directory/file with spaces ', 'wt').write('see how this works\n')
337
runcmd('bzr commit -m add-spaces')
341
runcmd('bzr log --forward')
349
progress('ignore patterns')
350
mkdir('ignorebranch')
353
assert backtick('bzr unknowns') == ''
355
file('foo.tmp', 'wt').write('tmp files are ignored')
356
assert backtick('bzr unknowns') == ''
358
file('foo.c', 'wt').write('int main() {}')
359
assert backtick('bzr unknowns') == 'foo.c\n'
360
runcmd('bzr add foo.c')
361
assert backtick('bzr unknowns') == ''
363
# 'ignore' works when creating the .bzignore file
364
file('foo.blah', 'wt').write('blah')
365
assert backtick('bzr unknowns') == 'foo.blah\n'
366
runcmd('bzr ignore *.blah')
367
assert backtick('bzr unknowns') == ''
368
assert file('.bzrignore', 'rb').read() == '*.blah\n'
370
# 'ignore' works when then .bzrignore file already exists
371
file('garh', 'wt').write('garh')
372
assert backtick('bzr unknowns') == 'garh\n'
373
runcmd('bzr ignore garh')
374
assert backtick('bzr unknowns') == ''
375
assert file('.bzrignore', 'rb').read() == '*.blah\ngarh\n'
379
progress("all tests passed!")
381
sys.stderr.write('*' * 50 + '\n'
382
+ 'testbzr: tests failed\n'
383
+ 'see ' + LOGFILENAME + ' for more information\n'
385
logfile.write('tests failed!\n')
386
traceback.print_exc(None, logfile)
389
sys.stdout.writelines(file(os.path.join(start_dir, LOGFILENAME), 'rt').readlines()[-50:])