1
# Copyright (C) 2005 by Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
from unittest import TestResult, TestCase
22
from subprocess import call, Popen, PIPE
23
except ImportError, e:
24
sys.stderr.write("testbzr: sorry, this test suite requires the subprocess module\n"
25
"this is shipped with python2.4 and available separately for 2.3\n")
29
class CommandFailed(Exception):
33
class TestBase(TestCase):
34
"""Base class for bzr test cases.
36
Just defines some useful helper functions; doesn't actually test
40
# TODO: Special methods to invoke bzr, so that we can run it
41
# through a specified Python intepreter
43
OVERRIDE_PYTHON = None # to run with alternative python 'python'
47
def formcmd(self, cmd):
48
if isinstance(cmd, basestring):
53
if self.OVERRIDE_PYTHON:
54
cmd.insert(0, self.OVERRIDE_PYTHON)
56
self.log('$ %r' % cmd)
61
def runcmd(self, 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."""
69
cmd = self.formcmd(cmd)
71
self.log('$ ' + ' '.join(cmd))
72
actual_retcode = call(cmd, stdout=self.TEST_LOG, stderr=self.TEST_LOG)
74
if retcode != actual_retcode:
75
raise CommandFailed("test failed: %r returned %d, expected %d"
76
% (cmd, actual_retcode, retcode))
79
def backtick(self, cmd, retcode=0):
80
cmd = self.formcmd(cmd)
81
child = Popen(cmd, stdout=PIPE, stderr=self.TEST_LOG)
82
outd, errd = child.communicate()
84
actual_retcode = child.wait()
86
outd = outd.replace('\r', '')
88
if retcode != actual_retcode:
89
raise CommandFailed("test failed: %r returned %d, expected %d"
90
% (cmd, actual_retcode, retcode))
98
"""Log a message to a progress file"""
99
print >>self.TEST_LOG, msg
102
class InTempDir(TestBase):
103
"""Base class for tests run in a temporary branch."""
106
self.test_dir = os.path.join(self.TEST_ROOT, self.__class__.__name__)
107
os.mkdir(self.test_dir)
108
os.chdir(self.test_dir)
112
os.chdir(self.TEST_ROOT)
118
class _MyResult(TestResult):
122
No special behaviour for now.
124
def __init__(self, out):
126
TestResult.__init__(self)
128
def startTest(self, test):
129
# TODO: Maybe show test.shortDescription somewhere?
130
print >>self.out, '%-60.60s' % test.id(),
131
TestResult.startTest(self, test)
133
def stopTest(self, test):
135
TestResult.stopTest(self, test)
138
def addError(self, test, err):
139
print >>self.out, 'ERROR'
140
TestResult.addError(self, test, err)
142
def addFailure(self, test, err):
143
print >>self.out, 'FAILURE'
144
TestResult.addFailure(self, test, err)
146
def addSuccess(self, test):
147
print >>self.out, 'OK'
148
TestResult.addSuccess(self, test)
153
from unittest import TestLoader, TestSuite
155
import bzrlib.selftest.whitebox
156
import bzrlib.selftest.blackbox
157
import bzrlib.selftest.versioning
158
from doctest import DocTestSuite
171
for m in bzrlib.selftest.whitebox, \
172
bzrlib.selftest.versioning:
173
suite.addTest(tl.loadTestsFromModule(m))
175
suite.addTest(bzrlib.selftest.blackbox.suite())
177
for m in bzrlib.store, bzrlib.inventory, bzrlib.branch, bzrlib.osutils, \
179
suite.addTest(DocTestSuite(m))
181
# save stdout & stderr so there's no leakage from code-under-test
182
real_stdout = sys.stdout
183
real_stderr = sys.stderr
184
sys.stdout = sys.stderr = TestBase.TEST_LOG
186
result = _MyResult(real_stdout)
189
sys.stdout = real_stdout
190
sys.stderr = real_stderr
192
_show_results(result)
194
return result.wasSuccessful()
199
def _setup_test_log():
203
log_filename = os.path.abspath('testbzr.log')
204
TestBase.TEST_LOG = open(log_filename, 'wt', buffering=1) # line buffered
206
print >>TestBase.TEST_LOG, "bzr tests run at " + time.ctime()
207
print '%-30s %s' % ('test log', log_filename)
210
def _setup_test_dir():
214
TestBase.ORIG_DIR = os.getcwdu()
215
TestBase.TEST_ROOT = os.path.abspath("testbzr.tmp")
217
print '%-30s %s' % ('running tests in', TestBase.TEST_ROOT)
219
if os.path.exists(TestBase.TEST_ROOT):
220
shutil.rmtree(TestBase.TEST_ROOT)
221
os.mkdir(TestBase.TEST_ROOT)
222
os.chdir(TestBase.TEST_ROOT)
224
# make a fake bzr directory there to prevent any tests propagating
225
# up onto the source directory's real branch
226
os.mkdir(os.path.join(TestBase.TEST_ROOT, '.bzr'))
230
def _show_results(result):
231
for case, tb in result.errors:
232
_show_test_failure('ERROR', case, tb)
234
for case, tb in result.failures:
235
_show_test_failure('FAILURE', case, tb)
238
print '%4d tests run' % result.testsRun
239
print '%4d errors' % len(result.errors)
240
print '%4d failures' % len(result.failures)
244
def _show_test_failure(kind, case, tb):
245
print (kind + '! ').ljust(60, '-')
247
desc = case.shortDescription()
251
print ''.ljust(60, '-')