15
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:
25
sys.stderr.write("testbzr: sorry, this test suite requires the subprocess module\n"
26
"this is shipped with python2.4 and available separately for 2.3\n")
30
class CommandFailed(Exception):
34
class TestBase(TestCase):
35
"""Base class for bzr test cases.
37
Just defines some useful helper functions; doesn't actually test
41
# TODO: Special methods to invoke bzr, so that we can run it
42
# through a specified Python intepreter
44
OVERRIDE_PYTHON = None # to run with alternative python 'python'
50
def formcmd(self, cmd):
51
if isinstance(cmd, basestring):
56
if self.OVERRIDE_PYTHON:
57
cmd.insert(0, self.OVERRIDE_PYTHON)
59
self.log('$ %r' % cmd)
64
def runcmd(self, cmd, retcode=0):
65
"""Run one command and check the return code.
67
Returns a tuple of (stdout,stderr) strings.
69
If a single string is based, it is split into words.
70
For commands that are not simple space-separated words, please
71
pass a list instead."""
72
cmd = self.formcmd(cmd)
74
self.log('$ ' + ' '.join(cmd))
75
actual_retcode = call(cmd, stdout=self.TEST_LOG, stderr=self.TEST_LOG)
77
if retcode != actual_retcode:
78
raise CommandFailed("test failed: %r returned %d, expected %d"
79
% (cmd, actual_retcode, retcode))
82
def backtick(self, cmd, retcode=0):
83
"""Run a command and return its output"""
84
cmd = self.formcmd(cmd)
85
child = Popen(cmd, stdout=PIPE, stderr=self.TEST_LOG)
86
outd, errd = child.communicate()
88
actual_retcode = child.wait()
90
outd = outd.replace('\r', '')
92
if retcode != actual_retcode:
93
raise CommandFailed("test failed: %r returned %d, expected %d"
94
% (cmd, actual_retcode, retcode))
100
def build_tree(self, shape):
101
"""Build a test tree according to a pattern.
103
shape is a sequence of file specifications. If the final
104
character is '/', a directory is created.
106
This doesn't add anything to a branch.
108
# XXX: It's OK to just create them using forward slashes on windows?
111
assert isinstance(name, basestring)
116
print >>f, "contents of", name
121
"""Log a message to a progress file"""
122
self._log_buf = self._log_buf + str(msg) + '\n'
123
print >>self.TEST_LOG, msg
126
def check_inventory_shape(self, inv, shape):
128
Compare an inventory to a list of expected names.
130
Fail if they are not precisely equal.
133
shape = list(shape) # copy
134
for path, ie in inv.entries():
135
name = path.replace('\\', '/')
143
self.fail("expected paths not found in inventory: %r" % shape)
145
self.fail("unexpected paths found in inventory: %r" % extras)
148
def check_file_contents(self, filename, expect):
149
self.log("check contents of file %s" % filename)
150
contents = file(filename, 'r').read()
151
if contents != expect:
152
self.log("expected: %r" % expected)
153
self.log("actually: %r" % contents)
154
self.fail("contents of %s not as expected")
158
class InTempDir(TestBase):
159
"""Base class for tests run in a temporary branch."""
162
self.test_dir = os.path.join(self.TEST_ROOT, self.__class__.__name__)
163
os.mkdir(self.test_dir)
164
os.chdir(self.test_dir)
18
from testsweet import TestCase, run_suite, InTempDir
19
import bzrlib.commands
22
MODULES_TO_DOCTEST = []
25
class BzrTestBase(InTempDir):
26
"""bzr-specific test base class"""
27
def run_bzr(self, *args, **kwargs):
28
retcode = kwargs.get('retcode', 0)
29
self.assertEquals(bzrlib.commands.run_bzr(args), retcode)
168
os.chdir(self.TEST_ROOT)
174
class _MyResult(TestResult):
178
No special behaviour for now.
180
def __init__(self, out):
182
TestResult.__init__(self)
184
def startTest(self, test):
185
# TODO: Maybe show test.shortDescription somewhere?
186
print >>self.out, '%-60.60s' % test.id(),
188
TestResult.startTest(self, test)
190
def stopTest(self, test):
192
TestResult.stopTest(self, test)
195
def addError(self, test, err):
196
print >>self.out, 'ERROR'
197
TestResult.addError(self, test, err)
198
_show_test_failure('error', test, err, self.out)
200
def addFailure(self, test, err):
201
print >>self.out, 'FAILURE'
202
TestResult.addFailure(self, test, err)
203
_show_test_failure('failure', test, err, self.out)
205
def addSuccess(self, test):
206
print >>self.out, 'OK'
207
TestResult.addSuccess(self, test)
32
def selftest(verbose=False):
212
33
from unittest import TestLoader, TestSuite
213
import bzrlib, bzrlib.store, bzrlib.inventory, bzrlib.branch, bzrlib.osutils, bzrlib.commands
215
import bzrlib.selftest.whitebox
216
import bzrlib.selftest.blackbox
217
import bzrlib.selftest.versioning
218
import bzrlib.selftest.testmerge3
219
import bzrlib.merge_core
34
import bzrlib, bzrlib.store, bzrlib.inventory, bzrlib.branch
35
import bzrlib.osutils, bzrlib.commands, bzrlib.merge3, bzrlib.plugin
220
36
from doctest import DocTestSuite
226
TestBase.BZRPATH = os.path.join(os.path.realpath(os.path.dirname(bzrlib.__path__[0])), 'bzr')
227
print '%-30s %s' % ('bzr binary', TestBase.BZRPATH)
43
global MODULES_TO_TEST, MODULES_TO_DOCTEST
46
['bzrlib.selftest.whitebox',
47
'bzrlib.selftest.versioning',
48
'bzrlib.selftest.testinv',
49
'bzrlib.selftest.testmerge3',
50
'bzrlib.selftest.testhashcache',
51
'bzrlib.selftest.teststatus',
52
'bzrlib.selftest.testlog',
53
'bzrlib.selftest.blackbox',
54
'bzrlib.selftest.testrevisionnamespaces',
55
'bzrlib.selftest.testbranch',
56
'bzrlib.selftest.testrevision',
58
'bzrlib.selftest.testdiff',
61
# XXX: should also test bzrlib.merge_core, but they seem to be out
62
# of date with the code.
64
for m in (bzrlib.store, bzrlib.inventory, bzrlib.branch,
65
bzrlib.osutils, bzrlib.commands, bzrlib.merge3):
66
if m not in MODULES_TO_DOCTEST:
67
MODULES_TO_DOCTEST.append(m)
70
TestCase.BZRPATH = os.path.join(os.path.realpath(os.path.dirname(bzrlib.__path__[0])), 'bzr')
71
print '%-30s %s' % ('bzr binary', TestCase.BZRPATH)
233
75
suite = TestSuite()
236
# should also test bzrlib.merge_core, but they seem to be out of date with
239
for m in bzrlib.selftest.whitebox, \
240
bzrlib.selftest.versioning, \
241
bzrlib.selftest.testmerge3:
242
suite.addTest(tl.loadTestsFromModule(m))
244
for m in bzrlib.store, bzrlib.inventory, bzrlib.branch, bzrlib.osutils, \
77
suite.addTest(TestLoader().loadTestsFromNames(testmod_names))
79
for m in MODULES_TO_TEST:
80
suite.addTest(TestLoader().loadTestsFromModule(m))
82
for m in (MODULES_TO_DOCTEST):
247
83
suite.addTest(DocTestSuite(m))
249
suite.addTest(bzrlib.selftest.blackbox.suite())
251
# save stdout & stderr so there's no leakage from code-under-test
252
real_stdout = sys.stdout
253
real_stderr = sys.stderr
254
sys.stdout = sys.stderr = TestBase.TEST_LOG
256
result = _MyResult(real_stdout)
259
sys.stdout = real_stdout
260
sys.stderr = real_stderr
262
_show_results(result)
264
return result.wasSuccessful()
269
def _setup_test_log():
273
log_filename = os.path.abspath('testbzr.log')
274
TestBase.TEST_LOG = open(log_filename, 'wt', buffering=1) # line buffered
276
print >>TestBase.TEST_LOG, "bzr tests run at " + time.ctime()
277
print '%-30s %s' % ('test log', log_filename)
280
def _setup_test_dir():
284
TestBase.ORIG_DIR = os.getcwdu()
285
TestBase.TEST_ROOT = os.path.abspath("testbzr.tmp")
287
print '%-30s %s' % ('running tests in', TestBase.TEST_ROOT)
289
if os.path.exists(TestBase.TEST_ROOT):
290
shutil.rmtree(TestBase.TEST_ROOT)
291
os.mkdir(TestBase.TEST_ROOT)
292
os.chdir(TestBase.TEST_ROOT)
294
# make a fake bzr directory there to prevent any tests propagating
295
# up onto the source directory's real branch
296
os.mkdir(os.path.join(TestBase.TEST_ROOT, '.bzr'))
300
def _show_results(result):
302
print '%4d tests run' % result.testsRun
303
print '%4d errors' % len(result.errors)
304
print '%4d failures' % len(result.failures)
308
def _show_test_failure(kind, case, exc_info, out):
309
from traceback import print_exception
311
print >>out, '-' * 60
314
desc = case.shortDescription()
316
print >>out, ' (%s)' % desc
318
print_exception(exc_info[0], exc_info[1], exc_info[2], None, out)
320
if isinstance(case, TestBase):
322
print >>out, 'log from this test:'
323
print >>out, case._log_buf
325
print >>out, '-' * 60
85
for p in bzrlib.plugin.all_plugins:
86
if hasattr(p, 'test_suite'):
87
suite.addTest(p.test_suite())
89
import bzrlib.merge_core
90
suite.addTest(unittest.makeSuite(bzrlib.merge_core.MergeTest, 'test_'))
92
return run_suite(suite, 'testbzr', verbose=verbose)