~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()
78
    
298 by Martin Pool
- test some commands known to fail
79
    if retcode != actual_retcode:
80
        raise CommandFailed("test failed: %r returned %d, expected %d"
81
                            % (cmd, actual_retcode, retcode))
292 by Martin Pool
- start adding a pure-python blackbox test suite
82
302 by Martin Pool
testbzr: new backtick() helper
83
    return outd
84
301 by Martin Pool
- provide for catching output from shell commands
85
292 by Martin Pool
- start adding a pure-python blackbox test suite
86
87
def progress(msg):
88
    print '* ' + msg
89
    logfile.write('* '+ msg + '\n')
297 by Martin Pool
- fix intentional testcase failure
90
    log_linenumber()
91
92
299 by Martin Pool
testbzr:
93
def cd(dirname):
94
    logfile.write('$ cd %s\n' % dirname)
95
    os.chdir(dirname)
96
97
300 by Martin Pool
- more tests
98
297 by Martin Pool
- fix intentional testcase failure
99
def log_linenumber():
100
    """Log the stack frame location two things up."""
101
    stack = traceback.extract_stack()[-3]
102
    logfile.write('   at %s:%d\n' % stack[:2])
103
104
105
TESTDIR = "testbzr.tmp"
292 by Martin Pool
- start adding a pure-python blackbox test suite
106
107
# prepare an empty scratch directory
108
if os.path.exists(TESTDIR):
109
    shutil.rmtree(TESTDIR)
110
111
297 by Martin Pool
- fix intentional testcase failure
112
logfile = open('testbzr.log', 'wt', buffering=1)
292 by Martin Pool
- start adding a pure-python blackbox test suite
113
114
300 by Martin Pool
- more tests
115
try:
116
    runcmd(['mkdir', TESTDIR])
299 by Martin Pool
testbzr:
117
    cd(TESTDIR)
296 by Martin Pool
- better reports from testbzr when it fails
118
300 by Martin Pool
- more tests
119
    progress("introductory commands")
296 by Martin Pool
- better reports from testbzr when it fails
120
    runcmd("bzr version")
121
    runcmd("bzr help")
297 by Martin Pool
- fix intentional testcase failure
122
    runcmd("bzr --help")
123
300 by Martin Pool
- more tests
124
    progress("user identity")
297 by Martin Pool
- fix intentional testcase failure
125
    # this should always identify something, if only "john@localhost"
126
    runcmd("bzr whoami")
298 by Martin Pool
- test some commands known to fail
127
    runcmd("bzr whoami --email")
302 by Martin Pool
testbzr: new backtick() helper
128
    assert backtick("bzr whoami --email").count('@') == 1
298 by Martin Pool
- test some commands known to fail
129
300 by Martin Pool
- more tests
130
    progress("invalid commands")
298 by Martin Pool
- test some commands known to fail
131
    runcmd("bzr pants", retcode=1)
132
    runcmd("bzr --pants off", retcode=1)
296 by Martin Pool
- better reports from testbzr when it fails
133
300 by Martin Pool
- more tests
134
    progress("basic branch creation")
135
    runcmd(['mkdir', 'branch1'])
136
    cd('branch1')
137
    runcmd('bzr init')
303 by Martin Pool
- more tests for unknown file
138
139
    progress("status of new file")
300 by Martin Pool
- more tests
140
    
141
    f = file('test.txt', 'wt')
142
    f.write('hello world!\n')
143
    f.close()
144
303 by Martin Pool
- more tests for unknown file
145
    out = backtick("bzr unknowns").rstrip('\r\n')
146
    assert out == 'test.txt'
147
148
    out = backtick("bzr status").replace('\r', '')
149
    assert out == '''?       test.txt\n'''
150
151
    out = backtick("bzr status --all").replace('\r', '')
304 by Martin Pool
testbzr: test adding a file
152
    assert out == "?       test.txt\n"
153
154
    progress("adding a file")
155
156
    runcmd("bzr add test.txt")
157
    assert backtick("bzr unknowns") == ''
158
    assert backtick("bzr status --all").replace('\r', '') == "A       test.txt\n"
300 by Martin Pool
- more tests
159
160
    cd('..')
161
296 by Martin Pool
- better reports from testbzr when it fails
162
    progress("all tests passed!")
163
except Exception, e:
164
    sys.stderr.write('*' * 50 + '\n'
165
                     + 'testbzr: tests failed\n'
302 by Martin Pool
testbzr: new backtick() helper
166
                     + 'see testbzr.log for more information\n'
296 by Martin Pool
- better reports from testbzr when it fails
167
                     + '*' * 50 + '\n')
168
    logfile.write('tests failed!\n')
169
    traceback.print_exc(None, logfile)
170
    sys.exit(1)