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)