31
33
from cStringIO import StringIO
37
from pprint import pformat
42
from subprocess import Popen, PIPE
56
# nb: check this before importing anything else from within it
57
_testtools_version = getattr(testtools, '__version__', ())
58
if _testtools_version < (0, 9, 5):
59
raise ImportError("need at least testtools 0.9.5: %s is %r"
60
% (testtools.__file__, _testtools_version))
61
from testtools import content
51
64
from bzrlib import (
68
commands as _mod_commands,
77
plugin as _mod_plugin,
84
transport as _mod_transport,
66
import bzrlib.commands
67
import bzrlib.timestamp
69
import bzrlib.inventory
70
import bzrlib.iterablefile
73
88
import bzrlib.lsprof
74
89
except ImportError:
75
90
# lsprof not available
77
from bzrlib.merge import merge_inner
80
from bzrlib.smart import client, server
82
from bzrlib import symbol_versioning
83
from bzrlib.symbol_versioning import (
90
from bzrlib.transport import get_transport
91
import bzrlib.transport
92
from bzrlib.transport.local import LocalURLServer
93
from bzrlib.transport.memory import MemoryServer
94
from bzrlib.transport.readonly import ReadonlyServer
95
from bzrlib.trace import mutter, note
96
from bzrlib.tests import TestUtil
97
from bzrlib.tests.http_server import HttpServer
98
from bzrlib.tests.TestUtil import (
102
from bzrlib.tests.treeshape import build_tree_contents
103
import bzrlib.version_info_formats.format_custom
104
from bzrlib.workingtree import WorkingTree, WorkingTreeFormat2
92
from bzrlib.smart import client, request
93
from bzrlib.transport import (
97
from bzrlib.tests import (
102
from bzrlib.ui import NullProgressView
103
from bzrlib.ui.text import TextUIFactory
106
105
# Mark this python module as being part of the implementation
107
106
# of unittest: this gives us better tracebacks where the last
108
107
# shown frame is the test code, not our assertXYZ.
111
default_transport = LocalURLServer
114
class ExtendedTestResult(unittest._TextTestResult):
110
default_transport = test_server.LocalURLServer
113
_unitialized_attr = object()
114
"""A sentinel needed to act as a default value in a method signature."""
117
# Subunit result codes, defined here to prevent a hard dependency on subunit.
121
# These are intentionally brought into this namespace. That way plugins, etc
122
# can just "from bzrlib.tests import TestCase, TestLoader, etc"
123
TestSuite = TestUtil.TestSuite
124
TestLoader = TestUtil.TestLoader
126
# Tests should run in a clean and clearly defined environment. The goal is to
127
# keep them isolated from the running environment as mush as possible. The test
128
# framework ensures the variables defined below are set (or deleted if the
129
# value is None) before a test is run and reset to their original value after
130
# the test is run. Generally if some code depends on an environment variable,
131
# the tests should start without this variable in the environment. There are a
132
# few exceptions but you shouldn't violate this rule lightly.
136
# bzr now uses the Win32 API and doesn't rely on APPDATA, but the
137
# tests do check our impls match APPDATA
138
'BZR_EDITOR': None, # test_msgeditor manipulates this variable
142
'BZREMAIL': None, # may still be present in the environment
143
'EMAIL': 'jrandom@example.com', # set EMAIL as bzr does not guess
144
'BZR_PROGRESS_BAR': None,
145
# This should trap leaks to ~/.bzr.log. This occurs when tests use TestCase
146
# as a base class instead of TestCaseInTempDir. Tests inheriting from
147
# TestCase should not use disk resources, BZR_LOG is one.
148
'BZR_LOG': '/you-should-use-TestCaseInTempDir-if-you-need-a-log-file',
149
'BZR_PLUGIN_PATH': None,
150
'BZR_DISABLE_PLUGINS': None,
151
'BZR_PLUGINS_AT': None,
152
'BZR_CONCURRENCY': None,
153
# Make sure that any text ui tests are consistent regardless of
154
# the environment the test case is run in; you may want tests that
155
# test other combinations. 'dumb' is a reasonable guess for tests
156
# going to a pipe or a StringIO.
162
'SSH_AUTH_SOCK': None,
172
# Nobody cares about ftp_proxy, FTP_PROXY AFAIK. So far at
173
# least. If you do (care), please update this comment
177
'BZR_REMOTE_PATH': None,
178
# Generally speaking, we don't want apport reporting on crashes in
179
# the test envirnoment unless we're specifically testing apport,
180
# so that it doesn't leak into the real system environment. We
181
# use an env var so it propagates to subprocesses.
182
'APPORT_DISABLE': '1',
186
def override_os_environ(test, env=None):
187
"""Modify os.environ keeping a copy.
189
:param test: A test instance
191
:param env: A dict containing variable definitions to be installed
194
env = isolated_environ
195
test._original_os_environ = dict([(var, value)
196
for var, value in os.environ.iteritems()])
197
for var, value in env.iteritems():
198
osutils.set_or_unset_env(var, value)
199
if var not in test._original_os_environ:
200
# The var is new, add it with a value of None, so
201
# restore_os_environ will delete it
202
test._original_os_environ[var] = None
205
def restore_os_environ(test):
206
"""Restore os.environ to its original state.
208
:param test: A test instance previously passed to override_os_environ.
210
for var, value in test._original_os_environ.iteritems():
211
# Restore the original value (or delete it if the value has been set to
212
# None in override_os_environ).
213
osutils.set_or_unset_env(var, value)
216
class ExtendedTestResult(testtools.TextTestResult):
115
217
"""Accepts, reports and accumulates the results of running tests.
117
219
Compared to the unittest version this class adds support for
164
266
self.unsupported = {}
166
268
self._overall_start_time = time.time()
168
def _extractBenchmarkTime(self, testCase):
269
self._strict = strict
270
self._first_thread_leaker_id = None
271
self._tests_leaking_threads_count = 0
272
self._traceback_from_test = None
274
def stopTestRun(self):
277
stopTime = time.time()
278
timeTaken = stopTime - self.startTime
279
# GZ 2010-07-19: Seems testtools has no printErrors method, and though
280
# the parent class method is similar have to duplicate
281
self._show_list('ERROR', self.errors)
282
self._show_list('FAIL', self.failures)
283
self.stream.write(self.sep2)
284
self.stream.write("%s %d test%s in %.3fs\n\n" % (actionTaken,
285
run, run != 1 and "s" or "", timeTaken))
286
if not self.wasSuccessful():
287
self.stream.write("FAILED (")
288
failed, errored = map(len, (self.failures, self.errors))
290
self.stream.write("failures=%d" % failed)
292
if failed: self.stream.write(", ")
293
self.stream.write("errors=%d" % errored)
294
if self.known_failure_count:
295
if failed or errored: self.stream.write(", ")
296
self.stream.write("known_failure_count=%d" %
297
self.known_failure_count)
298
self.stream.write(")\n")
300
if self.known_failure_count:
301
self.stream.write("OK (known_failures=%d)\n" %
302
self.known_failure_count)
304
self.stream.write("OK\n")
305
if self.skip_count > 0:
306
skipped = self.skip_count
307
self.stream.write('%d test%s skipped\n' %
308
(skipped, skipped != 1 and "s" or ""))
310
for feature, count in sorted(self.unsupported.items()):
311
self.stream.write("Missing feature '%s' skipped %d tests.\n" %
314
ok = self.wasStrictlySuccessful()
316
ok = self.wasSuccessful()
317
if self._first_thread_leaker_id:
319
'%s is leaking threads among %d leaking tests.\n' % (
320
self._first_thread_leaker_id,
321
self._tests_leaking_threads_count))
322
# We don't report the main thread as an active one.
324
'%d non-main threads were left active in the end.\n'
325
% (len(self._active_threads) - 1))
327
def getDescription(self, test):
330
def _extractBenchmarkTime(self, testCase, details=None):
169
331
"""Add a benchmark time for the current test case."""
332
if details and 'benchtime' in details:
333
return float(''.join(details['benchtime'].iter_bytes()))
170
334
return getattr(testCase, "_benchtime", None)
172
336
def _elapsedTestTimeString(self):
173
337
"""Return a time string for the overall time the current test has taken."""
174
return self._formatTime(time.time() - self._start_time)
338
return self._formatTime(self._delta_to_float(
339
self._now() - self._start_datetime))
176
341
def _testTimeString(self, testCase):
177
342
benchmark_time = self._extractBenchmarkTime(testCase)
178
343
if benchmark_time is not None:
180
self._formatTime(benchmark_time),
181
self._elapsedTestTimeString())
344
return self._formatTime(benchmark_time) + "*"
183
return " %s" % self._elapsedTestTimeString()
346
return self._elapsedTestTimeString()
185
348
def _formatTime(self, seconds):
186
349
"""Format seconds as milliseconds with leading spaces."""
191
354
def _shortened_test_description(self, test):
193
what = re.sub(r'^bzrlib\.(tests|benchmarks)\.', '', what)
356
what = re.sub(r'^bzrlib\.tests\.', '', what)
359
# GZ 2010-10-04: Cloned tests may end up harmlessly calling this method
360
# multiple times in a row, because the handler is added for
361
# each test but the container list is shared between cases.
362
# See lp:498869 lp:625574 and lp:637725 for background.
363
def _record_traceback_from_test(self, exc_info):
364
"""Store the traceback from passed exc_info tuple till"""
365
self._traceback_from_test = exc_info[2]
196
367
def startTest(self, test):
197
unittest.TestResult.startTest(self, test)
368
super(ExtendedTestResult, self).startTest(test)
198
372
self.report_test_start(test)
199
373
test.number = self.count
200
374
self._recordTestStartTime()
375
# Make testtools cases give us the real traceback on failure
376
addOnException = getattr(test, "addOnException", None)
377
if addOnException is not None:
378
addOnException(self._record_traceback_from_test)
379
# Only check for thread leaks on bzrlib derived test cases
380
if isinstance(test, TestCase):
381
test.addCleanup(self._check_leaked_threads, test)
383
def stopTest(self, test):
384
super(ExtendedTestResult, self).stopTest(test)
385
# Manually break cycles, means touching various private things but hey
386
getDetails = getattr(test, "getDetails", None)
387
if getDetails is not None:
389
# Clear _type_equality_funcs to try to stop TestCase instances
390
# from wasting memory. 'clear' is not available in all Python
391
# versions (bug 809048)
392
type_equality_funcs = getattr(test, "_type_equality_funcs", None)
393
if type_equality_funcs is not None:
394
tef_clear = getattr(type_equality_funcs, "clear", None)
395
if tef_clear is None:
396
tef_instance_dict = getattr(type_equality_funcs, "__dict__", None)
397
if tef_instance_dict is not None:
398
tef_clear = tef_instance_dict.clear
399
if tef_clear is not None:
401
self._traceback_from_test = None
403
def startTests(self):
404
self.report_tests_starting()
405
self._active_threads = threading.enumerate()
407
def _check_leaked_threads(self, test):
408
"""See if any threads have leaked since last call
410
A sample of live threads is stored in the _active_threads attribute,
411
when this method runs it compares the current live threads and any not
412
in the previous sample are treated as having leaked.
414
now_active_threads = set(threading.enumerate())
415
threads_leaked = now_active_threads.difference(self._active_threads)
417
self._report_thread_leak(test, threads_leaked, now_active_threads)
418
self._tests_leaking_threads_count += 1
419
if self._first_thread_leaker_id is None:
420
self._first_thread_leaker_id = test.id()
421
self._active_threads = now_active_threads
202
423
def _recordTestStartTime(self):
203
424
"""Record that a test has started."""
204
self._start_time = time.time()
206
def _cleanupLogFile(self, test):
207
# We can only do this if we have one of our TestCases, not if
209
setKeepLogfile = getattr(test, 'setKeepLogfile', None)
210
if setKeepLogfile is not None:
425
self._start_datetime = self._now()
213
427
def addError(self, test, err):
214
428
"""Tell result that test finished with an error.
235
443
Called from the TestCase run() method when the test
236
444
fails because e.g. an assert() method failed.
238
self._testConcluded(test)
239
if isinstance(err[1], KnownFailure):
240
return self._addKnownFailure(test, err)
242
unittest.TestResult.addFailure(self, test, err)
243
self.failure_count += 1
244
self.report_failure(test, err)
247
self._cleanupLogFile(test)
446
self._post_mortem(self._traceback_from_test)
447
super(ExtendedTestResult, self).addFailure(test, err)
448
self.failure_count += 1
449
self.report_failure(test, err)
249
def addSuccess(self, test):
453
def addSuccess(self, test, details=None):
250
454
"""Tell result that test completed successfully.
252
456
Called from the TestCase run()
254
self._testConcluded(test)
255
458
if self._bench_history is not None:
256
benchmark_time = self._extractBenchmarkTime(test)
459
benchmark_time = self._extractBenchmarkTime(test, details)
257
460
if benchmark_time is not None:
258
461
self._bench_history.write("%s %s\n" % (
259
462
self._formatTime(benchmark_time),
261
464
self.report_success(test)
262
self._cleanupLogFile(test)
263
unittest.TestResult.addSuccess(self, test)
465
super(ExtendedTestResult, self).addSuccess(test)
264
466
test._log_contents = ''
266
def _testConcluded(self, test):
267
"""Common code when a test has finished.
269
Called regardless of whether it succeded, failed, etc.
273
def _addKnownFailure(self, test, err):
468
def addExpectedFailure(self, test, err):
274
469
self.known_failure_count += 1
275
470
self.report_known_failure(test, err)
472
def addUnexpectedSuccess(self, test, details=None):
473
"""Tell result the test unexpectedly passed, counting as a failure
475
When the minimum version of testtools required becomes 0.9.8 this
476
can be updated to use the new handling there.
478
super(ExtendedTestResult, self).addFailure(test, details=details)
479
self.failure_count += 1
480
self.report_unexpected_success(test,
481
"".join(details["reason"].iter_text()))
277
485
def addNotSupported(self, test, feature):
278
486
"""The test will not be run because of a missing feature.
280
488
# this can be called in two different ways: it may be that the
281
# test started running, and then raised (through addError)
489
# test started running, and then raised (through requireFeature)
282
490
# UnavailableFeature. Alternatively this method can be called
283
# while probing for features before running the tests; in that
284
# case we will see startTest and stopTest, but the test will never
491
# while probing for features before running the test code proper; in
492
# that case we will see startTest and stopTest, but the test will
493
# never actually run.
286
494
self.unsupported.setdefault(str(feature), 0)
287
495
self.unsupported[str(feature)] += 1
288
496
self.report_unsupported(test, feature)
292
500
self.skip_count += 1
293
501
self.report_skip(test, reason)
295
def _addNotApplicable(self, test, skip_excinfo):
296
if isinstance(skip_excinfo[1], TestNotApplicable):
297
self.not_applicable_count += 1
298
self.report_not_applicable(test, skip_excinfo)
301
except KeyboardInterrupt:
304
self.addError(test, test.exc_info())
306
# seems best to treat this as success from point-of-view of unittest
307
# -- it actually does nothing so it barely matters :)
308
unittest.TestResult.addSuccess(self, test)
309
test._log_contents = ''
311
def printErrorList(self, flavour, errors):
312
for test, err in errors:
313
self.stream.writeln(self.separator1)
314
self.stream.write("%s: " % flavour)
315
self.stream.writeln(self.getDescription(test))
316
if getattr(test, '_get_log', None) is not None:
317
self.stream.write('\n')
319
('vvvv[log from %s]' % test.id()).ljust(78,'-'))
320
self.stream.write('\n')
321
self.stream.write(test._get_log())
322
self.stream.write('\n')
324
('^^^^[log from %s]' % test.id()).ljust(78,'-'))
325
self.stream.write('\n')
326
self.stream.writeln(self.separator2)
327
self.stream.writeln("%s" % err)
332
def report_cleaning_up(self):
503
def addNotApplicable(self, test, reason):
504
self.not_applicable_count += 1
505
self.report_not_applicable(test, reason)
507
def _post_mortem(self, tb=None):
508
"""Start a PDB post mortem session."""
509
if os.environ.get('BZR_TEST_PDB', None):
513
def progress(self, offset, whence):
514
"""The test is adjusting the count of tests to run."""
515
if whence == SUBUNIT_SEEK_SET:
516
self.num_tests = offset
517
elif whence == SUBUNIT_SEEK_CUR:
518
self.num_tests += offset
520
raise errors.BzrError("Unknown whence %r" % whence)
522
def report_tests_starting(self):
523
"""Display information before the test run begins"""
524
if getattr(sys, 'frozen', None) is None:
525
bzr_path = osutils.realpath(sys.argv[0])
527
bzr_path = sys.executable
529
'bzr selftest: %s\n' % (bzr_path,))
532
bzrlib.__path__[0],))
534
' bzr-%s python-%s %s\n' % (
535
bzrlib.version_string,
536
bzrlib._format_version_tuple(sys.version_info),
537
platform.platform(aliased=1),
539
self.stream.write('\n')
541
def report_test_start(self, test):
542
"""Display information on the test just about to be run"""
544
def _report_thread_leak(self, test, leaked_threads, active_threads):
545
"""Display information on a test that leaked one or more threads"""
546
# GZ 2010-09-09: A leak summary reported separately from the general
547
# thread debugging would be nice. Tests under subunit
548
# need something not using stream, perhaps adding a
549
# testtools details object would be fitting.
550
if 'threads' in selftest_debug_flags:
551
self.stream.write('%s is leaking, active is now %d\n' %
552
(test.id(), len(active_threads)))
554
def startTestRun(self):
555
self.startTime = time.time()
335
557
def report_success(self, test):
465
696
return '%s%s' % (indent, err[1])
467
698
def report_error(self, test, err):
468
self.stream.writeln('ERROR %s\n%s'
699
self.stream.write('ERROR %s\n%s\n'
469
700
% (self._testTimeString(test),
470
701
self._error_summary(err)))
472
703
def report_failure(self, test, err):
473
self.stream.writeln(' FAIL %s\n%s'
704
self.stream.write(' FAIL %s\n%s\n'
474
705
% (self._testTimeString(test),
475
706
self._error_summary(err)))
477
708
def report_known_failure(self, test, err):
478
self.stream.writeln('XFAIL %s\n%s'
709
self.stream.write('XFAIL %s\n%s\n'
479
710
% (self._testTimeString(test),
480
711
self._error_summary(err)))
713
def report_unexpected_success(self, test, reason):
714
self.stream.write(' FAIL %s\n%s: %s\n'
715
% (self._testTimeString(test),
716
"Unexpected success. Should have failed",
482
719
def report_success(self, test):
483
self.stream.writeln(' OK %s' % self._testTimeString(test))
720
self.stream.write(' OK %s\n' % self._testTimeString(test))
484
721
for bench_called, stats in getattr(test, '_benchcalls', []):
485
self.stream.writeln('LSProf output for %s(%s, %s)' % bench_called)
722
self.stream.write('LSProf output for %s(%s, %s)\n' % bench_called)
486
723
stats.pprint(file=self.stream)
487
724
# flush the stream so that we get smooth output. This verbose mode is
488
725
# used to show the output in PQM.
489
726
self.stream.flush()
491
728
def report_skip(self, test, reason):
492
self.stream.writeln(' SKIP %s\n%s'
729
self.stream.write(' SKIP %s\n%s\n'
493
730
% (self._testTimeString(test), reason))
495
def report_not_applicable(self, test, skip_excinfo):
496
self.stream.writeln(' N/A %s\n%s'
497
% (self._testTimeString(test),
498
self._error_summary(skip_excinfo)))
732
def report_not_applicable(self, test, reason):
733
self.stream.write(' N/A %s\n %s\n'
734
% (self._testTimeString(test), reason))
500
736
def report_unsupported(self, test, feature):
501
737
"""test cannot be run because feature is missing."""
502
self.stream.writeln("NODEP %s\n The feature '%s' is not available."
738
self.stream.write("NODEP %s\n The feature '%s' is not available.\n"
503
739
%(self._testTimeString(test), feature))
513
749
bench_history=None,
751
result_decorators=None,
516
self.stream = unittest._WritelnDecorator(stream)
753
"""Create a TextTestRunner.
755
:param result_decorators: An optional list of decorators to apply
756
to the result object being used by the runner. Decorators are
757
applied left to right - the first element in the list is the
760
# stream may know claim to know to write unicode strings, but in older
761
# pythons this goes sufficiently wrong that it is a bad idea. (
762
# specifically a built in file with encoding 'UTF-8' will still try
763
# to encode using ascii.
764
new_encoding = osutils.get_terminal_encoding()
765
codec = codecs.lookup(new_encoding)
766
if type(codec) is tuple:
770
encode = codec.encode
771
# GZ 2010-09-08: Really we don't want to be writing arbitrary bytes,
772
# so should swap to the plain codecs.StreamWriter
773
stream = osutils.UnicodeOrBytesToBytesWriter(encode, stream,
775
stream.encoding = new_encoding
517
777
self.descriptions = descriptions
518
778
self.verbosity = verbosity
519
779
self._bench_history = bench_history
520
self.list_only = list_only
780
self._strict = strict
781
self._result_decorators = result_decorators or []
522
783
def run(self, test):
523
784
"Run the given test case or test suite."
524
startTime = time.time()
525
785
if self.verbosity == 1:
526
786
result_class = TextTestResult
527
787
elif self.verbosity >= 2:
528
788
result_class = VerboseTestResult
529
result = result_class(self.stream,
789
original_result = result_class(self.stream,
530
790
self.descriptions,
532
792
bench_history=self._bench_history,
533
num_tests=test.countTestCases(),
535
result.stop_early = self.stop_on_failure
536
result.report_starting()
538
if self.verbosity >= 2:
539
self.stream.writeln("Listing tests only ...\n")
541
for t in iter_suite_tests(test):
542
self.stream.writeln("%s" % (t.id()))
544
actionTaken = "Listed"
795
# Signal to result objects that look at stop early policy to stop,
796
original_result.stop_early = self.stop_on_failure
797
result = original_result
798
for decorator in self._result_decorators:
799
result = decorator(result)
800
result.stop_early = self.stop_on_failure
801
result.startTestRun()
547
run = result.testsRun
549
stopTime = time.time()
550
timeTaken = stopTime - startTime
552
self.stream.writeln(result.separator2)
553
self.stream.writeln("%s %d test%s in %.3fs" % (actionTaken,
554
run, run != 1 and "s" or "", timeTaken))
555
self.stream.writeln()
556
if not result.wasSuccessful():
557
self.stream.write("FAILED (")
558
failed, errored = map(len, (result.failures, result.errors))
560
self.stream.write("failures=%d" % failed)
562
if failed: self.stream.write(", ")
563
self.stream.write("errors=%d" % errored)
564
if result.known_failure_count:
565
if failed or errored: self.stream.write(", ")
566
self.stream.write("known_failure_count=%d" %
567
result.known_failure_count)
568
self.stream.writeln(")")
570
if result.known_failure_count:
571
self.stream.writeln("OK (known_failures=%d)" %
572
result.known_failure_count)
574
self.stream.writeln("OK")
575
if result.skip_count > 0:
576
skipped = result.skip_count
577
self.stream.writeln('%d test%s skipped' %
578
(skipped, skipped != 1 and "s" or ""))
579
if result.unsupported:
580
for feature, count in sorted(result.unsupported.items()):
581
self.stream.writeln("Missing feature '%s' skipped %d tests." %
806
# higher level code uses our extended protocol to determine
807
# what exit code to give.
808
return original_result
587
811
def iter_suite_tests(suite):
744
962
routine, and to build and check bzr trees.
746
964
In addition to the usual method of overriding tearDown(), this class also
747
allows subclasses to register functions into the _cleanups list, which is
965
allows subclasses to register cleanup functions via addCleanup, which are
748
966
run in order as the object is torn down. It's less likely this will be
749
967
accidentally overlooked.
752
_active_threads = None
753
_leaking_threads_tests = 0
754
_first_thread_leaker_id = None
755
_log_file_name = None
757
_keep_log_file = False
758
971
# record lsprof data when performing benchmark calls.
759
972
_gather_lsprof_in_benchmarks = False
760
attrs_to_keep = ('id', '_testMethodName', '_testMethodDoc',
761
'_log_contents', '_log_file_name', '_benchtime',
762
'_TestCase__testMethodName')
764
974
def __init__(self, methodName='testMethod'):
765
975
super(TestCase, self).__init__(methodName)
767
self._bzr_test_setUp_run = False
768
self._bzr_test_tearDown_run = False
976
self._directory_isolation = True
977
self.exception_handlers.insert(0,
978
(UnavailableFeature, self._do_unsupported_or_skip))
979
self.exception_handlers.insert(0,
980
(TestNotApplicable, self._do_not_applicable))
771
unittest.TestCase.setUp(self)
772
self._bzr_test_setUp_run = True
983
super(TestCase, self).setUp()
984
for feature in getattr(self, '_test_needs_features', []):
985
self.requireFeature(feature)
773
986
self._cleanEnvironment()
774
987
self._silenceUI()
775
988
self._startLogFile()
776
989
self._benchcalls = []
777
990
self._benchtime = None
778
991
self._clear_hooks()
992
self._track_transports()
779
994
self._clear_debug_flags()
780
TestCase._active_threads = threading.activeCount()
781
self.addCleanup(self._check_leaked_threads)
995
# Isolate global verbosity level, to make sure it's reproducible
996
# between tests. We should get rid of this altogether: bug 656694. --
998
self.overrideAttr(bzrlib.trace, '_verbosity_level', 0)
999
# Isolate config option expansion until its default value for bzrlib is
1000
# settled on or a the FIXME associated with _get_expand_default_value
1001
# is addressed -- vila 20110219
1002
self.overrideAttr(config, '_expand_default_value', None)
1003
self._log_files = set()
1004
# Each key in the ``_counters`` dict holds a value for a different
1005
# counter. When the test ends, addDetail() should be used to output the
1006
# counter values. This happens in install_counter_hook().
1008
if 'config_stats' in selftest_debug_flags:
1009
self._install_config_stats_hooks()
783
1011
def debug(self):
784
1012
# debug a frame up.
786
1014
pdb.Pdb().set_trace(sys._getframe().f_back)
789
absent_attr = object()
790
exc_info = getattr(self, '_exc_info', absent_attr)
791
if exc_info is absent_attr:
792
exc_info = getattr(self, '_TestCase__exc_info')
795
def _check_leaked_threads(self):
796
active = threading.activeCount()
797
leaked_threads = active - TestCase._active_threads
798
TestCase._active_threads = active
800
TestCase._leaking_threads_tests += 1
801
if TestCase._first_thread_leaker_id is None:
802
TestCase._first_thread_leaker_id = self.id()
803
# we're not specifically told when all tests are finished.
804
# This will do. We use a function to avoid keeping a reference
805
# to a TestCase object.
806
atexit.register(_report_leaked_threads)
1016
def discardDetail(self, name):
1017
"""Extend the addDetail, getDetails api so we can remove a detail.
1019
eg. bzr always adds the 'log' detail at startup, but we don't want to
1020
include it for skipped, xfail, etc tests.
1022
It is safe to call this for a detail that doesn't exist, in case this
1023
gets called multiple times.
1025
# We cheat. details is stored in __details which means we shouldn't
1026
# touch it. but getDetails() returns the dict directly, so we can
1028
details = self.getDetails()
1032
def install_counter_hook(self, hooks, name, counter_name=None):
1033
"""Install a counting hook.
1035
Any hook can be counted as long as it doesn't need to return a value.
1037
:param hooks: Where the hook should be installed.
1039
:param name: The hook name that will be counted.
1041
:param counter_name: The counter identifier in ``_counters``, defaults
1044
_counters = self._counters # Avoid closing over self
1045
if counter_name is None:
1047
if _counters.has_key(counter_name):
1048
raise AssertionError('%s is already used as a counter name'
1050
_counters[counter_name] = 0
1051
self.addDetail(counter_name, content.Content(content.UTF8_TEXT,
1052
lambda: ['%d' % (_counters[counter_name],)]))
1053
def increment_counter(*args, **kwargs):
1054
_counters[counter_name] += 1
1055
label = 'count %s calls' % (counter_name,)
1056
hooks.install_named_hook(name, increment_counter, label)
1057
self.addCleanup(hooks.uninstall_named_hook, name, label)
1059
def _install_config_stats_hooks(self):
1060
"""Install config hooks to count hook calls.
1063
for hook_name in ('get', 'set', 'remove', 'load', 'save'):
1064
self.install_counter_hook(config.ConfigHooks, hook_name,
1065
'config.%s' % (hook_name,))
1067
# The OldConfigHooks are private and need special handling to protect
1068
# against recursive tests (tests that run other tests), so we just do
1069
# manually what registering them into _builtin_known_hooks will provide
1071
self.overrideAttr(config, 'OldConfigHooks', config._OldConfigHooks())
1072
for hook_name in ('get', 'set', 'remove', 'load', 'save'):
1073
self.install_counter_hook(config.OldConfigHooks, hook_name,
1074
'old_config.%s' % (hook_name,))
808
1076
def _clear_debug_flags(self):
809
1077
"""Prevent externally set debug flags affecting tests.
811
1079
Tests that want to use debug flags can just set them in the
812
1080
debug_flags set during setup/teardown.
814
self._preserved_debug_flags = set(debug.debug_flags)
1082
# Start with a copy of the current debug flags we can safely modify.
1083
self.overrideAttr(debug, 'debug_flags', set(debug.debug_flags))
815
1084
if 'allow_debug' not in selftest_debug_flags:
816
1085
debug.debug_flags.clear()
817
self.addCleanup(self._restore_debug_flags)
1086
if 'disable_lock_checks' not in selftest_debug_flags:
1087
debug.debug_flags.add('strict_locks')
819
1089
def _clear_hooks(self):
820
1090
# prevent hooks affecting tests
1091
known_hooks = hooks.known_hooks
821
1092
self._preserved_hooks = {}
822
for key, factory in hooks.known_hooks.items():
823
parent, name = hooks.known_hooks_key_to_parent_and_attribute(key)
824
current_hooks = hooks.known_hooks_key_to_object(key)
1093
for key, (parent, name) in known_hooks.iter_parent_objects():
1094
current_hooks = getattr(parent, name)
825
1095
self._preserved_hooks[parent] = (name, current_hooks)
1096
self._preserved_lazy_hooks = hooks._lazy_hooks
1097
hooks._lazy_hooks = {}
826
1098
self.addCleanup(self._restoreHooks)
827
for key, factory in hooks.known_hooks.items():
828
parent, name = hooks.known_hooks_key_to_parent_and_attribute(key)
1099
for key, (parent, name) in known_hooks.iter_parent_objects():
1100
factory = known_hooks.get(key)
829
1101
setattr(parent, name, factory())
1102
# this hook should always be installed
1103
request._install_hook()
1105
def disable_directory_isolation(self):
1106
"""Turn off directory isolation checks."""
1107
self._directory_isolation = False
1109
def enable_directory_isolation(self):
1110
"""Enable directory isolation checks."""
1111
self._directory_isolation = True
831
1113
def _silenceUI(self):
832
1114
"""Turn off UI for duration of test"""
833
1115
# by default the UI is off; tests can turn it on if they want it.
834
saved = ui.ui_factory
836
ui.ui_factory = saved
837
ui.ui_factory = ui.SilentUIFactory()
838
self.addCleanup(_restore)
1116
self.overrideAttr(ui, 'ui_factory', ui.SilentUIFactory())
1118
def _check_locks(self):
1119
"""Check that all lock take/release actions have been paired."""
1120
# We always check for mismatched locks. If a mismatch is found, we
1121
# fail unless -Edisable_lock_checks is supplied to selftest, in which
1122
# case we just print a warning.
1124
acquired_locks = [lock for action, lock in self._lock_actions
1125
if action == 'acquired']
1126
released_locks = [lock for action, lock in self._lock_actions
1127
if action == 'released']
1128
broken_locks = [lock for action, lock in self._lock_actions
1129
if action == 'broken']
1130
# trivially, given the tests for lock acquistion and release, if we
1131
# have as many in each list, it should be ok. Some lock tests also
1132
# break some locks on purpose and should be taken into account by
1133
# considering that breaking a lock is just a dirty way of releasing it.
1134
if len(acquired_locks) != (len(released_locks) + len(broken_locks)):
1136
'Different number of acquired and '
1137
'released or broken locks.\n'
1141
(acquired_locks, released_locks, broken_locks))
1142
if not self._lock_check_thorough:
1143
# Rather than fail, just warn
1144
print "Broken test %s: %s" % (self, message)
1148
def _track_locks(self):
1149
"""Track lock activity during tests."""
1150
self._lock_actions = []
1151
if 'disable_lock_checks' in selftest_debug_flags:
1152
self._lock_check_thorough = False
1154
self._lock_check_thorough = True
1156
self.addCleanup(self._check_locks)
1157
_mod_lock.Lock.hooks.install_named_hook('lock_acquired',
1158
self._lock_acquired, None)
1159
_mod_lock.Lock.hooks.install_named_hook('lock_released',
1160
self._lock_released, None)
1161
_mod_lock.Lock.hooks.install_named_hook('lock_broken',
1162
self._lock_broken, None)
1164
def _lock_acquired(self, result):
1165
self._lock_actions.append(('acquired', result))
1167
def _lock_released(self, result):
1168
self._lock_actions.append(('released', result))
1170
def _lock_broken(self, result):
1171
self._lock_actions.append(('broken', result))
1173
def permit_dir(self, name):
1174
"""Permit a directory to be used by this test. See permit_url."""
1175
name_transport = _mod_transport.get_transport(name)
1176
self.permit_url(name)
1177
self.permit_url(name_transport.base)
1179
def permit_url(self, url):
1180
"""Declare that url is an ok url to use in this test.
1182
Do this for memory transports, temporary test directory etc.
1184
Do not do this for the current working directory, /tmp, or any other
1185
preexisting non isolated url.
1187
if not url.endswith('/'):
1189
self._bzr_selftest_roots.append(url)
1191
def permit_source_tree_branch_repo(self):
1192
"""Permit the source tree bzr is running from to be opened.
1194
Some code such as bzrlib.version attempts to read from the bzr branch
1195
that bzr is executing from (if any). This method permits that directory
1196
to be used in the test suite.
1198
path = self.get_source_path()
1199
self.record_directory_isolation()
1202
workingtree.WorkingTree.open(path)
1203
except (errors.NotBranchError, errors.NoWorkingTree):
1204
raise TestSkipped('Needs a working tree of bzr sources')
1206
self.enable_directory_isolation()
1208
def _preopen_isolate_transport(self, transport):
1209
"""Check that all transport openings are done in the test work area."""
1210
while isinstance(transport, pathfilter.PathFilteringTransport):
1211
# Unwrap pathfiltered transports
1212
transport = transport.server.backing_transport.clone(
1213
transport._filter('.'))
1214
url = transport.base
1215
# ReadonlySmartTCPServer_for_testing decorates the backing transport
1216
# urls it is given by prepending readonly+. This is appropriate as the
1217
# client shouldn't know that the server is readonly (or not readonly).
1218
# We could register all servers twice, with readonly+ prepending, but
1219
# that makes for a long list; this is about the same but easier to
1221
if url.startswith('readonly+'):
1222
url = url[len('readonly+'):]
1223
self._preopen_isolate_url(url)
1225
def _preopen_isolate_url(self, url):
1226
if not self._directory_isolation:
1228
if self._directory_isolation == 'record':
1229
self._bzr_selftest_roots.append(url)
1231
# This prevents all transports, including e.g. sftp ones backed on disk
1232
# from working unless they are explicitly granted permission. We then
1233
# depend on the code that sets up test transports to check that they are
1234
# appropriately isolated and enable their use by calling
1235
# self.permit_transport()
1236
if not osutils.is_inside_any(self._bzr_selftest_roots, url):
1237
raise errors.BzrError("Attempt to escape test isolation: %r %r"
1238
% (url, self._bzr_selftest_roots))
1240
def record_directory_isolation(self):
1241
"""Gather accessed directories to permit later access.
1243
This is used for tests that access the branch bzr is running from.
1245
self._directory_isolation = "record"
1247
def start_server(self, transport_server, backing_server=None):
1248
"""Start transport_server for this test.
1250
This starts the server, registers a cleanup for it and permits the
1251
server's urls to be used.
1253
if backing_server is None:
1254
transport_server.start_server()
1256
transport_server.start_server(backing_server)
1257
self.addCleanup(transport_server.stop_server)
1258
# Obtain a real transport because if the server supplies a password, it
1259
# will be hidden from the base on the client side.
1260
t = _mod_transport.get_transport(transport_server.get_url())
1261
# Some transport servers effectively chroot the backing transport;
1262
# others like SFTPServer don't - users of the transport can walk up the
1263
# transport to read the entire backing transport. This wouldn't matter
1264
# except that the workdir tests are given - and that they expect the
1265
# server's url to point at - is one directory under the safety net. So
1266
# Branch operations into the transport will attempt to walk up one
1267
# directory. Chrooting all servers would avoid this but also mean that
1268
# we wouldn't be testing directly against non-root urls. Alternatively
1269
# getting the test framework to start the server with a backing server
1270
# at the actual safety net directory would work too, but this then
1271
# means that the self.get_url/self.get_transport methods would need
1272
# to transform all their results. On balance its cleaner to handle it
1273
# here, and permit a higher url when we have one of these transports.
1274
if t.base.endswith('/work/'):
1275
# we have safety net/test root/work
1276
t = t.clone('../..')
1277
elif isinstance(transport_server,
1278
test_server.SmartTCPServer_for_testing):
1279
# The smart server adds a path similar to work, which is traversed
1280
# up from by the client. But the server is chrooted - the actual
1281
# backing transport is not escaped from, and VFS requests to the
1282
# root will error (because they try to escape the chroot).
1284
while t2.base != t.base:
1287
self.permit_url(t.base)
1289
def _track_transports(self):
1290
"""Install checks for transport usage."""
1291
# TestCase has no safe place it can write to.
1292
self._bzr_selftest_roots = []
1293
# Currently the easiest way to be sure that nothing is going on is to
1294
# hook into bzr dir opening. This leaves a small window of error for
1295
# transport tests, but they are well known, and we can improve on this
1297
bzrdir.BzrDir.hooks.install_named_hook("pre_open",
1298
self._preopen_isolate_transport, "Check bzr directories are safe.")
840
1300
def _ndiff_strings(self, a, b):
841
1301
"""Return ndiff between two strings containing lines.
1212
1703
The file is removed as the test is torn down.
1214
fileno, name = tempfile.mkstemp(suffix='.log', prefix='testbzr')
1215
self._log_file = os.fdopen(fileno, 'w+')
1216
self._log_memento = bzrlib.trace.push_log_file(self._log_file)
1217
self._log_file_name = name
1705
pseudo_log_file = StringIO()
1706
def _get_log_contents_for_weird_testtools_api():
1707
return [pseudo_log_file.getvalue().decode(
1708
"utf-8", "replace").encode("utf-8")]
1709
self.addDetail("log", content.Content(content.ContentType("text",
1710
"plain", {"charset": "utf8"}),
1711
_get_log_contents_for_weird_testtools_api))
1712
self._log_file = pseudo_log_file
1713
self._log_memento = trace.push_log_file(self._log_file)
1218
1714
self.addCleanup(self._finishLogFile)
1220
1716
def _finishLogFile(self):
1221
1717
"""Finished with the log file.
1223
Close the file and delete it, unless setKeepLogfile was called.
1225
if self._log_file is None:
1227
bzrlib.trace.pop_log_file(self._log_memento)
1228
self._log_file.close()
1229
self._log_file = None
1230
if not self._keep_log_file:
1231
os.remove(self._log_file_name)
1232
self._log_file_name = None
1234
def setKeepLogfile(self):
1235
"""Make the logfile not be deleted when _finishLogFile is called."""
1236
self._keep_log_file = True
1238
def addCleanup(self, callable, *args, **kwargs):
1239
"""Arrange to run a callable when this case is torn down.
1241
Callables are run in the reverse of the order they are registered,
1242
ie last-in first-out.
1244
self._cleanups.append((callable, args, kwargs))
1719
Close the file and delete it.
1721
if trace._trace_file:
1722
# flush the log file, to get all content
1723
trace._trace_file.flush()
1724
trace.pop_log_file(self._log_memento)
1726
def thisFailsStrictLockCheck(self):
1727
"""It is known that this test would fail with -Dstrict_locks.
1729
By default, all tests are run with strict lock checking unless
1730
-Edisable_lock_checks is supplied. However there are some tests which
1731
we know fail strict locks at this point that have not been fixed.
1732
They should call this function to disable the strict checking.
1734
This should be used sparingly, it is much better to fix the locking
1735
issues rather than papering over the problem by calling this function.
1737
debug.debug_flags.discard('strict_locks')
1739
def overrideAttr(self, obj, attr_name, new=_unitialized_attr):
1740
"""Overrides an object attribute restoring it after the test.
1742
:note: This should be used with discretion; you should think about
1743
whether it's better to make the code testable without monkey-patching.
1745
:param obj: The object that will be mutated.
1747
:param attr_name: The attribute name we want to preserve/override in
1750
:param new: The optional value we want to set the attribute to.
1752
:returns: The actual attr value.
1754
value = getattr(obj, attr_name)
1755
# The actual value is captured by the call below
1756
self.addCleanup(setattr, obj, attr_name, value)
1757
if new is not _unitialized_attr:
1758
setattr(obj, attr_name, new)
1761
def overrideEnv(self, name, new):
1762
"""Set an environment variable, and reset it after the test.
1764
:param name: The environment variable name.
1766
:param new: The value to set the variable to. If None, the
1767
variable is deleted from the environment.
1769
:returns: The actual variable value.
1771
value = osutils.set_or_unset_env(name, new)
1772
self.addCleanup(osutils.set_or_unset_env, name, value)
1775
def recordCalls(self, obj, attr_name):
1776
"""Monkeypatch in a wrapper that will record calls.
1778
The monkeypatch is automatically removed when the test concludes.
1780
:param obj: The namespace holding the reference to be replaced;
1781
typically a module, class, or object.
1782
:param attr_name: A string for the name of the attribute to
1784
:returns: A list that will be extended with one item every time the
1785
function is called, with a tuple of (args, kwargs).
1789
def decorator(*args, **kwargs):
1790
calls.append((args, kwargs))
1791
return orig(*args, **kwargs)
1792
orig = self.overrideAttr(obj, attr_name, decorator)
1246
1795
def _cleanEnvironment(self):
1248
'BZR_HOME': None, # Don't inherit BZR_HOME to all the tests.
1249
'HOME': os.getcwd(),
1250
# bzr now uses the Win32 API and doesn't rely on APPDATA, but the
1251
# tests do check our impls match APPDATA
1252
'BZR_EDITOR': None, # test_msgeditor manipulates this variable
1254
'BZREMAIL': None, # may still be present in the environment
1256
'BZR_PROGRESS_BAR': None,
1258
'BZR_PLUGIN_PATH': None,
1260
'SSH_AUTH_SOCK': None,
1264
'https_proxy': None,
1265
'HTTPS_PROXY': None,
1270
# Nobody cares about these ones AFAIK. So far at
1271
# least. If you do (care), please update this comment
1275
'BZR_REMOTE_PATH': None,
1278
self.addCleanup(self._restoreEnvironment)
1279
for name, value in new_env.iteritems():
1280
self._captureVar(name, value)
1282
def _captureVar(self, name, newvalue):
1283
"""Set an environment variable, and reset it when finished."""
1284
self.__old_env[name] = osutils.set_or_unset_env(name, newvalue)
1286
def _restore_debug_flags(self):
1287
debug.debug_flags.clear()
1288
debug.debug_flags.update(self._preserved_debug_flags)
1290
def _restoreEnvironment(self):
1291
for name, value in self.__old_env.iteritems():
1292
osutils.set_or_unset_env(name, value)
1796
for name, value in isolated_environ.iteritems():
1797
self.overrideEnv(name, value)
1294
1799
def _restoreHooks(self):
1295
1800
for klass, (name, hooks) in self._preserved_hooks.items():
1296
1801
setattr(klass, name, hooks)
1802
self._preserved_hooks.clear()
1803
bzrlib.hooks._lazy_hooks = self._preserved_lazy_hooks
1804
self._preserved_lazy_hooks.clear()
1298
1806
def knownFailure(self, reason):
1299
1807
"""This test has failed for some known reason."""
1300
1808
raise KnownFailure(reason)
1810
def _suppress_log(self):
1811
"""Remove the log info from details."""
1812
self.discardDetail('log')
1302
1814
def _do_skip(self, result, reason):
1815
self._suppress_log()
1303
1816
addSkip = getattr(result, 'addSkip', None)
1304
1817
if not callable(addSkip):
1305
result.addError(self, self.exc_info())
1818
result.addSuccess(result)
1307
1820
addSkip(self, reason)
1309
def run(self, result=None):
1310
if result is None: result = self.defaultTestResult()
1311
for feature in getattr(self, '_test_needs_features', []):
1312
if not feature.available():
1313
result.startTest(self)
1314
if getattr(result, 'addNotSupported', None):
1315
result.addNotSupported(self, feature)
1317
result.addSuccess(self)
1318
result.stopTest(self)
1322
result.startTest(self)
1323
absent_attr = object()
1325
method_name = getattr(self, '_testMethodName', absent_attr)
1326
if method_name is absent_attr:
1328
method_name = getattr(self, '_TestCase__testMethodName')
1329
testMethod = getattr(self, method_name)
1333
if not self._bzr_test_setUp_run:
1335
"test setUp did not invoke "
1336
"bzrlib.tests.TestCase's setUp")
1337
except KeyboardInterrupt:
1339
except TestSkipped, e:
1340
self._do_skip(result, e.args[0])
1344
result.addError(self, self.exc_info())
1351
except self.failureException:
1352
result.addFailure(self, self.exc_info())
1353
except TestSkipped, e:
1355
reason = "No reason given."
1358
self._do_skip(result, reason)
1359
except KeyboardInterrupt:
1362
result.addError(self, self.exc_info())
1366
if not self._bzr_test_tearDown_run:
1368
"test tearDown did not invoke "
1369
"bzrlib.tests.TestCase's tearDown")
1370
except KeyboardInterrupt:
1373
result.addError(self, self.exc_info())
1375
if ok: result.addSuccess(self)
1377
result.stopTest(self)
1379
except TestNotApplicable:
1380
# Not moved from the result [yet].
1382
except KeyboardInterrupt:
1386
absent_attr = object()
1387
for attr_name in self.attrs_to_keep:
1388
attr = getattr(self, attr_name, absent_attr)
1389
if attr is not absent_attr:
1390
saved_attrs[attr_name] = attr
1391
self.__dict__ = saved_attrs
1394
self._bzr_test_tearDown_run = True
1396
self._log_contents = ''
1397
unittest.TestCase.tearDown(self)
1823
def _do_known_failure(self, result, e):
1824
self._suppress_log()
1825
err = sys.exc_info()
1826
addExpectedFailure = getattr(result, 'addExpectedFailure', None)
1827
if addExpectedFailure is not None:
1828
addExpectedFailure(self, err)
1830
result.addSuccess(self)
1833
def _do_not_applicable(self, result, e):
1835
reason = 'No reason given'
1838
self._suppress_log ()
1839
addNotApplicable = getattr(result, 'addNotApplicable', None)
1840
if addNotApplicable is not None:
1841
result.addNotApplicable(self, reason)
1843
self._do_skip(result, reason)
1846
def _report_skip(self, result, err):
1847
"""Override the default _report_skip.
1849
We want to strip the 'log' detail. If we waint until _do_skip, it has
1850
already been formatted into the 'reason' string, and we can't pull it
1853
self._suppress_log()
1854
super(TestCase, self)._report_skip(self, result, err)
1857
def _report_expected_failure(self, result, err):
1860
See _report_skip for motivation.
1862
self._suppress_log()
1863
super(TestCase, self)._report_expected_failure(self, result, err)
1866
def _do_unsupported_or_skip(self, result, e):
1868
self._suppress_log()
1869
addNotSupported = getattr(result, 'addNotSupported', None)
1870
if addNotSupported is not None:
1871
result.addNotSupported(self, reason)
1873
self._do_skip(result, reason)
1399
1875
def time(self, callable, *args, **kwargs):
1400
1876
"""Run callable and accrue the time it takes to the benchmark time.
2639
3195
if runner_class is None:
2640
3196
runner_class = TextTestRunner
2641
runner = runner_class(stream=sys.stdout,
3199
runner = runner_class(stream=stream,
2642
3200
descriptions=0,
2643
3201
verbosity=verbosity,
2644
3202
bench_history=bench_history,
2645
list_only=list_only,
3204
result_decorators=result_decorators,
2647
3206
runner.stop_on_failure=stop_on_failure
2648
# Initialise the random number generator and display the seed used.
2649
# We convert the seed to a long to make it reuseable across invocations.
2650
random_order = False
2651
if random_seed is not None:
2653
if random_seed == "now":
2654
random_seed = long(time.time())
3207
# built in decorator factories:
3209
random_order(random_seed, runner),
3210
exclude_tests(exclude_pattern),
3212
if matching_tests_first:
3213
decorators.append(tests_first(pattern))
3215
decorators.append(filter_tests(pattern))
3216
if suite_decorators:
3217
decorators.extend(suite_decorators)
3218
# tell the result object how many tests will be running: (except if
3219
# --parallel=fork is being used. Robert said he will provide a better
3220
# progress design later -- vila 20090817)
3221
if fork_decorator not in decorators:
3222
decorators.append(CountingDecorator)
3223
for decorator in decorators:
3224
suite = decorator(suite)
3226
# Done after test suite decoration to allow randomisation etc
3227
# to take effect, though that is of marginal benefit.
3229
stream.write("Listing tests only ...\n")
3230
for t in iter_suite_tests(suite):
3231
stream.write("%s\n" % (t.id()))
3233
result = runner.run(suite)
3235
return result.wasStrictlySuccessful()
3237
return result.wasSuccessful()
3240
# A registry where get() returns a suite decorator.
3241
parallel_registry = registry.Registry()
3244
def fork_decorator(suite):
3245
if getattr(os, "fork", None) is None:
3246
raise errors.BzrCommandError("platform does not support fork,"
3247
" try --parallel=subprocess instead.")
3248
concurrency = osutils.local_concurrency()
3249
if concurrency == 1:
3251
from testtools import ConcurrentTestSuite
3252
return ConcurrentTestSuite(suite, fork_for_tests)
3253
parallel_registry.register('fork', fork_decorator)
3256
def subprocess_decorator(suite):
3257
concurrency = osutils.local_concurrency()
3258
if concurrency == 1:
3260
from testtools import ConcurrentTestSuite
3261
return ConcurrentTestSuite(suite, reinvoke_for_tests)
3262
parallel_registry.register('subprocess', subprocess_decorator)
3265
def exclude_tests(exclude_pattern):
3266
"""Return a test suite decorator that excludes tests."""
3267
if exclude_pattern is None:
3268
return identity_decorator
3269
def decorator(suite):
3270
return ExcludeDecorator(suite, exclude_pattern)
3274
def filter_tests(pattern):
3276
return identity_decorator
3277
def decorator(suite):
3278
return FilterTestsDecorator(suite, pattern)
3282
def random_order(random_seed, runner):
3283
"""Return a test suite decorator factory for randomising tests order.
3285
:param random_seed: now, a string which casts to a long, or a long.
3286
:param runner: A test runner with a stream attribute to report on.
3288
if random_seed is None:
3289
return identity_decorator
3290
def decorator(suite):
3291
return RandomDecorator(suite, random_seed, runner.stream)
3295
def tests_first(pattern):
3297
return identity_decorator
3298
def decorator(suite):
3299
return TestFirstDecorator(suite, pattern)
3303
def identity_decorator(suite):
3308
class TestDecorator(TestUtil.TestSuite):
3309
"""A decorator for TestCase/TestSuite objects.
3311
Usually, subclasses should override __iter__(used when flattening test
3312
suites), which we do to filter, reorder, parallelise and so on, run() and
3316
def __init__(self, suite):
3317
TestUtil.TestSuite.__init__(self)
3320
def countTestCases(self):
3323
cases += test.countTestCases()
3330
def run(self, result):
3331
# Use iteration on self, not self._tests, to allow subclasses to hook
3334
if result.shouldStop:
3340
class CountingDecorator(TestDecorator):
3341
"""A decorator which calls result.progress(self.countTestCases)."""
3343
def run(self, result):
3344
progress_method = getattr(result, 'progress', None)
3345
if callable(progress_method):
3346
progress_method(self.countTestCases(), SUBUNIT_SEEK_SET)
3347
return super(CountingDecorator, self).run(result)
3350
class ExcludeDecorator(TestDecorator):
3351
"""A decorator which excludes test matching an exclude pattern."""
3353
def __init__(self, suite, exclude_pattern):
3354
TestDecorator.__init__(self, suite)
3355
self.exclude_pattern = exclude_pattern
3356
self.excluded = False
3360
return iter(self._tests)
3361
self.excluded = True
3362
suite = exclude_tests_by_re(self, self.exclude_pattern)
3364
self.addTests(suite)
3365
return iter(self._tests)
3368
class FilterTestsDecorator(TestDecorator):
3369
"""A decorator which filters tests to those matching a pattern."""
3371
def __init__(self, suite, pattern):
3372
TestDecorator.__init__(self, suite)
3373
self.pattern = pattern
3374
self.filtered = False
3378
return iter(self._tests)
3379
self.filtered = True
3380
suite = filter_suite_by_re(self, self.pattern)
3382
self.addTests(suite)
3383
return iter(self._tests)
3386
class RandomDecorator(TestDecorator):
3387
"""A decorator which randomises the order of its tests."""
3389
def __init__(self, suite, random_seed, stream):
3390
TestDecorator.__init__(self, suite)
3391
self.random_seed = random_seed
3392
self.randomised = False
3393
self.stream = stream
3397
return iter(self._tests)
3398
self.randomised = True
3399
self.stream.write("Randomizing test order using seed %s\n\n" %
3400
(self.actual_seed()))
3401
# Initialise the random number generator.
3402
random.seed(self.actual_seed())
3403
suite = randomize_suite(self)
3405
self.addTests(suite)
3406
return iter(self._tests)
3408
def actual_seed(self):
3409
if self.random_seed == "now":
3410
# We convert the seed to a long to make it reuseable across
3411
# invocations (because the user can reenter it).
3412
self.random_seed = long(time.time())
2656
3414
# Convert the seed to a long if we can
2658
random_seed = long(random_seed)
3416
self.random_seed = long(self.random_seed)
2661
runner.stream.writeln("Randomizing test order using seed %s\n" %
2663
random.seed(random_seed)
2664
# Customise the list of tests if requested
2665
if exclude_pattern is not None:
2666
suite = exclude_tests_by_re(suite, exclude_pattern)
2668
order_changer = randomize_suite
2670
order_changer = preserve_input
2671
if pattern != '.*' or random_order:
2672
if matching_tests_first:
2673
suites = map(order_changer, split_suite_by_re(suite, pattern))
2674
suite = TestUtil.TestSuite(suites)
3419
return self.random_seed
3422
class TestFirstDecorator(TestDecorator):
3423
"""A decorator which moves named tests to the front."""
3425
def __init__(self, suite, pattern):
3426
TestDecorator.__init__(self, suite)
3427
self.pattern = pattern
3428
self.filtered = False
3432
return iter(self._tests)
3433
self.filtered = True
3434
suites = split_suite_by_re(self, self.pattern)
3436
self.addTests(suites)
3437
return iter(self._tests)
3440
def partition_tests(suite, count):
3441
"""Partition suite into count lists of tests."""
3442
# This just assigns tests in a round-robin fashion. On one hand this
3443
# splits up blocks of related tests that might run faster if they shared
3444
# resources, but on the other it avoids assigning blocks of slow tests to
3445
# just one partition. So the slowest partition shouldn't be much slower
3447
partitions = [list() for i in range(count)]
3448
tests = iter_suite_tests(suite)
3449
for partition, test in itertools.izip(itertools.cycle(partitions), tests):
3450
partition.append(test)
3454
def workaround_zealous_crypto_random():
3455
"""Crypto.Random want to help us being secure, but we don't care here.
3457
This workaround some test failure related to the sftp server. Once paramiko
3458
stop using the controversial API in Crypto.Random, we may get rid of it.
3461
from Crypto.Random import atfork
3467
def fork_for_tests(suite):
3468
"""Take suite and start up one runner per CPU by forking()
3470
:return: An iterable of TestCase-like objects which can each have
3471
run(result) called on them to feed tests to result.
3473
concurrency = osutils.local_concurrency()
3475
from subunit import TestProtocolClient, ProtocolTestCase
3476
from subunit.test_results import AutoTimingTestResultDecorator
3477
class TestInOtherProcess(ProtocolTestCase):
3478
# Should be in subunit, I think. RBC.
3479
def __init__(self, stream, pid):
3480
ProtocolTestCase.__init__(self, stream)
3483
def run(self, result):
3485
ProtocolTestCase.run(self, result)
3487
os.waitpid(self.pid, 0)
3489
test_blocks = partition_tests(suite, concurrency)
3490
for process_tests in test_blocks:
3491
process_suite = TestUtil.TestSuite()
3492
process_suite.addTests(process_tests)
3493
c2pread, c2pwrite = os.pipe()
3496
workaround_zealous_crypto_random()
3499
# Leave stderr and stdout open so we can see test noise
3500
# Close stdin so that the child goes away if it decides to
3501
# read from stdin (otherwise its a roulette to see what
3502
# child actually gets keystrokes for pdb etc).
3505
stream = os.fdopen(c2pwrite, 'wb', 1)
3506
subunit_result = AutoTimingTestResultDecorator(
3507
TestProtocolClient(stream))
3508
process_suite.run(subunit_result)
2676
suite = order_changer(filter_suite_by_re(suite, pattern))
2678
result = runner.run(suite)
2681
return result.wasStrictlySuccessful()
2683
return result.wasSuccessful()
3513
stream = os.fdopen(c2pread, 'rb', 1)
3514
test = TestInOtherProcess(stream, pid)
3519
def reinvoke_for_tests(suite):
3520
"""Take suite and start up one runner per CPU using subprocess().
3522
:return: An iterable of TestCase-like objects which can each have
3523
run(result) called on them to feed tests to result.
3525
concurrency = osutils.local_concurrency()
3527
from subunit import ProtocolTestCase
3528
class TestInSubprocess(ProtocolTestCase):
3529
def __init__(self, process, name):
3530
ProtocolTestCase.__init__(self, process.stdout)
3531
self.process = process
3532
self.process.stdin.close()
3535
def run(self, result):
3537
ProtocolTestCase.run(self, result)
3540
os.unlink(self.name)
3541
# print "pid %d finished" % finished_process
3542
test_blocks = partition_tests(suite, concurrency)
3543
for process_tests in test_blocks:
3544
# ugly; currently reimplement rather than reuses TestCase methods.
3545
bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
3546
if not os.path.isfile(bzr_path):
3547
# We are probably installed. Assume sys.argv is the right file
3548
bzr_path = sys.argv[0]
3549
bzr_path = [bzr_path]
3550
if sys.platform == "win32":
3551
# if we're on windows, we can't execute the bzr script directly
3552
bzr_path = [sys.executable] + bzr_path
3553
fd, test_list_file_name = tempfile.mkstemp()
3554
test_list_file = os.fdopen(fd, 'wb', 1)
3555
for test in process_tests:
3556
test_list_file.write(test.id() + '\n')
3557
test_list_file.close()
3559
argv = bzr_path + ['selftest', '--load-list', test_list_file_name,
3561
if '--no-plugins' in sys.argv:
3562
argv.append('--no-plugins')
3563
# stderr=subprocess.STDOUT would be ideal, but until we prevent
3564
# noise on stderr it can interrupt the subunit protocol.
3565
process = subprocess.Popen(argv, stdin=subprocess.PIPE,
3566
stdout=subprocess.PIPE,
3567
stderr=subprocess.PIPE,
3569
test = TestInSubprocess(process, test_list_file_name)
3572
os.unlink(test_list_file_name)
3577
class ProfileResult(testtools.ExtendedToOriginalDecorator):
3578
"""Generate profiling data for all activity between start and success.
3580
The profile data is appended to the test's _benchcalls attribute and can
3581
be accessed by the forwarded-to TestResult.
3583
While it might be cleaner do accumulate this in stopTest, addSuccess is
3584
where our existing output support for lsprof is, and this class aims to
3585
fit in with that: while it could be moved it's not necessary to accomplish
3586
test profiling, nor would it be dramatically cleaner.
3589
def startTest(self, test):
3590
self.profiler = bzrlib.lsprof.BzrProfiler()
3591
# Prevent deadlocks in tests that use lsprof: those tests will
3593
bzrlib.lsprof.BzrProfiler.profiler_block = 0
3594
self.profiler.start()
3595
testtools.ExtendedToOriginalDecorator.startTest(self, test)
3597
def addSuccess(self, test):
3598
stats = self.profiler.stop()
3600
calls = test._benchcalls
3601
except AttributeError:
3602
test._benchcalls = []
3603
calls = test._benchcalls
3604
calls.append(((test.id(), "", ""), stats))
3605
testtools.ExtendedToOriginalDecorator.addSuccess(self, test)
3607
def stopTest(self, test):
3608
testtools.ExtendedToOriginalDecorator.stopTest(self, test)
3609
self.profiler = None
2686
3612
# Controlled by "bzr selftest -E=..." option
3613
# Currently supported:
3614
# -Eallow_debug Will no longer clear debug.debug_flags() so it
3615
# preserves any flags supplied at the command line.
3616
# -Edisable_lock_checks Turns errors in mismatched locks into simple prints
3617
# rather than failing tests. And no longer raise
3618
# LockContention when fctnl locks are not being used
3619
# with proper exclusion rules.
3620
# -Ethreads Will display thread ident at creation/join time to
3621
# help track thread leaks
3623
# -Econfig_stats Will collect statistics using addDetail
2687
3624
selftest_debug_flags = set()
2899
3854
test_prefix_alias_registry.register('bp', 'bzrlib.plugins')
3857
def _test_suite_testmod_names():
3858
"""Return the standard list of test module names to test."""
3861
'bzrlib.tests.blackbox',
3862
'bzrlib.tests.commands',
3863
'bzrlib.tests.doc_generate',
3864
'bzrlib.tests.per_branch',
3865
'bzrlib.tests.per_bzrdir',
3866
'bzrlib.tests.per_controldir',
3867
'bzrlib.tests.per_controldir_colo',
3868
'bzrlib.tests.per_foreign_vcs',
3869
'bzrlib.tests.per_interrepository',
3870
'bzrlib.tests.per_intertree',
3871
'bzrlib.tests.per_inventory',
3872
'bzrlib.tests.per_interbranch',
3873
'bzrlib.tests.per_lock',
3874
'bzrlib.tests.per_merger',
3875
'bzrlib.tests.per_transport',
3876
'bzrlib.tests.per_tree',
3877
'bzrlib.tests.per_pack_repository',
3878
'bzrlib.tests.per_repository',
3879
'bzrlib.tests.per_repository_chk',
3880
'bzrlib.tests.per_repository_reference',
3881
'bzrlib.tests.per_repository_vf',
3882
'bzrlib.tests.per_uifactory',
3883
'bzrlib.tests.per_versionedfile',
3884
'bzrlib.tests.per_workingtree',
3885
'bzrlib.tests.test__annotator',
3886
'bzrlib.tests.test__bencode',
3887
'bzrlib.tests.test__btree_serializer',
3888
'bzrlib.tests.test__chk_map',
3889
'bzrlib.tests.test__dirstate_helpers',
3890
'bzrlib.tests.test__groupcompress',
3891
'bzrlib.tests.test__known_graph',
3892
'bzrlib.tests.test__rio',
3893
'bzrlib.tests.test__simple_set',
3894
'bzrlib.tests.test__static_tuple',
3895
'bzrlib.tests.test__walkdirs_win32',
3896
'bzrlib.tests.test_ancestry',
3897
'bzrlib.tests.test_annotate',
3898
'bzrlib.tests.test_api',
3899
'bzrlib.tests.test_atomicfile',
3900
'bzrlib.tests.test_bad_files',
3901
'bzrlib.tests.test_bisect_multi',
3902
'bzrlib.tests.test_branch',
3903
'bzrlib.tests.test_branchbuilder',
3904
'bzrlib.tests.test_btree_index',
3905
'bzrlib.tests.test_bugtracker',
3906
'bzrlib.tests.test_bundle',
3907
'bzrlib.tests.test_bzrdir',
3908
'bzrlib.tests.test__chunks_to_lines',
3909
'bzrlib.tests.test_cache_utf8',
3910
'bzrlib.tests.test_chk_map',
3911
'bzrlib.tests.test_chk_serializer',
3912
'bzrlib.tests.test_chunk_writer',
3913
'bzrlib.tests.test_clean_tree',
3914
'bzrlib.tests.test_cleanup',
3915
'bzrlib.tests.test_cmdline',
3916
'bzrlib.tests.test_commands',
3917
'bzrlib.tests.test_commit',
3918
'bzrlib.tests.test_commit_merge',
3919
'bzrlib.tests.test_config',
3920
'bzrlib.tests.test_conflicts',
3921
'bzrlib.tests.test_controldir',
3922
'bzrlib.tests.test_counted_lock',
3923
'bzrlib.tests.test_crash',
3924
'bzrlib.tests.test_decorators',
3925
'bzrlib.tests.test_delta',
3926
'bzrlib.tests.test_debug',
3927
'bzrlib.tests.test_diff',
3928
'bzrlib.tests.test_directory_service',
3929
'bzrlib.tests.test_dirstate',
3930
'bzrlib.tests.test_email_message',
3931
'bzrlib.tests.test_eol_filters',
3932
'bzrlib.tests.test_errors',
3933
'bzrlib.tests.test_export',
3934
'bzrlib.tests.test_export_pot',
3935
'bzrlib.tests.test_extract',
3936
'bzrlib.tests.test_fetch',
3937
'bzrlib.tests.test_fixtures',
3938
'bzrlib.tests.test_fifo_cache',
3939
'bzrlib.tests.test_filters',
3940
'bzrlib.tests.test_ftp_transport',
3941
'bzrlib.tests.test_foreign',
3942
'bzrlib.tests.test_generate_docs',
3943
'bzrlib.tests.test_generate_ids',
3944
'bzrlib.tests.test_globbing',
3945
'bzrlib.tests.test_gpg',
3946
'bzrlib.tests.test_graph',
3947
'bzrlib.tests.test_groupcompress',
3948
'bzrlib.tests.test_hashcache',
3949
'bzrlib.tests.test_help',
3950
'bzrlib.tests.test_hooks',
3951
'bzrlib.tests.test_http',
3952
'bzrlib.tests.test_http_response',
3953
'bzrlib.tests.test_https_ca_bundle',
3954
'bzrlib.tests.test_i18n',
3955
'bzrlib.tests.test_identitymap',
3956
'bzrlib.tests.test_ignores',
3957
'bzrlib.tests.test_index',
3958
'bzrlib.tests.test_import_tariff',
3959
'bzrlib.tests.test_info',
3960
'bzrlib.tests.test_inv',
3961
'bzrlib.tests.test_inventory_delta',
3962
'bzrlib.tests.test_knit',
3963
'bzrlib.tests.test_lazy_import',
3964
'bzrlib.tests.test_lazy_regex',
3965
'bzrlib.tests.test_library_state',
3966
'bzrlib.tests.test_lock',
3967
'bzrlib.tests.test_lockable_files',
3968
'bzrlib.tests.test_lockdir',
3969
'bzrlib.tests.test_log',
3970
'bzrlib.tests.test_lru_cache',
3971
'bzrlib.tests.test_lsprof',
3972
'bzrlib.tests.test_mail_client',
3973
'bzrlib.tests.test_matchers',
3974
'bzrlib.tests.test_memorytree',
3975
'bzrlib.tests.test_merge',
3976
'bzrlib.tests.test_merge3',
3977
'bzrlib.tests.test_merge_core',
3978
'bzrlib.tests.test_merge_directive',
3979
'bzrlib.tests.test_mergetools',
3980
'bzrlib.tests.test_missing',
3981
'bzrlib.tests.test_msgeditor',
3982
'bzrlib.tests.test_multiparent',
3983
'bzrlib.tests.test_mutabletree',
3984
'bzrlib.tests.test_nonascii',
3985
'bzrlib.tests.test_options',
3986
'bzrlib.tests.test_osutils',
3987
'bzrlib.tests.test_osutils_encodings',
3988
'bzrlib.tests.test_pack',
3989
'bzrlib.tests.test_patch',
3990
'bzrlib.tests.test_patches',
3991
'bzrlib.tests.test_permissions',
3992
'bzrlib.tests.test_plugins',
3993
'bzrlib.tests.test_progress',
3994
'bzrlib.tests.test_pyutils',
3995
'bzrlib.tests.test_read_bundle',
3996
'bzrlib.tests.test_reconcile',
3997
'bzrlib.tests.test_reconfigure',
3998
'bzrlib.tests.test_registry',
3999
'bzrlib.tests.test_remote',
4000
'bzrlib.tests.test_rename_map',
4001
'bzrlib.tests.test_repository',
4002
'bzrlib.tests.test_revert',
4003
'bzrlib.tests.test_revision',
4004
'bzrlib.tests.test_revisionspec',
4005
'bzrlib.tests.test_revisiontree',
4006
'bzrlib.tests.test_rio',
4007
'bzrlib.tests.test_rules',
4008
'bzrlib.tests.test_sampler',
4009
'bzrlib.tests.test_scenarios',
4010
'bzrlib.tests.test_script',
4011
'bzrlib.tests.test_selftest',
4012
'bzrlib.tests.test_serializer',
4013
'bzrlib.tests.test_setup',
4014
'bzrlib.tests.test_sftp_transport',
4015
'bzrlib.tests.test_shelf',
4016
'bzrlib.tests.test_shelf_ui',
4017
'bzrlib.tests.test_smart',
4018
'bzrlib.tests.test_smart_add',
4019
'bzrlib.tests.test_smart_request',
4020
'bzrlib.tests.test_smart_transport',
4021
'bzrlib.tests.test_smtp_connection',
4022
'bzrlib.tests.test_source',
4023
'bzrlib.tests.test_ssh_transport',
4024
'bzrlib.tests.test_status',
4025
'bzrlib.tests.test_store',
4026
'bzrlib.tests.test_strace',
4027
'bzrlib.tests.test_subsume',
4028
'bzrlib.tests.test_switch',
4029
'bzrlib.tests.test_symbol_versioning',
4030
'bzrlib.tests.test_tag',
4031
'bzrlib.tests.test_test_server',
4032
'bzrlib.tests.test_testament',
4033
'bzrlib.tests.test_textfile',
4034
'bzrlib.tests.test_textmerge',
4035
'bzrlib.tests.test_cethread',
4036
'bzrlib.tests.test_timestamp',
4037
'bzrlib.tests.test_trace',
4038
'bzrlib.tests.test_transactions',
4039
'bzrlib.tests.test_transform',
4040
'bzrlib.tests.test_transport',
4041
'bzrlib.tests.test_transport_log',
4042
'bzrlib.tests.test_tree',
4043
'bzrlib.tests.test_treebuilder',
4044
'bzrlib.tests.test_treeshape',
4045
'bzrlib.tests.test_tsort',
4046
'bzrlib.tests.test_tuned_gzip',
4047
'bzrlib.tests.test_ui',
4048
'bzrlib.tests.test_uncommit',
4049
'bzrlib.tests.test_upgrade',
4050
'bzrlib.tests.test_upgrade_stacked',
4051
'bzrlib.tests.test_urlutils',
4052
'bzrlib.tests.test_utextwrap',
4053
'bzrlib.tests.test_version',
4054
'bzrlib.tests.test_version_info',
4055
'bzrlib.tests.test_versionedfile',
4056
'bzrlib.tests.test_weave',
4057
'bzrlib.tests.test_whitebox',
4058
'bzrlib.tests.test_win32utils',
4059
'bzrlib.tests.test_workingtree',
4060
'bzrlib.tests.test_workingtree_4',
4061
'bzrlib.tests.test_wsgi',
4062
'bzrlib.tests.test_xml',
4066
def _test_suite_modules_to_doctest():
4067
"""Return the list of modules to doctest."""
4069
# GZ 2009-03-31: No docstrings with -OO so there's nothing to doctest
4073
'bzrlib.branchbuilder',
4074
'bzrlib.decorators',
4076
'bzrlib.iterablefile',
4081
'bzrlib.symbol_versioning',
4083
'bzrlib.tests.fixtures',
4085
'bzrlib.transport.http',
4086
'bzrlib.version_info_formats.format_custom',
2902
4090
def test_suite(keep_only=None, starting_with=None):
2903
4091
"""Build and return TestSuite for the whole of bzrlib.
2910
4098
This function can be replaced if you need to change the default test
2911
4099
suite on a global basis, but it is not encouraged.
2915
'bzrlib.tests.blackbox',
2916
'bzrlib.tests.branch_implementations',
2917
'bzrlib.tests.bzrdir_implementations',
2918
'bzrlib.tests.commands',
2919
'bzrlib.tests.interrepository_implementations',
2920
'bzrlib.tests.intertree_implementations',
2921
'bzrlib.tests.inventory_implementations',
2922
'bzrlib.tests.per_interbranch',
2923
'bzrlib.tests.per_lock',
2924
'bzrlib.tests.per_repository',
2925
'bzrlib.tests.per_repository_reference',
2926
'bzrlib.tests.test__dirstate_helpers',
2927
'bzrlib.tests.test__walkdirs_win32',
2928
'bzrlib.tests.test_ancestry',
2929
'bzrlib.tests.test_annotate',
2930
'bzrlib.tests.test_api',
2931
'bzrlib.tests.test_atomicfile',
2932
'bzrlib.tests.test_bad_files',
2933
'bzrlib.tests.test_bisect_multi',
2934
'bzrlib.tests.test_branch',
2935
'bzrlib.tests.test_branchbuilder',
2936
'bzrlib.tests.test_btree_index',
2937
'bzrlib.tests.test_bugtracker',
2938
'bzrlib.tests.test_bundle',
2939
'bzrlib.tests.test_bzrdir',
2940
'bzrlib.tests.test_cache_utf8',
2941
'bzrlib.tests.test_clean_tree',
2942
'bzrlib.tests.test_chunk_writer',
2943
'bzrlib.tests.test__chunks_to_lines',
2944
'bzrlib.tests.test_commands',
2945
'bzrlib.tests.test_commit',
2946
'bzrlib.tests.test_commit_merge',
2947
'bzrlib.tests.test_config',
2948
'bzrlib.tests.test_conflicts',
2949
'bzrlib.tests.test_counted_lock',
2950
'bzrlib.tests.test_decorators',
2951
'bzrlib.tests.test_delta',
2952
'bzrlib.tests.test_debug',
2953
'bzrlib.tests.test_deprecated_graph',
2954
'bzrlib.tests.test_diff',
2955
'bzrlib.tests.test_directory_service',
2956
'bzrlib.tests.test_dirstate',
2957
'bzrlib.tests.test_email_message',
2958
'bzrlib.tests.test_errors',
2959
'bzrlib.tests.test_export',
2960
'bzrlib.tests.test_extract',
2961
'bzrlib.tests.test_fetch',
2962
'bzrlib.tests.test_fifo_cache',
2963
'bzrlib.tests.test_ftp_transport',
2964
'bzrlib.tests.test_foreign',
2965
'bzrlib.tests.test_generate_docs',
2966
'bzrlib.tests.test_generate_ids',
2967
'bzrlib.tests.test_globbing',
2968
'bzrlib.tests.test_gpg',
2969
'bzrlib.tests.test_graph',
2970
'bzrlib.tests.test_hashcache',
2971
'bzrlib.tests.test_help',
2972
'bzrlib.tests.test_hooks',
2973
'bzrlib.tests.test_http',
2974
'bzrlib.tests.test_http_implementations',
2975
'bzrlib.tests.test_http_response',
2976
'bzrlib.tests.test_https_ca_bundle',
2977
'bzrlib.tests.test_identitymap',
2978
'bzrlib.tests.test_ignores',
2979
'bzrlib.tests.test_index',
2980
'bzrlib.tests.test_info',
2981
'bzrlib.tests.test_inv',
2982
'bzrlib.tests.test_knit',
2983
'bzrlib.tests.test_lazy_import',
2984
'bzrlib.tests.test_lazy_regex',
2985
'bzrlib.tests.test_lockable_files',
2986
'bzrlib.tests.test_lockdir',
2987
'bzrlib.tests.test_log',
2988
'bzrlib.tests.test_lru_cache',
2989
'bzrlib.tests.test_lsprof',
2990
'bzrlib.tests.test_mail_client',
2991
'bzrlib.tests.test_memorytree',
2992
'bzrlib.tests.test_merge',
2993
'bzrlib.tests.test_merge3',
2994
'bzrlib.tests.test_merge_core',
2995
'bzrlib.tests.test_merge_directive',
2996
'bzrlib.tests.test_missing',
2997
'bzrlib.tests.test_msgeditor',
2998
'bzrlib.tests.test_multiparent',
2999
'bzrlib.tests.test_mutabletree',
3000
'bzrlib.tests.test_nonascii',
3001
'bzrlib.tests.test_options',
3002
'bzrlib.tests.test_osutils',
3003
'bzrlib.tests.test_osutils_encodings',
3004
'bzrlib.tests.test_pack',
3005
'bzrlib.tests.test_pack_repository',
3006
'bzrlib.tests.test_patch',
3007
'bzrlib.tests.test_patches',
3008
'bzrlib.tests.test_permissions',
3009
'bzrlib.tests.test_plugins',
3010
'bzrlib.tests.test_progress',
3011
'bzrlib.tests.test_read_bundle',
3012
'bzrlib.tests.test_reconcile',
3013
'bzrlib.tests.test_reconfigure',
3014
'bzrlib.tests.test_registry',
3015
'bzrlib.tests.test_remote',
3016
'bzrlib.tests.test_repository',
3017
'bzrlib.tests.test_revert',
3018
'bzrlib.tests.test_revision',
3019
'bzrlib.tests.test_revisionspec',
3020
'bzrlib.tests.test_revisiontree',
3021
'bzrlib.tests.test_rio',
3022
'bzrlib.tests.test_rules',
3023
'bzrlib.tests.test_sampler',
3024
'bzrlib.tests.test_selftest',
3025
'bzrlib.tests.test_setup',
3026
'bzrlib.tests.test_sftp_transport',
3027
'bzrlib.tests.test_shelf',
3028
'bzrlib.tests.test_shelf_ui',
3029
'bzrlib.tests.test_smart',
3030
'bzrlib.tests.test_smart_add',
3031
'bzrlib.tests.test_smart_request',
3032
'bzrlib.tests.test_smart_transport',
3033
'bzrlib.tests.test_smtp_connection',
3034
'bzrlib.tests.test_source',
3035
'bzrlib.tests.test_ssh_transport',
3036
'bzrlib.tests.test_status',
3037
'bzrlib.tests.test_store',
3038
'bzrlib.tests.test_strace',
3039
'bzrlib.tests.test_subsume',
3040
'bzrlib.tests.test_switch',
3041
'bzrlib.tests.test_symbol_versioning',
3042
'bzrlib.tests.test_tag',
3043
'bzrlib.tests.test_testament',
3044
'bzrlib.tests.test_textfile',
3045
'bzrlib.tests.test_textmerge',
3046
'bzrlib.tests.test_timestamp',
3047
'bzrlib.tests.test_trace',
3048
'bzrlib.tests.test_transactions',
3049
'bzrlib.tests.test_transform',
3050
'bzrlib.tests.test_transport',
3051
'bzrlib.tests.test_transport_implementations',
3052
'bzrlib.tests.test_transport_log',
3053
'bzrlib.tests.test_tree',
3054
'bzrlib.tests.test_treebuilder',
3055
'bzrlib.tests.test_tsort',
3056
'bzrlib.tests.test_tuned_gzip',
3057
'bzrlib.tests.test_ui',
3058
'bzrlib.tests.test_uncommit',
3059
'bzrlib.tests.test_upgrade',
3060
'bzrlib.tests.test_upgrade_stacked',
3061
'bzrlib.tests.test_urlutils',
3062
'bzrlib.tests.test_version',
3063
'bzrlib.tests.test_version_info',
3064
'bzrlib.tests.test_versionedfile',
3065
'bzrlib.tests.test_weave',
3066
'bzrlib.tests.test_whitebox',
3067
'bzrlib.tests.test_win32utils',
3068
'bzrlib.tests.test_workingtree',
3069
'bzrlib.tests.test_workingtree_4',
3070
'bzrlib.tests.test_wsgi',
3071
'bzrlib.tests.test_xml',
3072
'bzrlib.tests.tree_implementations',
3073
'bzrlib.tests.workingtree_implementations',
3074
'bzrlib.util.tests.test_bencode',
3077
4102
loader = TestUtil.TestLoader()
4104
if keep_only is not None:
4105
id_filter = TestIdList(keep_only)
3079
4106
if starting_with:
3080
starting_with = [test_prefix_alias_registry.resolve_alias(start)
3081
for start in starting_with]
3082
4107
# We take precedence over keep_only because *at loading time* using
3083
4108
# both options means we will load less tests for the same final result.
3084
4109
def interesting_module(name):
3274
4293
:param new_id: The id to assign to it.
3275
4294
:return: The new test.
3277
from copy import deepcopy
3278
new_test = deepcopy(test)
4296
new_test = copy.copy(test)
3279
4297
new_test.id = lambda: new_id
4298
# XXX: Workaround <https://bugs.launchpad.net/testtools/+bug/637725>, which
4299
# causes cloned tests to share the 'details' dict. This makes it hard to
4300
# read the test output for parameterized tests, because tracebacks will be
4301
# associated with irrelevant tests.
4303
details = new_test._TestCase__details
4304
except AttributeError:
4305
# must be a different version of testtools than expected. Do nothing.
4308
# Reset the '__details' dict.
4309
new_test._TestCase__details = {}
3280
4310
return new_test
3283
def _rmtree_temp_dir(dirname):
4313
def permute_tests_for_extension(standard_tests, loader, py_module_name,
4315
"""Helper for permutating tests against an extension module.
4317
This is meant to be used inside a modules 'load_tests()' function. It will
4318
create 2 scenarios, and cause all tests in the 'standard_tests' to be run
4319
against both implementations. Setting 'test.module' to the appropriate
4320
module. See bzrlib.tests.test__chk_map.load_tests as an example.
4322
:param standard_tests: A test suite to permute
4323
:param loader: A TestLoader
4324
:param py_module_name: The python path to a python module that can always
4325
be loaded, and will be considered the 'python' implementation. (eg
4326
'bzrlib._chk_map_py')
4327
:param ext_module_name: The python path to an extension module. If the
4328
module cannot be loaded, a single test will be added, which notes that
4329
the module is not available. If it can be loaded, all standard_tests
4330
will be run against that module.
4331
:return: (suite, feature) suite is a test-suite that has all the permuted
4332
tests. feature is the Feature object that can be used to determine if
4333
the module is available.
4336
py_module = pyutils.get_named_object(py_module_name)
4338
('python', {'module': py_module}),
4340
suite = loader.suiteClass()
4341
feature = ModuleAvailableFeature(ext_module_name)
4342
if feature.available():
4343
scenarios.append(('C', {'module': feature.module}))
4345
# the compiled module isn't available, so we add a failing test
4346
class FailWithoutFeature(TestCase):
4347
def test_fail(self):
4348
self.requireFeature(feature)
4349
suite.addTest(loader.loadTestsFromTestCase(FailWithoutFeature))
4350
result = multiply_tests(standard_tests, scenarios, suite)
4351
return result, feature
4354
def _rmtree_temp_dir(dirname, test_id=None):
3284
4355
# If LANG=C we probably have created some bogus paths
3285
4356
# which rmtree(unicode) will fail to delete
3286
4357
# so make sure we are using rmtree(str) to delete everything