15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
from cStringIO import StringIO
24
from testsweet import run_suite
25
29
import bzrlib.commands
27
30
import bzrlib.trace
28
31
import bzrlib.fetch
30
34
MODULES_TO_TEST = []
31
35
MODULES_TO_DOCTEST = []
33
37
from logging import debug, warning, error
39
class CommandFailed(Exception):
36
42
class TestCase(unittest.TestCase):
37
43
"""Base class for bzr unit tests.
86
90
"""Return as a string the log for this test"""
87
91
return open(self._log_file_name).read()
94
def capture(self, cmd):
95
"""Shortcut that splits cmd into words, runs, and returns stdout"""
96
return self.run_bzr_captured(cmd.split())[0]
98
def run_bzr_captured(self, argv, retcode=0):
99
"""Invoke bzr and return (result, stdout, stderr).
101
Useful for code that wants to check the contents of the
102
output, the way error messages are presented, etc.
104
This should be the main method for tests that want to exercise the
105
overall behavior of the bzr application (rather than a unit test
106
or a functional test of the library.)
108
Much of the old code runs bzr by forking a new copy of Python, but
109
that is slower, harder to debug, and generally not necessary.
111
This runs bzr through the interface that catches and reports
112
errors, and with logging set to something approximating the
113
default, so that error reporting can be checked.
115
argv -- arguments to invoke bzr
116
retcode -- expected return code, or None for don't-care.
120
self.log('run bzr: %s', ' '.join(argv))
121
handler = logging.StreamHandler(stderr)
122
handler.setFormatter(bzrlib.trace.QuietFormatter())
123
handler.setLevel(logging.INFO)
124
logger = logging.getLogger('')
125
logger.addHandler(handler)
127
result = self.apply_redirected(None, stdout, stderr,
128
bzrlib.commands.run_bzr_catch_errors,
131
logger.removeHandler(handler)
132
out = stdout.getvalue()
133
err = stderr.getvalue()
135
self.log('output:\n%s', out)
137
self.log('errors:\n%s', err)
138
if retcode is not None:
139
self.assertEquals(result, retcode)
89
142
def run_bzr(self, *args, **kwargs):
90
143
"""Invoke bzr, as if it were run from the command line.
93
146
overall behavior of the bzr application (rather than a unit test
94
147
or a functional test of the library.)
96
Much of the old code runs bzr by forking a new copy of Python, but
97
that is slower, harder to debug, and generally not necessary.
149
This sends the stdout/stderr results into the test's log,
150
where it may be useful for debugging. See also run_captured.
99
retcode = kwargs.get('retcode', 0)
100
result = self.apply_redirected(None, None, None,
101
bzrlib.commands.run_bzr, args)
102
self.assertEquals(result, retcode)
152
retcode = kwargs.pop('retcode', 0)
153
return self.run_bzr_captured(args, retcode)
104
155
def check_inventory_shape(self, inv, shape):
106
157
Compare an inventory to a list of expected names.
127
178
"""Call callable with redirected std io pipes.
129
180
Returns the return code."""
130
from StringIO import StringIO
131
181
if not callable(a_callable):
132
182
raise ValueError("a_callable must be callable.")
133
183
if stdin is None:
134
184
stdin = StringIO("")
135
185
if stdout is None:
136
stdout = self._log_file
186
if hasattr(self, "_log_file"):
187
stdout = self._log_file
137
190
if stderr is None:
138
stderr = self._log_file
191
if hasattr(self, "_log_file"):
192
stderr = self._log_file
139
195
real_stdin = sys.stdin
140
196
real_stdout = sys.stdout
141
197
real_stderr = sys.stderr
144
199
sys.stdout = stdout
145
200
sys.stderr = stderr
146
201
sys.stdin = stdin
147
result = a_callable(*args, **kwargs)
202
return a_callable(*args, **kwargs)
149
204
sys.stdout = real_stdout
150
205
sys.stderr = real_stderr
151
206
sys.stdin = real_stdin
155
209
BzrTestBase = TestCase
181
235
self.fail("contents of %s not as expected")
183
237
def _make_test_root(self):
188
238
if TestCaseInTempDir.TEST_ROOT is not None:
190
TestCaseInTempDir.TEST_ROOT = os.path.abspath(
191
tempfile.mkdtemp(suffix='.tmp',
192
prefix=self._TEST_NAME + '-',
242
root = 'test%04d.tmp' % i
246
if e.errno == errno.EEXIST:
251
# successfully created
252
TestCaseInTempDir.TEST_ROOT = os.path.abspath(root)
195
254
# make a fake bzr directory there to prevent any tests propagating
196
255
# up onto the source directory's real branch
197
256
os.mkdir(os.path.join(TestCaseInTempDir.TEST_ROOT, '.bzr'))
200
259
super(TestCaseInTempDir, self).setUp()
202
260
self._make_test_root()
203
261
self._currentdir = os.getcwdu()
204
262
self.test_dir = os.path.join(self.TEST_ROOT, self.id())
206
264
os.chdir(self.test_dir)
208
266
def tearDown(self):
210
267
os.chdir(self._currentdir)
211
268
super(TestCaseInTempDir, self).tearDown()
213
def _formcmd(self, cmd):
214
if isinstance(cmd, basestring):
217
cmd[0] = self.BZRPATH
218
if self.OVERRIDE_PYTHON:
219
cmd.insert(0, self.OVERRIDE_PYTHON)
220
self.log('$ %r' % cmd)
223
def runcmd(self, cmd, retcode=0):
224
"""Run one command and check the return code.
226
Returns a tuple of (stdout,stderr) strings.
228
If a single string is based, it is split into words.
229
For commands that are not simple space-separated words, please
230
pass a list instead."""
233
from subprocess import call
234
except ImportError, e:
237
cmd = self._formcmd(cmd)
238
self.log('$ ' + ' '.join(cmd))
239
actual_retcode = call(cmd, stdout=self._log_file, stderr=self._log_file)
240
if retcode != actual_retcode:
241
raise CommandFailed("test failed: %r returned %d, expected %d"
242
% (cmd, actual_retcode, retcode))
244
def backtick(self, cmd, retcode=0):
245
"""Run a command and return its output"""
248
from subprocess import Popen, PIPE
249
except ImportError, e:
253
cmd = self._formcmd(cmd)
254
child = Popen(cmd, stdout=PIPE, stderr=self._log_file)
255
outd, errd = child.communicate()
257
actual_retcode = child.wait()
259
outd = outd.replace('\r', '')
261
if retcode != actual_retcode:
262
raise CommandFailed("test failed: %r returned %d, expected %d"
263
% (cmd, actual_retcode, retcode))
269
270
def build_tree(self, shape):
270
271
"""Build a test tree according to a pattern.
299
298
def selftest(verbose=False, pattern=".*"):
300
return run_suite(test_suite(), 'testbzr', verbose=verbose, pattern=pattern)
299
return testsweet.run_suite(test_suite(), 'testbzr', verbose=verbose, pattern=pattern)
303
302
def test_suite():
305
304
import bzrlib, bzrlib.store, bzrlib.inventory, bzrlib.branch
306
305
import bzrlib.osutils, bzrlib.commands, bzrlib.merge3, bzrlib.plugin
307
306
from doctest import DocTestSuite
313
308
global MODULES_TO_TEST, MODULES_TO_DOCTEST
315
310
testmod_names = \
316
311
['bzrlib.selftest.MetaTestLog',
312
'bzrlib.selftest.test_parent',
317
313
'bzrlib.selftest.testinv',
318
314
'bzrlib.selftest.testfetch',
319
315
'bzrlib.selftest.versioning',
320
316
'bzrlib.selftest.whitebox',
321
317
'bzrlib.selftest.testmerge3',
318
'bzrlib.selftest.testmerge',
322
319
'bzrlib.selftest.testhashcache',
323
320
'bzrlib.selftest.teststatus',
324
321
'bzrlib.selftest.testlog',
325
322
'bzrlib.selftest.blackbox',
326
323
'bzrlib.selftest.testrevisionnamespaces',
327
324
'bzrlib.selftest.testbranch',
325
'bzrlib.selftest.testremotebranch',
328
326
'bzrlib.selftest.testrevision',
327
'bzrlib.selftest.test_revision_info',
329
328
'bzrlib.selftest.test_merge_core',
330
329
'bzrlib.selftest.test_smart_add',
331
330
'bzrlib.selftest.testdiff',
331
'bzrlib.selftest.test_xml',
333
'bzrlib.selftest.teststore',
334
'bzrlib.selftest.testgraph',
335
337
for m in (bzrlib.store, bzrlib.inventory, bzrlib.branch,