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)
58
def runcmd(cmd, retcode=0):
59
"""Run one command and check the return code.
61
Returns a tuple of (stdout,stderr) strings.
63
If a single string is based, it is split into words.
64
For commands that are not simple space-separated words, please
65
pass a list instead."""
69
actual_retcode = call(cmd, stdout=logfile, stderr=logfile)
71
if retcode != actual_retcode:
72
raise CommandFailed("test failed: %r returned %d, expected %d"
73
% (cmd, actual_retcode, retcode))
77
def backtick(cmd, retcode=0):
80
child = Popen(cmd, stdout=PIPE, stderr=logfile)
81
outd, errd = child.communicate()
83
actual_retcode = child.wait()
85
outd = outd.replace('\r', '')
87
if retcode != actual_retcode:
88
raise CommandFailed("test failed: %r returned %d, expected %d"
89
% (cmd, actual_retcode, retcode))
97
logfile.write('* '+ msg + '\n')
102
logfile.write('$ cd %s\n' % dirname)
107
def log_linenumber():
108
"""Log the stack frame location two things up."""
109
stack = traceback.extract_stack()[-3]
110
logfile.write(' at %s:%d\n' % stack[:2])
114
# prepare an empty scratch directory
115
if os.path.exists(TESTDIR):
116
shutil.rmtree(TESTDIR)
119
logfile = open(LOGFILENAME, 'wt', buffering=1)
123
runcmd(['mkdir', TESTDIR])
126
progress("introductory commands")
127
runcmd("bzr version")
128
runcmd("bzr --version")
132
progress("user identity")
133
# this should always identify something, if only "john@localhost"
135
runcmd("bzr whoami --email")
136
assert backtick("bzr whoami --email").count('@') == 1
138
progress("invalid commands")
139
runcmd("bzr pants", retcode=1)
140
runcmd("bzr --pants off", retcode=1)
141
runcmd("bzr diff --message foo", retcode=1)
143
progress("basic branch creation")
144
runcmd(['mkdir', 'branch1'])
148
progress("status of new file")
150
f = file('test.txt', 'wt')
151
f.write('hello world!\n')
154
out = backtick("bzr unknowns")
155
assert out == 'test.txt\n'
157
out = backtick("bzr status")
158
assert out == '''? test.txt\n'''
160
out = backtick("bzr status --all")
161
assert out == "? test.txt\n"
163
progress("command aliases")
164
out = backtick("bzr st --all")
165
assert out == "? test.txt\n"
166
out = backtick("bzr stat")
167
assert out == "? test.txt\n"
169
progress("command help")
170
runcmd("bzr help st")
172
runcmd("bzr help commands")
173
runcmd("bzr help slartibartfast", 1)
175
out = backtick("bzr help ci")
176
out.index('aliases: ')
178
progress("can't rename unversioned file")
179
runcmd("bzr rename test.txt new-test.txt", 1)
181
progress("adding a file")
183
runcmd("bzr add test.txt")
184
assert backtick("bzr unknowns") == ''
185
assert backtick("bzr status --all") == "A test.txt\n"
187
progress("rename newly-added file")
188
runcmd("bzr rename test.txt hello.txt")
189
assert os.path.exists("hello.txt")
190
assert not os.path.exists("test.txt")
192
assert backtick("bzr revno") == '0\n'
194
progress("add first revision")
195
runcmd(["bzr", "commit", "-m", 'add first revision'])
197
progress("more complex renames")
199
runcmd("bzr rename hello.txt sub1", 1)
200
runcmd("bzr rename hello.txt sub1/hello.txt", 1)
201
runcmd("bzr move hello.txt sub1", 1)
203
runcmd("bzr add sub1")
204
runcmd("bzr rename sub1 sub2")
205
runcmd("bzr move hello.txt sub2")
206
assert backtick("bzr relpath sub2/hello.txt") == "sub2/hello.txt\n"
208
assert exists("sub2")
209
assert exists("sub2/hello.txt")
210
assert not exists("sub1")
211
assert not exists("hello.txt")
213
runcmd(['bzr', 'commit', '-m', 'commit with some things moved to subdirs'])
216
runcmd('bzr add sub1')
217
runcmd('bzr move sub2/hello.txt sub1')
218
assert not exists('sub2/hello.txt')
219
assert exists('sub1/hello.txt')
220
runcmd('bzr move sub2 sub1')
221
assert not exists('sub2')
222
assert exists('sub1/sub2')
224
runcmd(['bzr', 'commit', '-m', 'rename nested subdirectories'])
227
runcmd('bzr move ../hello.txt .')
228
assert exists('./hello.txt')
229
assert backtick('bzr relpath hello.txt') == 'sub1/sub2/hello.txt\n'
230
assert backtick('bzr relpath ../../sub1/sub2/hello.txt') == 'sub1/sub2/hello.txt\n'
231
runcmd(['bzr', 'commit', '-m', 'move to parent directory'])
233
assert backtick('bzr relpath sub2/hello.txt') == 'sub1/sub2/hello.txt\n'
235
runcmd('bzr move sub2/hello.txt .')
236
assert exists('hello.txt')
238
f = file('hello.txt', 'wt')
239
f.write('some nice new content\n')
242
f = file('msg.tmp', 'wt')
243
f.write('this is my new commit\n')
246
runcmd('bzr commit -F msg.tmp')
248
assert backtick('bzr revno') == '5\n'
249
runcmd('bzr export -r 5 export-5.tmp')
250
runcmd('bzr export export.tmp')
254
progress("all tests passed!")
256
sys.stderr.write('*' * 50 + '\n'
257
+ 'testbzr: tests failed\n'
258
+ 'see ' + LOGFILENAME + ' for more information\n'
260
logfile.write('tests failed!\n')
261
traceback.print_exc(None, logfile)