18
18
from cStringIO import StringIO
30
29
import bzrlib.commands
31
30
import bzrlib.trace
32
31
import bzrlib.fetch
33
import bzrlib.osutils as osutils
34
32
from bzrlib.selftest import TestUtil
35
33
from bzrlib.selftest.TestUtil import TestLoader, TestSuite
36
from bzrlib.selftest.treeshape import build_tree_contents
38
36
MODULES_TO_TEST = []
39
37
MODULES_TO_DOCTEST = []
72
70
No special behaviour for now.
75
def _elapsedTime(self):
76
return "(Took %.3fs)" % (time.time() - self._start_time)
78
73
def startTest(self, test):
79
74
unittest.TestResult.startTest(self, test)
80
75
# TODO: Maybe show test.shortDescription somewhere?
83
78
self.stream.write('%-70.70s' % what)
84
79
self.stream.flush()
85
self._start_time = time.time()
87
81
def addError(self, test, err):
88
unittest.TestResult.addError(self, test, err)
90
self.stream.writeln("ERROR %s" % self._elapsedTime())
92
self.stream.write('E')
82
super(_MyResult, self).addError(test, err)
93
83
self.stream.flush()
95
85
def addFailure(self, test, err):
96
unittest.TestResult.addFailure(self, test, err)
98
self.stream.writeln("FAIL %s" % self._elapsedTime())
100
self.stream.write('F')
86
super(_MyResult, self).addFailure(test, err)
101
87
self.stream.flush()
103
89
def addSuccess(self, test):
105
self.stream.writeln('OK %s' % self._elapsedTime())
91
self.stream.writeln('OK')
107
93
self.stream.write('~')
108
94
self.stream.flush()
123
109
class TextTestRunner(unittest.TextTestRunner):
124
stop_on_failure = False
126
111
def _makeResult(self):
127
112
result = _MyResult(self.stream, self.descriptions, self.verbosity)
128
if self.stop_on_failure:
129
result = EarlyStoppingTestResultAdapter(result)
113
return EarlyStoppingTestResultAdapter(result)
133
116
def iter_suite_tests(suite):
165
148
routine, and to build and check bzr trees."""
168
_log_file_name = None
171
153
unittest.TestCase.setUp(self)
172
self.oldenv = os.environ.get('HOME', None)
173
os.environ['HOME'] = os.getcwd()
174
self.bzr_email = os.environ.get('BZREMAIL')
175
if self.bzr_email is not None:
176
del os.environ['BZREMAIL']
177
self.email = os.environ.get('EMAIL')
178
if self.email is not None:
179
del os.environ['EMAIL']
180
154
bzrlib.trace.disable_default_logging()
181
155
self._enable_file_logging()
183
def _ndiff_strings(self, a, b):
184
"""Return ndiff between two strings containing lines.
186
A trailing newline is added if missing to make the strings
188
if b and b[-1] != '\n':
190
if a and a[-1] != '\n':
192
difflines = difflib.ndiff(a.splitlines(True),
194
linejunk=lambda x: False,
195
charjunk=lambda x: False)
196
return ''.join(difflines)
198
def assertEqualDiff(self, a, b):
199
"""Assert two texts are equal, if not raise an exception.
201
This is intended for use with multi-line strings where it can
202
be hard to find the differences by eye.
204
# TODO: perhaps override assertEquals to call this for strings?
207
raise AssertionError("texts not equal:\n" +
208
self._ndiff_strings(a, b))
210
def assertContainsRe(self, haystack, needle_re):
211
"""Assert that a contains something matching a regular expression."""
212
if not re.search(needle_re, haystack):
213
raise AssertionError('pattern "%s" not found in "%s"'
214
% (needle_re, haystack))
216
158
def _enable_file_logging(self):
217
159
fileno, name = tempfile.mkstemp(suffix='.log', prefix='testbzr')
229
171
self._log_file_name = name
231
173
def tearDown(self):
232
os.environ['HOME'] = self.oldenv
233
if os.environ.get('BZREMAIL') is not None:
234
del os.environ['BZREMAIL']
235
if self.bzr_email is not None:
236
os.environ['BZREMAIL'] = self.bzr_email
237
if os.environ.get('EMAIL') is not None:
238
del os.environ['EMAIL']
239
if self.email is not None:
240
os.environ['EMAIL'] = self.email
241
174
logging.getLogger('').removeHandler(self._log_hdlr)
242
175
bzrlib.trace.enable_default_logging()
243
176
logging.debug('%s teardown', self.id())
250
183
def _get_log(self):
251
184
"""Return as a string the log for this test"""
252
if self._log_file_name:
253
return open(self._log_file_name).read()
185
return open(self._log_file_name).read()
257
188
def capture(self, cmd):
258
189
"""Shortcut that splits cmd into words, runs, and returns stdout"""
418
349
os.mkdir(os.path.join(TestCaseInTempDir.TEST_ROOT, '.bzr'))
352
super(TestCaseInTempDir, self).setUp()
421
353
self._make_test_root()
422
354
self._currentdir = os.getcwdu()
423
355
short_id = self.id().replace('bzrlib.selftest.', '') \
449
380
print >>f, "contents of", name
452
def build_tree_contents(self, shape):
453
bzrlib.selftest.build_tree_contents(shape)
455
383
def failUnlessExists(self, path):
456
384
"""Fail unless path, which may be abs or relative, exists."""
457
self.failUnless(osutils.lexists(path))
459
def assertFileEqual(self, content, path):
460
"""Fail if path does not contain 'content'."""
461
self.failUnless(osutils.lexists(path))
462
self.assertEqualDiff(content, open(path, 'r').read())
385
self.failUnless(os.path.exists(path))
465
388
class MetaTestLog(TestCase):
468
391
logging.info('an info message')
469
392
warning('something looks dodgy...')
470
393
logging.debug('hello, test is running')
474
397
def filter_suite_by_re(suite, pattern):
475
398
result = TestUtil.TestSuite()
476
399
filter_re = re.compile(pattern)
477
400
for test in iter_suite_tests(suite):
478
if filter_re.search(test.id()):
401
if filter_re.match(test.id()):
479
402
result.addTest(test)
483
def run_suite(suite, name='test', verbose=False, pattern=".*",
484
stop_on_failure=False):
406
def filter_suite_by_names(suite, wanted_names):
407
"""Return a new suite containing only selected tests.
409
Names are considered to match if any name is a substring of the
410
fully-qualified test id (i.e. the class ."""
412
for test in iter_suite_tests(suite):
414
for p in wanted_names:
415
if this_id.find(p) != -1:
420
def run_suite(suite, name='test', verbose=False, pattern=".*", testnames=None):
485
421
TestCaseInTempDir._TEST_NAME = name
490
426
runner = TextTestRunner(stream=sys.stdout,
492
428
verbosity=verbosity)
493
runner.stop_on_failure=stop_on_failure
430
suite = filter_suite_by_names(suite, testnames)
494
431
if pattern != '.*':
495
432
suite = filter_suite_by_re(suite, pattern)
496
433
result = runner.run(suite)
505
442
return result.wasSuccessful()
508
def selftest(verbose=False, pattern=".*", stop_on_failure=True):
445
def selftest(verbose=False, pattern=".*", testnames=None):
509
446
"""Run the whole test suite under the enhanced runner"""
510
447
return run_suite(test_suite(), 'testbzr', verbose=verbose, pattern=pattern,
511
stop_on_failure=stop_on_failure)
514
451
def test_suite():
522
459
testmod_names = \
523
460
['bzrlib.selftest.MetaTestLog',
524
'bzrlib.selftest.testgpg',
525
461
'bzrlib.selftest.testidentitymap',
526
462
'bzrlib.selftest.testinv',
527
463
'bzrlib.selftest.test_ancestry',
528
464
'bzrlib.selftest.test_commit',
529
465
'bzrlib.selftest.test_commit_merge',
530
'bzrlib.selftest.testconfig',
531
466
'bzrlib.selftest.versioning',
532
467
'bzrlib.selftest.testmerge3',
533
468
'bzrlib.selftest.testmerge',
556
491
'bzrlib.selftest.testworkingtree',
557
492
'bzrlib.selftest.test_upgrade',
558
493
'bzrlib.selftest.test_conflicts',
559
'bzrlib.selftest.testtestament',
560
'bzrlib.selftest.testannotate',
561
'bzrlib.selftest.testrevprops',
562
'bzrlib.selftest.testoptions',
563
'bzrlib.selftest.testhttp',
564
'bzrlib.selftest.testnonascii',
567
496
for m in (bzrlib.store, bzrlib.inventory, bzrlib.branch,
568
bzrlib.osutils, bzrlib.commands, bzrlib.merge3,
497
bzrlib.osutils, bzrlib.commands, bzrlib.merge3):
571
498
if m not in MODULES_TO_DOCTEST:
572
499
MODULES_TO_DOCTEST.append(m)