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])
144
progress("introductory commands")
145
runcmd("bzr version")
146
runcmd("bzr --version")
150
progress("internal tests")
151
runcmd("bzr selftest")
153
progress("user identity")
154
# this should always identify something, if only "john@localhost"
156
runcmd("bzr whoami --email")
157
assert backtick("bzr whoami --email").count('@') == 1
159
progress("invalid commands")
160
runcmd("bzr pants", retcode=1)
161
runcmd("bzr --pants off", retcode=1)
162
runcmd("bzr diff --message foo", retcode=1)
164
progress("basic branch creation")
165
runcmd(['mkdir', 'branch1'])
169
progress("status of new file")
171
f = file('test.txt', 'wt')
172
f.write('hello world!\n')
175
out = backtick("bzr unknowns")
176
assert out == 'test.txt\n'
178
out = backtick("bzr status")
179
assert out == '''? test.txt\n'''
181
out = backtick("bzr status --all")
182
assert out == "? test.txt\n"
184
out = backtick("bzr status test.txt --all")
185
assert out == "? test.txt\n"
187
f = file('test2.txt', 'wt')
188
f.write('goodbye cruel world...\n')
191
out = backtick("bzr status test.txt")
192
assert out == "? test.txt\n"
194
out = backtick("bzr status")
195
assert out == "? test.txt\n" \
198
os.unlink('test2.txt')
200
progress("command aliases")
201
out = backtick("bzr st --all")
202
assert out == "? test.txt\n"
203
out = backtick("bzr stat")
204
assert out == "? test.txt\n"
206
progress("command help")
207
runcmd("bzr help st")
209
runcmd("bzr help commands")
210
runcmd("bzr help slartibartfast", 1)
212
out = backtick("bzr help ci")
213
out.index('aliases: ')
215
progress("can't rename unversioned file")
216
runcmd("bzr rename test.txt new-test.txt", 1)
218
progress("adding a file")
220
runcmd("bzr add test.txt")
221
assert backtick("bzr unknowns") == ''
222
assert backtick("bzr status --all") == "A test.txt\n"
224
progress("rename newly-added file")
225
runcmd("bzr rename test.txt hello.txt")
226
assert os.path.exists("hello.txt")
227
assert not os.path.exists("test.txt")
229
assert backtick("bzr revno") == '0\n'
231
progress("add first revision")
232
runcmd(["bzr", "commit", "-m", 'add first revision'])
234
progress("more complex renames")
236
runcmd("bzr rename hello.txt sub1", 1)
237
runcmd("bzr rename hello.txt sub1/hello.txt", 1)
238
runcmd("bzr move hello.txt sub1", 1)
240
runcmd("bzr add sub1")
241
runcmd("bzr rename sub1 sub2")
242
runcmd("bzr move hello.txt sub2")
243
assert backtick("bzr relpath sub2/hello.txt") == "sub2/hello.txt\n"
245
assert exists("sub2")
246
assert exists("sub2/hello.txt")
247
assert not exists("sub1")
248
assert not exists("hello.txt")
250
runcmd(['bzr', 'commit', '-m', 'commit with some things moved to subdirs'])
253
runcmd('bzr add sub1')
254
runcmd('bzr move sub2/hello.txt sub1')
255
assert not exists('sub2/hello.txt')
256
assert exists('sub1/hello.txt')
257
runcmd('bzr move sub2 sub1')
258
assert not exists('sub2')
259
assert exists('sub1/sub2')
261
runcmd(['bzr', 'commit', '-m', 'rename nested subdirectories'])
264
runcmd('bzr move ../hello.txt .')
265
assert exists('./hello.txt')
266
assert backtick('bzr relpath hello.txt') == 'sub1/sub2/hello.txt\n'
267
assert backtick('bzr relpath ../../sub1/sub2/hello.txt') == 'sub1/sub2/hello.txt\n'
268
runcmd(['bzr', 'commit', '-m', 'move to parent directory'])
270
assert backtick('bzr relpath sub2/hello.txt') == 'sub1/sub2/hello.txt\n'
272
runcmd('bzr move sub2/hello.txt .')
273
assert exists('hello.txt')
275
f = file('hello.txt', 'wt')
276
f.write('some nice new content\n')
279
f = file('msg.tmp', 'wt')
280
f.write('this is my new commit\n')
283
runcmd('bzr commit -F msg.tmp')
285
assert backtick('bzr revno') == '5\n'
286
runcmd('bzr export -r 5 export-5.tmp')
287
runcmd('bzr export export.tmp')
292
progress('ignore patterns')
293
mkdir('ignorebranch')
296
assert backtick('bzr unknowns') == ''
298
file('foo.tmp', 'wt').write('tmp files are ignored')
299
assert backtick('bzr unknowns') == ''
301
file('foo.c', 'wt').write('int main() {}')
302
assert backtick('bzr unknowns') == 'foo.c\n'
303
runcmd('bzr add foo.c')
304
assert backtick('bzr unknowns') == ''
306
file('foo.blah', 'wt').write('blah')
307
assert backtick('bzr unknowns') == 'foo.blah\n'
308
runcmd('bzr ignore *.blah')
309
assert backtick('bzr unknowns') == ''
310
assert file('.bzrignore', 'rt').read() == '*.blah\n'
313
progress("all tests passed!")
315
sys.stderr.write('*' * 50 + '\n'
316
+ 'testbzr: tests failed\n'
317
+ 'see ' + LOGFILENAME + ' for more information\n'
319
logfile.write('tests failed!\n')
320
traceback.print_exc(None, logfile)