3
# Copyright (C) 2005 Canonical Ltd
5
# This program is free software; you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 2 of the License, or
8
# (at your option) any later version.
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
15
# You should have received a copy of the GNU General Public License
16
# along with this program; if not, write to the Free Software
17
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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.
25
This replaces the previous test.sh which was not very portable."""
27
import sys, os, traceback
29
from os.path import exists
31
TESTDIR = "testbzr.tmp"
33
LOGFILENAME = 'testbzr.log'
37
from subprocess import call, Popen, PIPE
38
except ImportError, e:
39
sys.stderr.write("testbzr: sorry, this test suite requires modules from python2.4\n"
44
class CommandFailed(Exception):
49
if isinstance(cmd, basestring):
50
logfile.write('$ %s\n' % cmd)
53
logfile.write('$ %r\n' % cmd)
61
def runcmd(cmd, retcode=0):
62
"""Run one command and check the return code.
64
Returns a tuple of (stdout,stderr) strings.
66
If a single string is based, it is split into words.
67
For commands that are not simple space-separated words, please
68
pass a list instead."""
72
actual_retcode = call(cmd, stdout=logfile, stderr=logfile)
74
if retcode != actual_retcode:
75
raise CommandFailed("test failed: %r returned %d, expected %d"
76
% (cmd, actual_retcode, retcode))
80
def backtick(cmd, retcode=0):
83
child = Popen(cmd, stdout=PIPE, stderr=logfile)
84
outd, errd = child.communicate()
86
actual_retcode = child.wait()
88
outd = outd.replace('\r', '')
90
if retcode != actual_retcode:
91
raise CommandFailed("test failed: %r returned %d, expected %d"
92
% (cmd, actual_retcode, retcode))
100
logfile.write('* '+ msg + '\n')
105
logfile.write('$ cd %s\n' % dirname)
110
def log_linenumber():
111
"""Log the stack frame location two things up."""
112
stack = traceback.extract_stack()[-3]
113
logfile.write(' at %s:%d\n' % stack[:2])
117
# prepare an empty scratch directory
118
if os.path.exists(TESTDIR):
119
shutil.rmtree(TESTDIR)
122
logfile = open(LOGFILENAME, 'wt', buffering=1)
126
mypath = os.path.abspath(sys.argv[0])
127
print '%-30s %s' % ('running tests from', mypath)
131
if len(sys.argv) > 1:
132
BZRPATH = sys.argv[1]
134
BZRPATH = os.path.join(os.path.split(mypath)[0], 'bzr')
136
print '%-30s %s' % ('against bzr', BZRPATH)
137
print '%-30s %s' % ('in directory', os.getcwd())
139
print backtick([BZRPATH, 'version'])
141
runcmd(['mkdir', TESTDIR])
143
test_root = os.getcwd()
145
progress("introductory commands")
146
runcmd("bzr version")
147
runcmd("bzr --version")
151
progress("internal tests")
152
runcmd("bzr selftest")
154
progress("user identity")
155
# this should always identify something, if only "john@localhost"
157
runcmd("bzr whoami --email")
158
assert backtick("bzr whoami --email").count('@') == 1
160
progress("invalid commands")
161
runcmd("bzr pants", retcode=1)
162
runcmd("bzr --pants off", retcode=1)
163
runcmd("bzr diff --message foo", retcode=1)
165
progress("basic branch creation")
166
runcmd(['mkdir', 'branch1'])
170
assert backtick('bzr root')[:-1] == os.path.join(test_root, 'branch1')
172
progress("status of new file")
174
f = file('test.txt', 'wt')
175
f.write('hello world!\n')
178
out = backtick("bzr unknowns")
179
assert out == 'test.txt\n'
181
out = backtick("bzr status")
182
assert out == 'unknown:\n test.txt\n'
184
out = backtick("bzr status --all")
185
assert out == "unknown:\n test.txt\n"
187
out = backtick("bzr status test.txt --all")
188
assert out == "unknown:\n test.txt\n"
190
f = file('test2.txt', 'wt')
191
f.write('goodbye cruel world...\n')
194
out = backtick("bzr status test.txt")
195
assert out == "unknown:\n test.txt\n"
197
out = backtick("bzr status")
198
assert out == ("unknown:\n"
202
os.unlink('test2.txt')
204
progress("command aliases")
205
out = backtick("bzr st --all")
206
assert out == ("unknown:\n"
209
out = backtick("bzr stat")
210
assert out == ("unknown:\n"
213
progress("command help")
214
runcmd("bzr help st")
216
runcmd("bzr help commands")
217
runcmd("bzr help slartibartfast", 1)
219
out = backtick("bzr help ci")
220
out.index('aliases: ')
222
progress("can't rename unversioned file")
223
runcmd("bzr rename test.txt new-test.txt", 1)
225
progress("adding a file")
227
runcmd("bzr add test.txt")
228
assert backtick("bzr unknowns") == ''
229
assert backtick("bzr status --all") == ("added:\n"
232
progress("rename newly-added file")
233
runcmd("bzr rename test.txt hello.txt")
234
assert os.path.exists("hello.txt")
235
assert not os.path.exists("test.txt")
237
assert backtick("bzr revno") == '0\n'
239
progress("add first revision")
240
runcmd(["bzr", "commit", "-m", 'add first revision'])
242
progress("more complex renames")
244
runcmd("bzr rename hello.txt sub1", 1)
245
runcmd("bzr rename hello.txt sub1/hello.txt", 1)
246
runcmd("bzr move hello.txt sub1", 1)
248
runcmd("bzr add sub1")
249
runcmd("bzr rename sub1 sub2")
250
runcmd("bzr move hello.txt sub2")
251
assert backtick("bzr relpath sub2/hello.txt") == "sub2/hello.txt\n"
253
assert exists("sub2")
254
assert exists("sub2/hello.txt")
255
assert not exists("sub1")
256
assert not exists("hello.txt")
258
runcmd(['bzr', 'commit', '-m', 'commit with some things moved to subdirs'])
261
runcmd('bzr add sub1')
262
runcmd('bzr move sub2/hello.txt sub1')
263
assert not exists('sub2/hello.txt')
264
assert exists('sub1/hello.txt')
265
runcmd('bzr move sub2 sub1')
266
assert not exists('sub2')
267
assert exists('sub1/sub2')
269
runcmd(['bzr', 'commit', '-m', 'rename nested subdirectories'])
272
assert backtick('bzr root')[:-1] == os.path.join(test_root, 'branch1')
273
runcmd('bzr move ../hello.txt .')
274
assert exists('./hello.txt')
275
assert backtick('bzr relpath hello.txt') == 'sub1/sub2/hello.txt\n'
276
assert backtick('bzr relpath ../../sub1/sub2/hello.txt') == 'sub1/sub2/hello.txt\n'
277
runcmd(['bzr', 'commit', '-m', 'move to parent directory'])
279
assert backtick('bzr relpath sub2/hello.txt') == 'sub1/sub2/hello.txt\n'
281
runcmd('bzr move sub2/hello.txt .')
282
assert exists('hello.txt')
284
f = file('hello.txt', 'wt')
285
f.write('some nice new content\n')
288
f = file('msg.tmp', 'wt')
289
f.write('this is my new commit\n')
292
runcmd('bzr commit -F msg.tmp')
294
assert backtick('bzr revno') == '5\n'
295
runcmd('bzr export -r 5 export-5.tmp')
296
runcmd('bzr export export.tmp')
304
progress('ignore patterns')
305
mkdir('ignorebranch')
308
assert backtick('bzr unknowns') == ''
310
file('foo.tmp', 'wt').write('tmp files are ignored')
311
assert backtick('bzr unknowns') == ''
313
file('foo.c', 'wt').write('int main() {}')
314
assert backtick('bzr unknowns') == 'foo.c\n'
315
runcmd('bzr add foo.c')
316
assert backtick('bzr unknowns') == ''
318
file('foo.blah', 'wt').write('blah')
319
assert backtick('bzr unknowns') == 'foo.blah\n'
320
runcmd('bzr ignore *.blah')
321
assert backtick('bzr unknowns') == ''
322
assert file('.bzrignore', 'rt').read() == '*.blah\n'
325
progress("all tests passed!")
327
sys.stderr.write('*' * 50 + '\n'
328
+ 'testbzr: tests failed\n'
329
+ 'see ' + LOGFILENAME + ' for more information\n'
331
logfile.write('tests failed!\n')
332
traceback.print_exc(None, logfile)