114
137
Shows output in a different format, including displaying runtime for tests.
116
139
stop_early = False
118
def _elapsedTime(self):
119
return "%5dms" % (1000 * (time.time() - self._start_time))
141
def __init__(self, stream, descriptions, verbosity, pb=None,
143
"""Construct new TestResult.
145
:param bench_history: Optionally, a writable file object to accumulate
148
unittest._TextTestResult.__init__(self, stream, descriptions, verbosity)
150
if bench_history is not None:
151
from bzrlib.version import _get_bzr_source_tree
152
src_tree = _get_bzr_source_tree()
155
revision_id = src_tree.get_parent_ids()[0]
157
# XXX: if this is a brand new tree, do the same as if there
161
# XXX: If there's no branch, what should we do?
163
bench_history.write("--date %s %s\n" % (time.time(), revision_id))
164
self._bench_history = bench_history
166
def extractBenchmarkTime(self, testCase):
167
"""Add a benchmark time for the current test case."""
168
self._benchmarkTime = getattr(testCase, "_benchtime", None)
170
def _elapsedTestTimeString(self):
171
"""Return a time string for the overall time the current test has taken."""
172
return self._formatTime(time.time() - self._start_time)
174
def _testTimeString(self):
175
if self._benchmarkTime is not None:
177
self._formatTime(self._benchmarkTime),
178
self._elapsedTestTimeString())
180
return " %s" % self._elapsedTestTimeString()
182
def _formatTime(self, seconds):
183
"""Format seconds as milliseconds with leading spaces."""
184
return "%5dms" % (1000 * seconds)
186
def _ellipsise_unimportant_words(self, a_string, final_width,
188
"""Add ellipses (sp?) for overly long strings.
190
:param keep_start: If true preserve the start of a_string rather
194
if len(a_string) > final_width:
195
result = a_string[:final_width-3] + '...'
199
if len(a_string) > final_width:
200
result = '...' + a_string[3-final_width:]
203
return result.ljust(final_width)
121
205
def startTest(self, test):
122
206
unittest.TestResult.startTest(self, test)
124
208
# the beginning, but in an id, the important words are
126
210
SHOW_DESCRIPTIONS = False
212
if not self.showAll and self.dots and self.pb is not None:
215
final_width = osutils.terminal_width()
216
final_width = final_width - 15 - 8
218
if SHOW_DESCRIPTIONS:
219
what = test.shortDescription()
221
what = self._ellipsise_unimportant_words(what, final_width, keep_start=True)
224
if what.startswith('bzrlib.tests.'):
226
what = self._ellipsise_unimportant_words(what, final_width)
128
width = osutils.terminal_width()
129
name_width = width - 15
131
if SHOW_DESCRIPTIONS:
132
what = test.shortDescription()
134
if len(what) > name_width:
135
what = what[:name_width-3] + '...'
138
if what.startswith('bzrlib.tests.'):
140
if len(what) > name_width:
141
what = '...' + what[3-name_width:]
142
what = what.ljust(name_width)
143
228
self.stream.write(what)
229
elif self.dots and self.pb is not None:
230
self.pb.update(what, self.testsRun - 1, None)
144
231
self.stream.flush()
232
self._recordTestStartTime()
234
def _recordTestStartTime(self):
235
"""Record that a test has started."""
145
236
self._start_time = time.time()
147
238
def addError(self, test, err):
148
239
if isinstance(err[1], TestSkipped):
149
240
return self.addSkipped(test, err)
150
241
unittest.TestResult.addError(self, test, err)
242
self.extractBenchmarkTime(test)
152
self.stream.writeln("ERROR %s" % self._elapsedTime())
244
self.stream.writeln("ERROR %s" % self._testTimeString())
245
elif self.dots and self.pb is None:
154
246
self.stream.write('E')
248
self.pb.update(self._ellipsise_unimportant_words('ERROR', 13), self.testsRun, None)
249
self.pb.note(self._ellipsise_unimportant_words(
250
test.id() + ': ERROR',
251
osutils.terminal_width()))
155
252
self.stream.flush()
156
253
if self.stop_early:
159
256
def addFailure(self, test, err):
160
257
unittest.TestResult.addFailure(self, test, err)
258
self.extractBenchmarkTime(test)
162
self.stream.writeln(" FAIL %s" % self._elapsedTime())
260
self.stream.writeln(" FAIL %s" % self._testTimeString())
261
elif self.dots and self.pb is None:
164
262
self.stream.write('F')
264
self.pb.update(self._ellipsise_unimportant_words('FAIL', 13), self.testsRun, None)
265
self.pb.note(self._ellipsise_unimportant_words(
266
test.id() + ': FAIL',
267
osutils.terminal_width()))
165
268
self.stream.flush()
166
269
if self.stop_early:
169
272
def addSuccess(self, test):
273
self.extractBenchmarkTime(test)
274
if self._bench_history is not None:
275
if self._benchmarkTime is not None:
276
self._bench_history.write("%s %s\n" % (
277
self._formatTime(self._benchmarkTime),
171
self.stream.writeln(' OK %s' % self._elapsedTime())
280
self.stream.writeln(' OK %s' % self._testTimeString())
281
for bench_called, stats in getattr(test, '_benchcalls', []):
282
self.stream.writeln('LSProf output for %s(%s, %s)' % bench_called)
283
stats.pprint(file=self.stream)
284
elif self.dots and self.pb is None:
173
285
self.stream.write('~')
287
self.pb.update(self._ellipsise_unimportant_words('OK', 13), self.testsRun, None)
174
288
self.stream.flush()
175
289
unittest.TestResult.addSuccess(self, test)
177
291
def addSkipped(self, test, skip_excinfo):
292
self.extractBenchmarkTime(test)
179
print >>self.stream, ' SKIP %s' % self._elapsedTime()
294
print >>self.stream, ' SKIP %s' % self._testTimeString()
180
295
print >>self.stream, ' %s' % skip_excinfo[1]
296
elif self.dots and self.pb is None:
182
297
self.stream.write('S')
299
self.pb.update(self._ellipsise_unimportant_words('SKIP', 13), self.testsRun, None)
183
300
self.stream.flush()
184
301
# seems best to treat this as success from point-of-view of unittest
185
302
# -- it actually does nothing so it barely matters :)
186
unittest.TestResult.addSuccess(self, test)
305
except KeyboardInterrupt:
308
self.addError(test, test.__exc_info())
310
unittest.TestResult.addSuccess(self, test)
188
312
def printErrorList(self, flavour, errors):
189
313
for test, err in errors:
200
324
self.stream.writeln("%s" % err)
203
class TextTestRunner(unittest.TextTestRunner):
327
class TextTestRunner(object):
204
328
stop_on_failure = False
337
self.stream = unittest._WritelnDecorator(stream)
338
self.descriptions = descriptions
339
self.verbosity = verbosity
340
self.keep_output = keep_output
342
self._bench_history = bench_history
206
344
def _makeResult(self):
207
result = _MyResult(self.stream, self.descriptions, self.verbosity)
345
result = _MyResult(self.stream,
349
bench_history=self._bench_history)
208
350
result.stop_early = self.stop_on_failure
354
"Run the given test case or test suite."
355
result = self._makeResult()
356
startTime = time.time()
357
if self.pb is not None:
358
self.pb.update('Running tests', 0, test.countTestCases())
360
stopTime = time.time()
361
timeTaken = stopTime - startTime
363
self.stream.writeln(result.separator2)
364
run = result.testsRun
365
self.stream.writeln("Ran %d test%s in %.3fs" %
366
(run, run != 1 and "s" or "", timeTaken))
367
self.stream.writeln()
368
if not result.wasSuccessful():
369
self.stream.write("FAILED (")
370
failed, errored = map(len, (result.failures, result.errors))
372
self.stream.write("failures=%d" % failed)
374
if failed: self.stream.write(", ")
375
self.stream.write("errors=%d" % errored)
376
self.stream.writeln(")")
378
self.stream.writeln("OK")
379
if self.pb is not None:
380
self.pb.update('Cleaning up', 0, 1)
381
# This is still a little bogus,
382
# but only a little. Folk not using our testrunner will
383
# have to delete their temp directories themselves.
384
test_root = TestCaseInTempDir.TEST_ROOT
385
if result.wasSuccessful() or not self.keep_output:
386
if test_root is not None:
387
# If LANG=C we probably have created some bogus paths
388
# which rmtree(unicode) will fail to delete
389
# so make sure we are using rmtree(str) to delete everything
390
# except on win32, where rmtree(str) will fail
391
# since it doesn't have the property of byte-stream paths
392
# (they are either ascii or mbcs)
393
if sys.platform == 'win32':
394
# make sure we are using the unicode win32 api
395
test_root = unicode(test_root)
397
test_root = test_root.encode(
398
sys.getfilesystemencoding())
399
osutils.rmtree(test_root)
401
if self.pb is not None:
402
self.pb.note("Failed tests working directories are in '%s'\n",
406
"Failed tests working directories are in '%s'\n" %
408
TestCaseInTempDir.TEST_ROOT = None
409
if self.pb is not None:
212
414
def iter_suite_tests(suite):
213
415
"""Return all tests in a suite, recursing through nested suites"""
341
579
def assertIsInstance(self, obj, kls):
342
580
"""Fail if obj is not an instance of kls"""
343
581
if not isinstance(obj, kls):
344
self.fail("%r is not an instance of %s" % (obj, kls))
582
self.fail("%r is an instance of %s rather than %s" % (
583
obj, obj.__class__, kls))
585
def _capture_warnings(self, a_callable, *args, **kwargs):
586
"""A helper for callDeprecated and applyDeprecated.
588
:param a_callable: A callable to call.
589
:param args: The positional arguments for the callable
590
:param kwargs: The keyword arguments for the callable
591
:return: A tuple (warnings, result). result is the result of calling
592
a_callable(*args, **kwargs).
595
def capture_warnings(msg, cls, stacklevel=None):
596
# we've hooked into a deprecation specific callpath,
597
# only deprecations should getting sent via it.
598
self.assertEqual(cls, DeprecationWarning)
599
local_warnings.append(msg)
600
original_warning_method = symbol_versioning.warn
601
symbol_versioning.set_warning_method(capture_warnings)
603
result = a_callable(*args, **kwargs)
605
symbol_versioning.set_warning_method(original_warning_method)
606
return (local_warnings, result)
608
def applyDeprecated(self, deprecation_format, a_callable, *args, **kwargs):
609
"""Call a deprecated callable without warning the user.
611
:param deprecation_format: The deprecation format that the callable
612
should have been deprecated with. This is the same type as the
613
parameter to deprecated_method/deprecated_function. If the
614
callable is not deprecated with this format, an assertion error
616
:param a_callable: A callable to call. This may be a bound method or
617
a regular function. It will be called with *args and **kwargs.
618
:param args: The positional arguments for the callable
619
:param kwargs: The keyword arguments for the callable
620
:return: The result of a_callable(*args, **kwargs)
622
call_warnings, result = self._capture_warnings(a_callable,
624
expected_first_warning = symbol_versioning.deprecation_string(
625
a_callable, deprecation_format)
626
if len(call_warnings) == 0:
627
self.fail("No assertion generated by call to %s" %
629
self.assertEqual(expected_first_warning, call_warnings[0])
632
def callDeprecated(self, expected, callable, *args, **kwargs):
633
"""Assert that a callable is deprecated in a particular way.
635
This is a very precise test for unusual requirements. The
636
applyDeprecated helper function is probably more suited for most tests
637
as it allows you to simply specify the deprecation format being used
638
and will ensure that that is issued for the function being called.
640
:param expected: a list of the deprecation warnings expected, in order
641
:param callable: The callable to call
642
:param args: The positional arguments for the callable
643
:param kwargs: The keyword arguments for the callable
645
call_warnings, result = self._capture_warnings(callable,
647
self.assertEqual(expected, call_warnings)
346
650
def _startLogFile(self):
347
651
"""Send bzr and test log messages to a temporary file.
383
688
'HOME': os.getcwd(),
384
689
'APPDATA': os.getcwd(),
691
'BZREMAIL': None, # may still be present in the environment
693
'BZR_PROGRESS_BAR': None,
388
695
self.__old_env = {}
389
696
self.addCleanup(self._restoreEnvironment)
390
697
for name, value in new_env.iteritems():
391
698
self._captureVar(name, value)
394
700
def _captureVar(self, name, newvalue):
395
"""Set an environment variable, preparing it to be reset when finished."""
396
self.__old_env[name] = os.environ.get(name, None)
398
if name in os.environ:
401
os.environ[name] = newvalue
404
def _restoreVar(name, value):
406
if name in os.environ:
409
os.environ[name] = value
701
"""Set an environment variable, and reset it when finished."""
702
self.__old_env[name] = osutils.set_or_unset_env(name, newvalue)
411
704
def _restoreEnvironment(self):
412
705
for name, value in self.__old_env.iteritems():
413
self._restoreVar(name, value)
706
osutils.set_or_unset_env(name, value)
415
708
def tearDown(self):
416
709
self._runCleanups()
417
710
unittest.TestCase.tearDown(self)
712
def time(self, callable, *args, **kwargs):
713
"""Run callable and accrue the time it takes to the benchmark time.
715
If lsprofiling is enabled (i.e. by --lsprof-time to bzr selftest) then
716
this will cause lsprofile statistics to be gathered and stored in
719
if self._benchtime is None:
723
if not self._gather_lsprof_in_benchmarks:
724
return callable(*args, **kwargs)
726
# record this benchmark
727
ret, stats = bzrlib.lsprof.profile(callable, *args, **kwargs)
729
self._benchcalls.append(((callable, args, kwargs), stats))
732
self._benchtime += time.time() - start
419
734
def _runCleanups(self):
420
735
"""Run registered cleanup functions.
458
773
errors, and with logging set to something approximating the
459
774
default, so that error reporting can be checked.
461
argv -- arguments to invoke bzr
462
retcode -- expected return code, or None for don't-care.
776
:param argv: arguments to invoke bzr
777
:param retcode: expected return code, or None for don't-care.
778
:param encoding: encoding for sys.stdout and sys.stderr
779
:param stdin: A string to be used as stdin for the command.
466
self.log('run bzr: %s', ' '.join(argv))
782
encoding = bzrlib.user_encoding
783
if stdin is not None:
784
stdin = StringIO(stdin)
785
stdout = StringIOWrapper()
786
stderr = StringIOWrapper()
787
stdout.encoding = encoding
788
stderr.encoding = encoding
790
self.log('run bzr: %r', argv)
467
791
# FIXME: don't call into logging here
468
792
handler = logging.StreamHandler(stderr)
469
handler.setFormatter(bzrlib.trace.QuietFormatter())
470
793
handler.setLevel(logging.INFO)
471
794
logger = logging.getLogger('')
472
795
logger.addHandler(handler)
796
old_ui_factory = bzrlib.ui.ui_factory
797
bzrlib.ui.ui_factory = bzrlib.tests.blackbox.TestUIFactory(
800
bzrlib.ui.ui_factory.stdin = stdin
474
result = self.apply_redirected(None, stdout, stderr,
802
result = self.apply_redirected(stdin, stdout, stderr,
475
803
bzrlib.commands.run_bzr_catch_errors,
478
806
logger.removeHandler(handler)
807
bzrlib.ui.ui_factory = old_ui_factory
479
809
out = stdout.getvalue()
480
810
err = stderr.getvalue()
482
self.log('output:\n%s', out)
812
self.log('output:\n%r', out)
484
self.log('errors:\n%s', err)
814
self.log('errors:\n%r', err)
485
815
if retcode is not None:
486
self.assertEquals(result, retcode)
816
self.assertEquals(retcode, result)
489
819
def run_bzr(self, *args, **kwargs):
496
826
This sends the stdout/stderr results into the test's log,
497
827
where it may be useful for debugging. See also run_captured.
829
:param stdin: A string to be used as stdin for the command.
499
831
retcode = kwargs.pop('retcode', 0)
500
return self.run_bzr_captured(args, retcode)
832
encoding = kwargs.pop('encoding', None)
833
stdin = kwargs.pop('stdin', None)
834
return self.run_bzr_captured(args, retcode=retcode, encoding=encoding, stdin=stdin)
836
def run_bzr_decode(self, *args, **kwargs):
837
if 'encoding' in kwargs:
838
encoding = kwargs['encoding']
840
encoding = bzrlib.user_encoding
841
return self.run_bzr(*args, **kwargs)[0].decode(encoding)
843
def run_bzr_error(self, error_regexes, *args, **kwargs):
844
"""Run bzr, and check that stderr contains the supplied regexes
846
:param error_regexes: Sequence of regular expressions which
847
must each be found in the error output. The relative ordering
849
:param args: command-line arguments for bzr
850
:param kwargs: Keyword arguments which are interpreted by run_bzr
851
This function changes the default value of retcode to be 3,
852
since in most cases this is run when you expect bzr to fail.
853
:return: (out, err) The actual output of running the command (in case you
854
want to do more inspection)
857
# Make sure that commit is failing because there is nothing to do
858
self.run_bzr_error(['no changes to commit'],
859
'commit', '-m', 'my commit comment')
860
# Make sure --strict is handling an unknown file, rather than
861
# giving us the 'nothing to do' error
862
self.build_tree(['unknown'])
863
self.run_bzr_error(['Commit refused because there are unknown files'],
864
'commit', '--strict', '-m', 'my commit comment')
866
kwargs.setdefault('retcode', 3)
867
out, err = self.run_bzr(*args, **kwargs)
868
for regex in error_regexes:
869
self.assertContainsRe(err, regex)
872
def run_bzr_subprocess(self, *args, **kwargs):
873
"""Run bzr in a subprocess for testing.
875
This starts a new Python interpreter and runs bzr in there.
876
This should only be used for tests that have a justifiable need for
877
this isolation: e.g. they are testing startup time, or signal
878
handling, or early startup code, etc. Subprocess code can't be
879
profiled or debugged so easily.
881
:param retcode: The status code that is expected. Defaults to 0. If
882
None is supplied, the status code is not checked.
883
:param env_changes: A dictionary which lists changes to environment
884
variables. A value of None will unset the env variable.
885
The values must be strings. The change will only occur in the
886
child, so you don't need to fix the environment after running.
887
:param universal_newlines: Convert CRLF => LF
889
env_changes = kwargs.get('env_changes', {})
890
process = self.start_bzr_subprocess(args, env_changes=env_changes)
891
# We distinguish between retcode=None and retcode not passed.
892
supplied_retcode = kwargs.get('retcode', 0)
893
return self.finish_bzr_subprocess(process, retcode=supplied_retcode,
894
universal_newlines=kwargs.get('universal_newlines', False),
897
def start_bzr_subprocess(self, process_args, env_changes=None,
898
skip_if_plan_to_signal=False):
899
"""Start bzr in a subprocess for testing.
901
This starts a new Python interpreter and runs bzr in there.
902
This should only be used for tests that have a justifiable need for
903
this isolation: e.g. they are testing startup time, or signal
904
handling, or early startup code, etc. Subprocess code can't be
905
profiled or debugged so easily.
907
:param process_args: a list of arguments to pass to the bzr executable,
908
for example `['--version']`.
909
:param env_changes: A dictionary which lists changes to environment
910
variables. A value of None will unset the env variable.
911
The values must be strings. The change will only occur in the
912
child, so you don't need to fix the environment after running.
913
:param skip_if_plan_to_signal: raise TestSkipped when true and os.kill
916
:returns: Popen object for the started process.
918
if skip_if_plan_to_signal:
919
if not getattr(os, 'kill', None):
920
raise TestSkipped("os.kill not available.")
922
if env_changes is None:
926
def cleanup_environment():
927
for env_var, value in env_changes.iteritems():
928
old_env[env_var] = osutils.set_or_unset_env(env_var, value)
930
def restore_environment():
931
for env_var, value in old_env.iteritems():
932
osutils.set_or_unset_env(env_var, value)
934
bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
935
if not os.path.isfile(bzr_path):
936
# We are probably installed. Assume sys.argv is the right file
937
bzr_path = sys.argv[0]
940
# win32 subprocess doesn't support preexec_fn
941
# so we will avoid using it on all platforms, just to
942
# make sure the code path is used, and we don't break on win32
943
cleanup_environment()
944
process = Popen([sys.executable, bzr_path] + list(process_args),
945
stdout=PIPE, stderr=PIPE)
947
restore_environment()
950
def finish_bzr_subprocess(self, process, retcode=0, send_signal=None,
951
universal_newlines=False, process_args=None):
952
"""Finish the execution of process.
954
:param process: the Popen object returned from start_bzr_subprocess.
955
:param retcode: The status code that is expected. Defaults to 0. If
956
None is supplied, the status code is not checked.
957
:param send_signal: an optional signal to send to the process.
958
:param universal_newlines: Convert CRLF => LF
959
:returns: (stdout, stderr)
961
if send_signal is not None:
962
os.kill(process.pid, send_signal)
963
out, err = process.communicate()
965
if universal_newlines:
966
out = out.replace('\r\n', '\n')
967
err = err.replace('\r\n', '\n')
969
if retcode is not None and retcode != process.returncode:
970
if process_args is None:
971
process_args = "(unknown args)"
972
mutter('Output of bzr %s:\n%s', process_args, out)
973
mutter('Error for bzr %s:\n%s', process_args, err)
974
self.fail('Command bzr %s failed with retcode %s != %s'
975
% (process_args, retcode, process.returncode))
502
978
def check_inventory_shape(self, inv, shape):
503
979
"""Compare an inventory to a list of expected names.
793
1291
self.assertTrue(t.is_readonly())
796
def make_branch(self, relpath):
1294
def make_branch(self, relpath, format=None):
797
1295
"""Create a branch on the transport at relpath."""
798
repo = self.make_repository(relpath)
1296
repo = self.make_repository(relpath, format=format)
799
1297
return repo.bzrdir.create_branch()
801
def make_bzrdir(self, relpath):
1299
def make_bzrdir(self, relpath, format=None):
803
url = self.get_url(relpath)
804
segments = relpath.split('/')
805
if segments and segments[-1] not in ('', '.'):
806
parent = self.get_url('/'.join(segments[:-1]))
807
t = get_transport(parent)
1301
# might be a relative or absolute path
1302
maybe_a_url = self.get_url(relpath)
1303
segments = maybe_a_url.rsplit('/', 1)
1304
t = get_transport(maybe_a_url)
1305
if len(segments) > 1 and segments[-1] not in ('', '.'):
809
t.mkdir(segments[-1])
810
1308
except errors.FileExists:
812
return bzrlib.bzrdir.BzrDir.create(url)
1311
format = bzrlib.bzrdir.BzrDirFormat.get_default_format()
1312
return format.initialize_on_transport(t)
813
1313
except errors.UninitializableFormat:
814
raise TestSkipped("Format %s is not initializable.")
1314
raise TestSkipped("Format %s is not initializable." % format)
816
def make_repository(self, relpath, shared=False):
1316
def make_repository(self, relpath, shared=False, format=None):
817
1317
"""Create a repository on our default transport at relpath."""
818
made_control = self.make_bzrdir(relpath)
1318
made_control = self.make_bzrdir(relpath, format=format)
819
1319
return made_control.create_repository(shared=shared)
821
def make_branch_and_tree(self, relpath):
1321
def make_branch_and_tree(self, relpath, format=None):
822
1322
"""Create a branch on the transport and a tree locally.
1324
If the transport is not a LocalTransport, the Tree can't be created on
1325
the transport. In that case the working tree is created in the local
1326
directory, and the returned tree's branch and repository will also be
1329
This will fail if the original default transport for this test
1330
case wasn't backed by the working directory, as the branch won't
1331
be on disk for us to open it.
1333
:param format: The BzrDirFormat.
1334
:returns: the WorkingTree.
826
1336
# TODO: always use the local disk path for the working tree,
827
1337
# this obviously requires a format that supports branch references
828
1338
# so check for that by checking bzrdir.BzrDirFormat.get_default_format()
830
b = self.make_branch(relpath)
1340
b = self.make_branch(relpath, format=format)
832
1342
return b.bzrdir.create_workingtree()
833
1343
except errors.NotLocalUrl:
834
# new formats - catch No tree error and create
835
# a branch reference and a checkout.
836
# old formats at that point - raise TestSkipped.
838
return WorkingTreeFormat2().initialize(bzrdir.BzrDir.open(relpath))
1344
# We can only make working trees locally at the moment. If the
1345
# transport can't support them, then reopen the branch on a local
1346
# transport, and create the working tree there.
1348
# Possibly we should instead keep
1349
# the non-disk-backed branch and create a local checkout?
1350
bd = bzrdir.BzrDir.open(relpath)
1351
return bd.create_workingtree()
840
1353
def assertIsDirectory(self, relpath, transport):
841
1354
"""Assert that relpath within transport is a directory.
883
1396
def run_suite(suite, name='test', verbose=False, pattern=".*",
884
1397
stop_on_failure=False, keep_output=False,
1398
transport=None, lsprof_timed=None, bench_history=None):
886
1399
TestCaseInTempDir._TEST_NAME = name
1400
TestCase._gather_lsprof_in_benchmarks = lsprof_timed
1406
pb = progress.ProgressBar()
891
1407
runner = TextTestRunner(stream=sys.stdout,
1409
verbosity=verbosity,
1410
keep_output=keep_output,
1412
bench_history=bench_history)
894
1413
runner.stop_on_failure=stop_on_failure
895
1414
if pattern != '.*':
896
1415
suite = filter_suite_by_re(suite, pattern)
897
1416
result = runner.run(suite)
898
# This is still a little bogus,
899
# but only a little. Folk not using our testrunner will
900
# have to delete their temp directories themselves.
901
test_root = TestCaseInTempDir.TEST_ROOT
902
if result.wasSuccessful() or not keep_output:
903
if test_root is not None:
904
print 'Deleting test root %s...' % test_root
906
shutil.rmtree(test_root)
910
print "Failed tests working directories are in '%s'\n" % TestCaseInTempDir.TEST_ROOT
911
1417
return result.wasSuccessful()
914
1420
def selftest(verbose=False, pattern=".*", stop_on_failure=True,
915
1421
keep_output=False,
1423
test_suite_factory=None,
1425
bench_history=None):
917
1426
"""Run the whole test suite under the enhanced runner"""
1427
# XXX: Very ugly way to do this...
1428
# Disable warning about old formats because we don't want it to disturb
1429
# any blackbox tests.
1430
from bzrlib import repository
1431
repository._deprecation_warning_done = True
918
1433
global default_transport
919
1434
if transport is None:
920
1435
transport = default_transport
921
1436
old_transport = default_transport
922
1437
default_transport = transport
1439
if test_suite_factory is None:
1440
suite = test_suite()
1442
suite = test_suite_factory()
925
1443
return run_suite(suite, 'testbzr', verbose=verbose, pattern=pattern,
926
1444
stop_on_failure=stop_on_failure, keep_output=keep_output,
1445
transport=transport,
1446
lsprof_timed=lsprof_timed,
1447
bench_history=bench_history)
929
1449
default_transport = old_transport
933
1452
def test_suite():
934
"""Build and return TestSuite for the whole program."""
935
from doctest import DocTestSuite
937
global MODULES_TO_DOCTEST
1453
"""Build and return TestSuite for the whole of bzrlib.
1455
This function can be replaced if you need to change the default test
1456
suite on a global basis, but it is not encouraged.
940
1459
'bzrlib.tests.test_ancestry',
941
'bzrlib.tests.test_annotate',
942
1460
'bzrlib.tests.test_api',
1461
'bzrlib.tests.test_atomicfile',
943
1462
'bzrlib.tests.test_bad_files',
944
'bzrlib.tests.test_basis_inventory',
945
1463
'bzrlib.tests.test_branch',
1464
'bzrlib.tests.test_bundle',
946
1465
'bzrlib.tests.test_bzrdir',
1466
'bzrlib.tests.test_cache_utf8',
947
1467
'bzrlib.tests.test_command',
948
1468
'bzrlib.tests.test_commit',
949
1469
'bzrlib.tests.test_commit_merge',
973
1496
'bzrlib.tests.test_nonascii',
974
1497
'bzrlib.tests.test_options',
975
1498
'bzrlib.tests.test_osutils',
1499
'bzrlib.tests.test_patch',
1500
'bzrlib.tests.test_patches',
976
1501
'bzrlib.tests.test_permissions',
977
1502
'bzrlib.tests.test_plugins',
978
1503
'bzrlib.tests.test_progress',
979
1504
'bzrlib.tests.test_reconcile',
980
1505
'bzrlib.tests.test_repository',
1506
'bzrlib.tests.test_revert',
981
1507
'bzrlib.tests.test_revision',
982
1508
'bzrlib.tests.test_revisionnamespaces',
983
'bzrlib.tests.test_revprops',
1509
'bzrlib.tests.test_revisiontree',
984
1510
'bzrlib.tests.test_rio',
985
1511
'bzrlib.tests.test_sampler',
986
1512
'bzrlib.tests.test_selftest',
987
1513
'bzrlib.tests.test_setup',
988
1514
'bzrlib.tests.test_sftp_transport',
1515
'bzrlib.tests.test_ftp_transport',
989
1516
'bzrlib.tests.test_smart_add',
990
1517
'bzrlib.tests.test_source',
1518
'bzrlib.tests.test_status',
991
1519
'bzrlib.tests.test_store',
992
1520
'bzrlib.tests.test_symbol_versioning',
993
1521
'bzrlib.tests.test_testament',
1522
'bzrlib.tests.test_textfile',
1523
'bzrlib.tests.test_textmerge',
994
1524
'bzrlib.tests.test_trace',
995
1525
'bzrlib.tests.test_transactions',
996
1526
'bzrlib.tests.test_transform',
997
1527
'bzrlib.tests.test_transport',
1528
'bzrlib.tests.test_tree',
998
1529
'bzrlib.tests.test_tsort',
1530
'bzrlib.tests.test_tuned_gzip',
999
1531
'bzrlib.tests.test_ui',
1000
1532
'bzrlib.tests.test_upgrade',
1533
'bzrlib.tests.test_urlutils',
1001
1534
'bzrlib.tests.test_versionedfile',
1535
'bzrlib.tests.test_version',
1002
1536
'bzrlib.tests.test_weave',
1003
1537
'bzrlib.tests.test_whitebox',
1004
1538
'bzrlib.tests.test_workingtree',
1005
1539
'bzrlib.tests.test_xml',
1007
1541
test_transport_implementations = [
1008
'bzrlib.tests.test_transport_implementations']
1010
TestCase.BZRPATH = osutils.pathjoin(
1011
osutils.realpath(osutils.dirname(bzrlib.__path__[0])), 'bzr')
1012
print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
1013
print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
1016
# python2.4's TestLoader.loadTestsFromNames gives very poor
1017
# errors if it fails to load a named module - no indication of what's
1018
# actually wrong, just "no such module". We should probably override that
1019
# class, but for the moment just load them ourselves. (mbp 20051202)
1020
loader = TestLoader()
1542
'bzrlib.tests.test_transport_implementations',
1543
'bzrlib.tests.test_read_bundle',
1545
suite = TestUtil.TestSuite()
1546
loader = TestUtil.TestLoader()
1547
suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
1021
1548
from bzrlib.transport import TransportTestProviderAdapter
1022
1549
adapter = TransportTestProviderAdapter()
1023
1550
adapt_modules(test_transport_implementations, adapter, loader, suite)
1024
for mod_name in testmod_names:
1025
mod = _load_module_by_name(mod_name)
1026
suite.addTest(loader.loadTestsFromModule(mod))
1027
1551
for package in packages_to_test():
1028
1552
suite.addTest(package.test_suite())
1029
1553
for m in MODULES_TO_TEST:
1030
1554
suite.addTest(loader.loadTestsFromModule(m))
1031
for m in (MODULES_TO_DOCTEST):
1032
suite.addTest(DocTestSuite(m))
1555
for m in MODULES_TO_DOCTEST:
1556
suite.addTest(doctest.DocTestSuite(m))
1033
1557
for name, plugin in bzrlib.plugin.all_plugins().items():
1034
1558
if getattr(plugin, 'test_suite', None) is not None:
1035
1559
suite.addTest(plugin.test_suite())