~bzr-pqm/bzr/bzr.dev

292 by Martin Pool
- start adding a pure-python blackbox test suite
1
#! /usr/bin/python
2
3
# Copyright (C) 2005 Canonical Ltd
4
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.
9
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.
14
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
18
19
20
"""External black-box test for bzr.
21
22
This always runs bzr as an external process to try to catch bugs
23
related to argument processing, startup, etc.
24
25
This replaces the previous test.sh which was not very portable."""
26
296 by Martin Pool
- better reports from testbzr when it fails
27
import sys, os, traceback
292 by Martin Pool
- start adding a pure-python blackbox test suite
28
29
try:
30
    import shutil
301 by Martin Pool
- provide for catching output from shell commands
31
    from subprocess import call, Popen, PIPE
292 by Martin Pool
- start adding a pure-python blackbox test suite
32
except ImportError, e:
33
    sys.stderr.write("testbzr: sorry, this test suite requires modules from python2.4\n"
34
                     + '    ' + str(e))
35
    sys.exit(1)
36
37
296 by Martin Pool
- better reports from testbzr when it fails
38
class CommandFailed(Exception):
39
    pass
40
41
302 by Martin Pool
testbzr: new backtick() helper
42
def formcmd(cmd):
43
    if isinstance(cmd, basestring):
44
        logfile.write('$ %s\n' % cmd)
45
        cmd = cmd.split()
46
    else:
47
        logfile.write('$ %r\n' % cmd)
48
49
    return cmd
50
51
52
def runcmd(cmd, retcode=0):
300 by Martin Pool
- more tests
53
    """Run one command and check the return code.
292 by Martin Pool
- start adding a pure-python blackbox test suite
54
301 by Martin Pool
- provide for catching output from shell commands
55
    Returns a tuple of (stdout,stderr) strings.
56
292 by Martin Pool
- start adding a pure-python blackbox test suite
57
    If a single string is based, it is split into words.
58
    For commands that are not simple space-separated words, please
59
    pass a list instead."""
302 by Martin Pool
testbzr: new backtick() helper
60
    cmd = formcmd(cmd)
61
    log_linenumber()
62
    
63
    actual_retcode = call(cmd, stdout=logfile, stderr=logfile)
64
    
65
    if retcode != actual_retcode:
66
        raise CommandFailed("test failed: %r returned %d, expected %d"
67
                            % (cmd, actual_retcode, retcode))
68
69
70
71
def backtick(cmd, retcode=0):
72
    cmd = formcmd(cmd)
73
    log_linenumber()
74
    child = Popen(cmd, stdout=PIPE, stderr=logfile)
301 by Martin Pool
- provide for catching output from shell commands
75
    outd, errd = child.communicate()
302 by Martin Pool
testbzr: new backtick() helper
76
    logfile.write(outd)
301 by Martin Pool
- provide for catching output from shell commands
77
    actual_retcode = child.wait()
307 by Martin Pool
testbzr: clean up crlf handling
78
79
    outd = outd.replace('\r', '')
301 by Martin Pool
- provide for catching output from shell commands
80
    
298 by Martin Pool
- test some commands known to fail
81
    if retcode != actual_retcode:
82
        raise CommandFailed("test failed: %r returned %d, expected %d"
83
                            % (cmd, actual_retcode, retcode))
292 by Martin Pool
- start adding a pure-python blackbox test suite
84
302 by Martin Pool
testbzr: new backtick() helper
85
    return outd
86
301 by Martin Pool
- provide for catching output from shell commands
87
292 by Martin Pool
- start adding a pure-python blackbox test suite
88
89
def progress(msg):
90
    print '* ' + msg
91
    logfile.write('* '+ msg + '\n')
297 by Martin Pool
- fix intentional testcase failure
92
    log_linenumber()
93
94
299 by Martin Pool
testbzr:
95
def cd(dirname):
96
    logfile.write('$ cd %s\n' % dirname)
97
    os.chdir(dirname)
98
99
300 by Martin Pool
- more tests
100
297 by Martin Pool
- fix intentional testcase failure
101
def log_linenumber():
102
    """Log the stack frame location two things up."""
103
    stack = traceback.extract_stack()[-3]
104
    logfile.write('   at %s:%d\n' % stack[:2])
105
106
107
TESTDIR = "testbzr.tmp"
292 by Martin Pool
- start adding a pure-python blackbox test suite
108
109
# prepare an empty scratch directory
110
if os.path.exists(TESTDIR):
111
    shutil.rmtree(TESTDIR)
112
113
297 by Martin Pool
- fix intentional testcase failure
114
logfile = open('testbzr.log', 'wt', buffering=1)
292 by Martin Pool
- start adding a pure-python blackbox test suite
115
116
300 by Martin Pool
- more tests
117
try:
118
    runcmd(['mkdir', TESTDIR])
299 by Martin Pool
testbzr:
119
    cd(TESTDIR)
296 by Martin Pool
- better reports from testbzr when it fails
120
300 by Martin Pool
- more tests
121
    progress("introductory commands")
296 by Martin Pool
- better reports from testbzr when it fails
122
    runcmd("bzr version")
123
    runcmd("bzr help")
297 by Martin Pool
- fix intentional testcase failure
124
    runcmd("bzr --help")
125
300 by Martin Pool
- more tests
126
    progress("user identity")
297 by Martin Pool
- fix intentional testcase failure
127
    # this should always identify something, if only "john@localhost"
128
    runcmd("bzr whoami")
298 by Martin Pool
- test some commands known to fail
129
    runcmd("bzr whoami --email")
302 by Martin Pool
testbzr: new backtick() helper
130
    assert backtick("bzr whoami --email").count('@') == 1
298 by Martin Pool
- test some commands known to fail
131
300 by Martin Pool
- more tests
132
    progress("invalid commands")
298 by Martin Pool
- test some commands known to fail
133
    runcmd("bzr pants", retcode=1)
134
    runcmd("bzr --pants off", retcode=1)
296 by Martin Pool
- better reports from testbzr when it fails
135
300 by Martin Pool
- more tests
136
    progress("basic branch creation")
137
    runcmd(['mkdir', 'branch1'])
138
    cd('branch1')
139
    runcmd('bzr init')
303 by Martin Pool
- more tests for unknown file
140
141
    progress("status of new file")
300 by Martin Pool
- more tests
142
    
143
    f = file('test.txt', 'wt')
144
    f.write('hello world!\n')
145
    f.close()
146
307 by Martin Pool
testbzr: clean up crlf handling
147
    out = backtick("bzr unknowns")
148
    assert out == 'test.txt\n'
303 by Martin Pool
- more tests for unknown file
149
307 by Martin Pool
testbzr: clean up crlf handling
150
    out = backtick("bzr status")
303 by Martin Pool
- more tests for unknown file
151
    assert out == '''?       test.txt\n'''
152
307 by Martin Pool
testbzr: clean up crlf handling
153
    out = backtick("bzr status --all")
304 by Martin Pool
testbzr: test adding a file
154
    assert out == "?       test.txt\n"
155
305 by Martin Pool
testbzr: test renames
156
    progress("can't rename unversioned file")
157
    runcmd("bzr rename test.txt new-test.txt", 1)
158
304 by Martin Pool
testbzr: test adding a file
159
    progress("adding a file")
160
161
    runcmd("bzr add test.txt")
162
    assert backtick("bzr unknowns") == ''
307 by Martin Pool
testbzr: clean up crlf handling
163
    assert backtick("bzr status --all") == "A       test.txt\n"
300 by Martin Pool
- more tests
164
305 by Martin Pool
testbzr: test renames
165
    progress("rename newly-added file")
166
    runcmd("bzr rename test.txt hello.txt")
306 by Martin Pool
testbzr: test renames
167
    assert os.path.exists("hello.txt")
168
    assert not os.path.exists("test.txt")
305 by Martin Pool
testbzr: test renames
169
308 by Martin Pool
fix test suite
170
    assert backtick("bzr revno") == '0\n'
307 by Martin Pool
testbzr: clean up crlf handling
171
300 by Martin Pool
- more tests
172
    cd('..')
173
296 by Martin Pool
- better reports from testbzr when it fails
174
    progress("all tests passed!")
175
except Exception, e:
176
    sys.stderr.write('*' * 50 + '\n'
177
                     + 'testbzr: tests failed\n'
302 by Martin Pool
testbzr: new backtick() helper
178
                     + 'see testbzr.log for more information\n'
296 by Martin Pool
- better reports from testbzr when it fails
179
                     + '*' * 50 + '\n')
180
    logfile.write('tests failed!\n')
181
    traceback.print_exc(None, logfile)
182
    sys.exit(1)