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 == '''? test.txt\n'''
184
out = backtick("bzr status --all")
185
assert out == "? test.txt\n"
187
out = backtick("bzr status test.txt --all")
188
assert out == "? 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 == "? test.txt\n"
197
out = backtick("bzr status")
198
assert out == "? test.txt\n" \
201
os.unlink('test2.txt')
203
progress("command aliases")
204
out = backtick("bzr st --all")
205
assert out == "? test.txt\n"
206
out = backtick("bzr stat")
207
assert out == "? test.txt\n"
209
progress("command help")
210
runcmd("bzr help st")
212
runcmd("bzr help commands")
213
runcmd("bzr help slartibartfast", 1)
215
out = backtick("bzr help ci")
216
out.index('aliases: ')
218
progress("can't rename unversioned file")
219
runcmd("bzr rename test.txt new-test.txt", 1)
221
progress("adding a file")
223
runcmd("bzr add test.txt")
224
assert backtick("bzr unknowns") == ''
225
assert backtick("bzr status --all") == "A test.txt\n"
227
progress("rename newly-added file")
228
runcmd("bzr rename test.txt hello.txt")
229
assert os.path.exists("hello.txt")
230
assert not os.path.exists("test.txt")
232
assert backtick("bzr revno") == '0\n'
234
progress("add first revision")
235
runcmd(["bzr", "commit", "-m", 'add first revision'])
237
progress("more complex renames")
239
runcmd("bzr rename hello.txt sub1", 1)
240
runcmd("bzr rename hello.txt sub1/hello.txt", 1)
241
runcmd("bzr move hello.txt sub1", 1)
243
runcmd("bzr add sub1")
244
runcmd("bzr rename sub1 sub2")
245
runcmd("bzr move hello.txt sub2")
246
assert backtick("bzr relpath sub2/hello.txt") == "sub2/hello.txt\n"
248
assert exists("sub2")
249
assert exists("sub2/hello.txt")
250
assert not exists("sub1")
251
assert not exists("hello.txt")
253
runcmd(['bzr', 'commit', '-m', 'commit with some things moved to subdirs'])
256
runcmd('bzr add sub1')
257
runcmd('bzr move sub2/hello.txt sub1')
258
assert not exists('sub2/hello.txt')
259
assert exists('sub1/hello.txt')
260
runcmd('bzr move sub2 sub1')
261
assert not exists('sub2')
262
assert exists('sub1/sub2')
264
runcmd(['bzr', 'commit', '-m', 'rename nested subdirectories'])
267
assert backtick('bzr root')[:-1] == os.path.join(test_root, 'branch1')
268
runcmd('bzr move ../hello.txt .')
269
assert exists('./hello.txt')
270
assert backtick('bzr relpath hello.txt') == 'sub1/sub2/hello.txt\n'
271
assert backtick('bzr relpath ../../sub1/sub2/hello.txt') == 'sub1/sub2/hello.txt\n'
272
runcmd(['bzr', 'commit', '-m', 'move to parent directory'])
274
assert backtick('bzr relpath sub2/hello.txt') == 'sub1/sub2/hello.txt\n'
276
runcmd('bzr move sub2/hello.txt .')
277
assert exists('hello.txt')
279
f = file('hello.txt', 'wt')
280
f.write('some nice new content\n')
283
f = file('msg.tmp', 'wt')
284
f.write('this is my new commit\n')
287
runcmd('bzr commit -F msg.tmp')
289
assert backtick('bzr revno') == '5\n'
290
runcmd('bzr export -r 5 export-5.tmp')
291
runcmd('bzr export export.tmp')
299
progress('ignore patterns')
300
mkdir('ignorebranch')
303
assert backtick('bzr unknowns') == ''
305
file('foo.tmp', 'wt').write('tmp files are ignored')
306
assert backtick('bzr unknowns') == ''
308
file('foo.c', 'wt').write('int main() {}')
309
assert backtick('bzr unknowns') == 'foo.c\n'
310
runcmd('bzr add foo.c')
311
assert backtick('bzr unknowns') == ''
313
file('foo.blah', 'wt').write('blah')
314
assert backtick('bzr unknowns') == 'foo.blah\n'
315
runcmd('bzr ignore *.blah')
316
assert backtick('bzr unknowns') == ''
317
assert file('.bzrignore', 'rt').read() == '*.blah\n'
320
progress("all tests passed!")
322
sys.stderr.write('*' * 50 + '\n'
323
+ 'testbzr: tests failed\n'
324
+ 'see ' + LOGFILENAME + ' for more information\n'
326
logfile.write('tests failed!\n')
327
traceback.print_exc(None, logfile)