15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
from testsweet import TestCase, run_suite, InTempDir
23
from testsweet import run_suite
19
25
import bzrlib.commands
21
28
MODULES_TO_TEST = []
22
29
MODULES_TO_DOCTEST = []
25
class BzrTestBase(InTempDir):
26
"""bzr-specific test base class"""
31
from logging import debug, warning, error
34
class TestCase(unittest.TestCase):
35
"""Base class for bzr unit tests.
37
Tests that need access to disk resources should subclass
38
FunctionalTestCase not TestCase.
40
Error and debug log messages are redirected from their usual
41
location into a temporary file, the contents of which can be
42
retrieved by _get_log().
44
There are also convenience functions to invoke bzr's command-line
45
routine, and to build and check bzr trees."""
50
# this replaces the default testsweet.TestCase; we don't want logging changed
51
unittest.TestCase.setUp(self)
52
bzrlib.trace.disable_default_logging()
53
self._enable_file_logging()
56
def _enable_file_logging(self):
57
fileno, name = tempfile.mkstemp(suffix='.log', prefix='testbzr')
59
self._log_file = os.fdopen(fileno, 'w+')
61
hdlr = logging.StreamHandler(self._log_file)
62
hdlr.setLevel(logging.DEBUG)
63
hdlr.setFormatter(logging.Formatter('%(levelname)4.4s %(message)s'))
64
logging.getLogger('').addHandler(hdlr)
65
logging.getLogger('').setLevel(logging.DEBUG)
67
debug('opened log file %s', name)
69
self._log_file_name = name
73
logging.getLogger('').removeHandler(self._log_hdlr)
74
bzrlib.trace.enable_default_logging()
75
logging.debug('%s teardown', self.id())
76
self._log_file.close()
77
unittest.TestCase.tearDown(self)
84
"""Return as a string the log for this test"""
85
return open(self._log_file_name).read()
27
87
def run_bzr(self, *args, **kwargs):
28
88
"""Invoke bzr, as if it were run from the command line.
34
94
Much of the old code runs bzr by forking a new copy of Python, but
35
95
that is slower, harder to debug, and generally not necessary.
37
97
retcode = kwargs.get('retcode', 0)
38
98
self.assertEquals(bzrlib.commands.run_bzr(args), retcode)
100
def check_inventory_shape(self, inv, shape):
102
Compare an inventory to a list of expected names.
104
Fail if they are not precisely equal.
107
shape = list(shape) # copy
108
for path, ie in inv.entries():
109
name = path.replace('\\', '/')
117
self.fail("expected paths not found in inventory: %r" % shape)
119
self.fail("unexpected paths found in inventory: %r" % extras)
121
BzrTestBase = TestCase
124
class FunctionalTestCase(TestCase):
125
"""Base class for tests that perform function testing - running bzr,
126
using files on disk, and similar activities.
128
InTempDir is an old alias for FunctionalTestCase.
133
OVERRIDE_PYTHON = 'python'
135
def check_file_contents(self, filename, expect):
136
self.log("check contents of file %s" % filename)
137
contents = file(filename, 'r').read()
138
if contents != expect:
139
self.log("expected: %r" % expect)
140
self.log("actually: %r" % contents)
141
self.fail("contents of %s not as expected")
143
def _make_test_root(self):
148
if FunctionalTestCase.TEST_ROOT is not None:
150
FunctionalTestCase.TEST_ROOT = os.path.abspath(
151
tempfile.mkdtemp(suffix='.tmp',
152
prefix=self._TEST_NAME + '-',
155
# make a fake bzr directory there to prevent any tests propagating
156
# up onto the source directory's real branch
157
os.mkdir(os.path.join(FunctionalTestCase.TEST_ROOT, '.bzr'))
160
super(FunctionalTestCase, self).setUp()
162
self._make_test_root()
163
self._currentdir = os.getcwdu()
164
self.test_dir = os.path.join(self.TEST_ROOT, self.id())
165
os.mkdir(self.test_dir)
166
os.chdir(self.test_dir)
170
os.chdir(self._currentdir)
171
super(FunctionalTestCase, self).tearDown()
173
def _formcmd(self, cmd):
174
if isinstance(cmd, basestring):
177
cmd[0] = self.BZRPATH
178
if self.OVERRIDE_PYTHON:
179
cmd.insert(0, self.OVERRIDE_PYTHON)
180
self.log('$ %r' % cmd)
183
def runcmd(self, cmd, retcode=0):
184
"""Run one command and check the return code.
186
Returns a tuple of (stdout,stderr) strings.
188
If a single string is based, it is split into words.
189
For commands that are not simple space-separated words, please
190
pass a list instead."""
193
from subprocess import call
194
except ImportError, e:
197
cmd = self._formcmd(cmd)
198
self.log('$ ' + ' '.join(cmd))
199
actual_retcode = call(cmd, stdout=self._log_file, stderr=self._log_file)
200
if retcode != actual_retcode:
201
raise CommandFailed("test failed: %r returned %d, expected %d"
202
% (cmd, actual_retcode, retcode))
204
def backtick(self, cmd, retcode=0):
205
"""Run a command and return its output"""
208
from subprocess import Popen, PIPE
209
except ImportError, e:
213
cmd = self._formcmd(cmd)
214
child = Popen(cmd, stdout=PIPE, stderr=self._log_file)
215
outd, errd = child.communicate()
217
actual_retcode = child.wait()
219
outd = outd.replace('\r', '')
221
if retcode != actual_retcode:
222
raise CommandFailed("test failed: %r returned %d, expected %d"
223
% (cmd, actual_retcode, retcode))
229
def build_tree(self, shape):
230
"""Build a test tree according to a pattern.
232
shape is a sequence of file specifications. If the final
233
character is '/', a directory is created.
235
This doesn't add anything to a branch.
237
# XXX: It's OK to just create them using forward slashes on windows?
240
assert isinstance(name, basestring)
245
print >>f, "contents of", name
250
class MetaTestLog(TestCase):
251
def test_logging(self):
252
"""Test logs are captured when a test fails."""
253
logging.info('an info message')
254
warning('something looks dodgy...')
255
logging.debug('hello, test is running')
259
InTempDir = FunctionalTestCase
41
262
def selftest(verbose=False):
42
263
from unittest import TestLoader, TestSuite
52
272
global MODULES_TO_TEST, MODULES_TO_DOCTEST
55
['bzrlib.selftest.whitebox',
275
['bzrlib.selftest.MetaTestLog',
276
'bzrlib.selftest.testinv',
277
'bzrlib.selftest.testfetch',
56
278
'bzrlib.selftest.versioning',
57
'bzrlib.selftest.testfetch',
58
'bzrlib.selftest.testinv',
279
'bzrlib.selftest.whitebox',
59
280
'bzrlib.selftest.testmerge3',
60
281
'bzrlib.selftest.testhashcache',
61
282
'bzrlib.selftest.teststatus',