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 == "? test.txt\n"
207
out = backtick("bzr stat")
208
assert out == "? test.txt\n"
210
progress("command help")
211
runcmd("bzr help st")
213
runcmd("bzr help commands")
214
runcmd("bzr help slartibartfast", 1)
216
out = backtick("bzr help ci")
217
out.index('aliases: ')
219
progress("can't rename unversioned file")
220
runcmd("bzr rename test.txt new-test.txt", 1)
222
progress("adding a file")
224
runcmd("bzr add test.txt")
225
assert backtick("bzr unknowns") == ''
226
assert backtick("bzr status --all") == "A test.txt\n"
228
progress("rename newly-added file")
229
runcmd("bzr rename test.txt hello.txt")
230
assert os.path.exists("hello.txt")
231
assert not os.path.exists("test.txt")
233
assert backtick("bzr revno") == '0\n'
235
progress("add first revision")
236
runcmd(["bzr", "commit", "-m", 'add first revision'])
238
progress("more complex renames")
240
runcmd("bzr rename hello.txt sub1", 1)
241
runcmd("bzr rename hello.txt sub1/hello.txt", 1)
242
runcmd("bzr move hello.txt sub1", 1)
244
runcmd("bzr add sub1")
245
runcmd("bzr rename sub1 sub2")
246
runcmd("bzr move hello.txt sub2")
247
assert backtick("bzr relpath sub2/hello.txt") == "sub2/hello.txt\n"
249
assert exists("sub2")
250
assert exists("sub2/hello.txt")
251
assert not exists("sub1")
252
assert not exists("hello.txt")
254
runcmd(['bzr', 'commit', '-m', 'commit with some things moved to subdirs'])
257
runcmd('bzr add sub1')
258
runcmd('bzr move sub2/hello.txt sub1')
259
assert not exists('sub2/hello.txt')
260
assert exists('sub1/hello.txt')
261
runcmd('bzr move sub2 sub1')
262
assert not exists('sub2')
263
assert exists('sub1/sub2')
265
runcmd(['bzr', 'commit', '-m', 'rename nested subdirectories'])
268
assert backtick('bzr root')[:-1] == os.path.join(test_root, 'branch1')
269
runcmd('bzr move ../hello.txt .')
270
assert exists('./hello.txt')
271
assert backtick('bzr relpath hello.txt') == 'sub1/sub2/hello.txt\n'
272
assert backtick('bzr relpath ../../sub1/sub2/hello.txt') == 'sub1/sub2/hello.txt\n'
273
runcmd(['bzr', 'commit', '-m', 'move to parent directory'])
275
assert backtick('bzr relpath sub2/hello.txt') == 'sub1/sub2/hello.txt\n'
277
runcmd('bzr move sub2/hello.txt .')
278
assert exists('hello.txt')
280
f = file('hello.txt', 'wt')
281
f.write('some nice new content\n')
284
f = file('msg.tmp', 'wt')
285
f.write('this is my new commit\n')
288
runcmd('bzr commit -F msg.tmp')
290
assert backtick('bzr revno') == '5\n'
291
runcmd('bzr export -r 5 export-5.tmp')
292
runcmd('bzr export export.tmp')
300
progress('ignore patterns')
301
mkdir('ignorebranch')
304
assert backtick('bzr unknowns') == ''
306
file('foo.tmp', 'wt').write('tmp files are ignored')
307
assert backtick('bzr unknowns') == ''
309
file('foo.c', 'wt').write('int main() {}')
310
assert backtick('bzr unknowns') == 'foo.c\n'
311
runcmd('bzr add foo.c')
312
assert backtick('bzr unknowns') == ''
314
file('foo.blah', 'wt').write('blah')
315
assert backtick('bzr unknowns') == 'foo.blah\n'
316
runcmd('bzr ignore *.blah')
317
assert backtick('bzr unknowns') == ''
318
assert file('.bzrignore', 'rt').read() == '*.blah\n'
321
progress("all tests passed!")
323
sys.stderr.write('*' * 50 + '\n'
324
+ 'testbzr: tests failed\n'
325
+ 'see ' + LOGFILENAME + ' for more information\n'
327
logfile.write('tests failed!\n')
328
traceback.print_exc(None, logfile)