29
31
from cStringIO import StringIO
37
from pprint import pformat
42
from subprocess import Popen, PIPE
54
# nb: check this before importing anything else from within it
55
_testtools_version = getattr(testtools, '__version__', ())
56
if _testtools_version < (0, 9, 5):
57
raise ImportError("need at least testtools 0.9.5: %s is %r"
58
% (testtools.__file__, _testtools_version))
59
from testtools import content
62
50
from bzrlib import (
66
commands as _mod_commands,
76
plugin as _mod_plugin,
83
transport as _mod_transport,
62
import bzrlib.commands
63
import bzrlib.timestamp
65
import bzrlib.inventory
66
import bzrlib.iterablefile
87
69
import bzrlib.lsprof
88
70
except ImportError:
89
71
# lsprof not available
91
from bzrlib.smart import client, request
92
from bzrlib.transport import (
73
from bzrlib.merge import merge_inner
76
from bzrlib.revision import common_ancestor
78
from bzrlib import symbol_versioning
96
79
from bzrlib.symbol_versioning import (
100
from bzrlib.tests import (
106
from bzrlib.ui import NullProgressView
107
from bzrlib.ui.text import TextUIFactory
108
from bzrlib.tests.features import _CompatabilityThunkFeature
85
from bzrlib.transport import get_transport
86
import bzrlib.transport
87
from bzrlib.transport.local import LocalURLServer
88
from bzrlib.transport.memory import MemoryServer
89
from bzrlib.transport.readonly import ReadonlyServer
90
from bzrlib.trace import mutter, note
91
from bzrlib.tests import TestUtil
92
from bzrlib.tests.HttpServer import HttpServer
93
from bzrlib.tests.TestUtil import (
97
from bzrlib.tests.EncodingAdapter import EncodingTestAdapter
98
from bzrlib.tests.treeshape import build_tree_contents
99
from bzrlib.workingtree import WorkingTree, WorkingTreeFormat2
110
101
# Mark this python module as being part of the implementation
111
102
# of unittest: this gives us better tracebacks where the last
112
103
# shown frame is the test code, not our assertXYZ.
115
default_transport = test_server.LocalURLServer
118
_unitialized_attr = object()
119
"""A sentinel needed to act as a default value in a method signature."""
122
# Subunit result codes, defined here to prevent a hard dependency on subunit.
126
# These are intentionally brought into this namespace. That way plugins, etc
127
# can just "from bzrlib.tests import TestCase, TestLoader, etc"
128
TestSuite = TestUtil.TestSuite
129
TestLoader = TestUtil.TestLoader
131
# Tests should run in a clean and clearly defined environment. The goal is to
132
# keep them isolated from the running environment as mush as possible. The test
133
# framework ensures the variables defined below are set (or deleted if the
134
# value is None) before a test is run and reset to their original value after
135
# the test is run. Generally if some code depends on an environment variable,
136
# the tests should start without this variable in the environment. There are a
137
# few exceptions but you shouldn't violate this rule lightly.
141
'XDG_CONFIG_HOME': None,
142
# bzr now uses the Win32 API and doesn't rely on APPDATA, but the
143
# tests do check our impls match APPDATA
144
'BZR_EDITOR': None, # test_msgeditor manipulates this variable
148
'BZREMAIL': None, # may still be present in the environment
149
'EMAIL': 'jrandom@example.com', # set EMAIL as bzr does not guess
150
'BZR_PROGRESS_BAR': None,
151
# This should trap leaks to ~/.bzr.log. This occurs when tests use TestCase
152
# as a base class instead of TestCaseInTempDir. Tests inheriting from
153
# TestCase should not use disk resources, BZR_LOG is one.
154
'BZR_LOG': '/you-should-use-TestCaseInTempDir-if-you-need-a-log-file',
155
'BZR_PLUGIN_PATH': None,
156
'BZR_DISABLE_PLUGINS': None,
157
'BZR_PLUGINS_AT': None,
158
'BZR_CONCURRENCY': None,
159
# Make sure that any text ui tests are consistent regardless of
160
# the environment the test case is run in; you may want tests that
161
# test other combinations. 'dumb' is a reasonable guess for tests
162
# going to a pipe or a StringIO.
168
'SSH_AUTH_SOCK': None,
178
# Nobody cares about ftp_proxy, FTP_PROXY AFAIK. So far at
179
# least. If you do (care), please update this comment
183
'BZR_REMOTE_PATH': None,
184
# Generally speaking, we don't want apport reporting on crashes in
185
# the test envirnoment unless we're specifically testing apport,
186
# so that it doesn't leak into the real system environment. We
187
# use an env var so it propagates to subprocesses.
188
'APPORT_DISABLE': '1',
192
def override_os_environ(test, env=None):
193
"""Modify os.environ keeping a copy.
195
:param test: A test instance
197
:param env: A dict containing variable definitions to be installed
200
env = isolated_environ
201
test._original_os_environ = dict([(var, value)
202
for var, value in os.environ.iteritems()])
203
for var, value in env.iteritems():
204
osutils.set_or_unset_env(var, value)
205
if var not in test._original_os_environ:
206
# The var is new, add it with a value of None, so
207
# restore_os_environ will delete it
208
test._original_os_environ[var] = None
211
def restore_os_environ(test):
212
"""Restore os.environ to its original state.
214
:param test: A test instance previously passed to override_os_environ.
216
for var, value in test._original_os_environ.iteritems():
217
# Restore the original value (or delete it if the value has been set to
218
# None in override_os_environ).
219
osutils.set_or_unset_env(var, value)
222
def _clear__type_equality_funcs(test):
223
"""Cleanup bound methods stored on TestCase instances
225
Clear the dict breaking a few (mostly) harmless cycles in the affected
226
unittests released with Python 2.6 and initial Python 2.7 versions.
228
For a few revisions between Python 2.7.1 and Python 2.7.2 that annoyingly
229
shipped in Oneiric, an object with no clear method was used, hence the
230
extra complications, see bug 809048 for details.
232
type_equality_funcs = getattr(test, "_type_equality_funcs", None)
233
if type_equality_funcs is not None:
234
tef_clear = getattr(type_equality_funcs, "clear", None)
235
if tef_clear is None:
236
tef_instance_dict = getattr(type_equality_funcs, "__dict__", None)
237
if tef_instance_dict is not None:
238
tef_clear = tef_instance_dict.clear
239
if tef_clear is not None:
243
class ExtendedTestResult(testtools.TextTestResult):
106
default_transport = LocalURLServer
109
MODULES_TO_DOCTEST = [
119
# quoted to avoid module-loading circularity
124
def packages_to_test():
125
"""Return a list of packages to test.
127
The packages are not globally imported so that import failures are
128
triggered when running selftest, not when importing the command.
131
import bzrlib.tests.blackbox
132
import bzrlib.tests.branch_implementations
133
import bzrlib.tests.bzrdir_implementations
134
import bzrlib.tests.commands
135
import bzrlib.tests.interrepository_implementations
136
import bzrlib.tests.interversionedfile_implementations
137
import bzrlib.tests.intertree_implementations
138
import bzrlib.tests.inventory_implementations
139
import bzrlib.tests.per_lock
140
import bzrlib.tests.repository_implementations
141
import bzrlib.tests.revisionstore_implementations
142
import bzrlib.tests.tree_implementations
143
import bzrlib.tests.workingtree_implementations
146
bzrlib.tests.blackbox,
147
bzrlib.tests.branch_implementations,
148
bzrlib.tests.bzrdir_implementations,
149
bzrlib.tests.commands,
150
bzrlib.tests.interrepository_implementations,
151
bzrlib.tests.interversionedfile_implementations,
152
bzrlib.tests.intertree_implementations,
153
bzrlib.tests.inventory_implementations,
154
bzrlib.tests.per_lock,
155
bzrlib.tests.repository_implementations,
156
bzrlib.tests.revisionstore_implementations,
157
bzrlib.tests.tree_implementations,
158
bzrlib.tests.workingtree_implementations,
162
class ExtendedTestResult(unittest._TextTestResult):
244
163
"""Accepts, reports and accumulates the results of running tests.
246
165
Compared to the unittest version this class adds support for
468
282
Called from the TestCase run() method when the test
469
283
fails because e.g. an assert() method failed.
471
self._post_mortem(self._traceback_from_test)
472
super(ExtendedTestResult, self).addFailure(test, err)
473
self.failure_count += 1
474
self.report_failure(test, err)
285
self._testConcluded(test)
286
if isinstance(err[1], KnownFailure):
287
return self._addKnownFailure(test, err)
289
unittest.TestResult.addFailure(self, test, err)
290
self.failure_count += 1
291
self.report_failure(test, err)
478
def addSuccess(self, test, details=None):
295
def addSuccess(self, test):
479
296
"""Tell result that test completed successfully.
481
298
Called from the TestCase run()
300
self._testConcluded(test)
483
301
if self._bench_history is not None:
484
benchmark_time = self._extractBenchmarkTime(test, details)
302
benchmark_time = self._extractBenchmarkTime(test)
485
303
if benchmark_time is not None:
486
304
self._bench_history.write("%s %s\n" % (
487
305
self._formatTime(benchmark_time),
489
307
self.report_success(test)
490
super(ExtendedTestResult, self).addSuccess(test)
491
test._log_contents = ''
493
def addExpectedFailure(self, test, err):
308
unittest.TestResult.addSuccess(self, test)
310
def _testConcluded(self, test):
311
"""Common code when a test has finished.
313
Called regardless of whether it succeded, failed, etc.
315
self._cleanupLogFile(test)
317
def _addKnownFailure(self, test, err):
494
318
self.known_failure_count += 1
495
319
self.report_known_failure(test, err)
497
def addUnexpectedSuccess(self, test, details=None):
498
"""Tell result the test unexpectedly passed, counting as a failure
500
When the minimum version of testtools required becomes 0.9.8 this
501
can be updated to use the new handling there.
503
super(ExtendedTestResult, self).addFailure(test, details=details)
504
self.failure_count += 1
505
self.report_unexpected_success(test,
506
"".join(details["reason"].iter_text()))
510
321
def addNotSupported(self, test, feature):
511
322
"""The test will not be run because of a missing feature.
513
324
# this can be called in two different ways: it may be that the
514
# test started running, and then raised (through requireFeature)
325
# test started running, and then raised (through addError)
515
326
# UnavailableFeature. Alternatively this method can be called
516
# while probing for features before running the test code proper; in
517
# that case we will see startTest and stopTest, but the test will
518
# never actually run.
327
# while probing for features before running the tests; in that
328
# case we will see startTest and stopTest, but the test will never
519
330
self.unsupported.setdefault(str(feature), 0)
520
331
self.unsupported[str(feature)] += 1
521
332
self.report_unsupported(test, feature)
523
def addSkip(self, test, reason):
524
"""A test has not run for 'reason'."""
526
self.report_skip(test, reason)
528
def addNotApplicable(self, test, reason):
529
self.not_applicable_count += 1
530
self.report_not_applicable(test, reason)
532
def _count_stored_tests(self):
533
"""Count of tests instances kept alive due to not succeeding"""
534
return self.error_count + self.failure_count + self.known_failure_count
536
def _post_mortem(self, tb=None):
537
"""Start a PDB post mortem session."""
538
if os.environ.get('BZR_TEST_PDB', None):
542
def progress(self, offset, whence):
543
"""The test is adjusting the count of tests to run."""
544
if whence == SUBUNIT_SEEK_SET:
545
self.num_tests = offset
546
elif whence == SUBUNIT_SEEK_CUR:
547
self.num_tests += offset
549
raise errors.BzrError("Unknown whence %r" % whence)
551
def report_tests_starting(self):
552
"""Display information before the test run begins"""
553
if getattr(sys, 'frozen', None) is None:
554
bzr_path = osutils.realpath(sys.argv[0])
556
bzr_path = sys.executable
558
'bzr selftest: %s\n' % (bzr_path,))
561
bzrlib.__path__[0],))
563
' bzr-%s python-%s %s\n' % (
564
bzrlib.version_string,
565
bzrlib._format_version_tuple(sys.version_info),
566
platform.platform(aliased=1),
568
self.stream.write('\n')
570
def report_test_start(self, test):
571
"""Display information on the test just about to be run"""
573
def _report_thread_leak(self, test, leaked_threads, active_threads):
574
"""Display information on a test that leaked one or more threads"""
575
# GZ 2010-09-09: A leak summary reported separately from the general
576
# thread debugging would be nice. Tests under subunit
577
# need something not using stream, perhaps adding a
578
# testtools details object would be fitting.
579
if 'threads' in selftest_debug_flags:
580
self.stream.write('%s is leaking, active is now %d\n' %
581
(test.id(), len(active_threads)))
583
def startTestRun(self):
584
self.startTime = time.time()
334
def _addSkipped(self, test, skip_excinfo):
335
if isinstance(skip_excinfo[1], TestNotApplicable):
336
self.not_applicable_count += 1
337
self.report_not_applicable(test, skip_excinfo)
340
self.report_skip(test, skip_excinfo)
343
except KeyboardInterrupt:
346
self.addError(test, test._exc_info())
348
# seems best to treat this as success from point-of-view of unittest
349
# -- it actually does nothing so it barely matters :)
350
unittest.TestResult.addSuccess(self, test)
352
def printErrorList(self, flavour, errors):
353
for test, err in errors:
354
self.stream.writeln(self.separator1)
355
self.stream.write("%s: " % flavour)
356
self.stream.writeln(self.getDescription(test))
357
if getattr(test, '_get_log', None) is not None:
358
self.stream.write('\n')
360
('vvvv[log from %s]' % test.id()).ljust(78,'-'))
361
self.stream.write('\n')
362
self.stream.write(test._get_log())
363
self.stream.write('\n')
365
('^^^^[log from %s]' % test.id()).ljust(78,'-'))
366
self.stream.write('\n')
367
self.stream.writeln(self.separator2)
368
self.stream.writeln("%s" % err)
373
def report_cleaning_up(self):
586
376
def report_success(self, test):
986
766
retrieved by _get_log(). We use a real OS file, not an in-memory object,
987
767
so that it can also capture file IO. When the test completes this file
988
768
is read into memory and removed from disk.
990
770
There are also convenience functions to invoke bzr's command-line
991
771
routine, and to build and check bzr trees.
993
773
In addition to the usual method of overriding tearDown(), this class also
994
allows subclasses to register cleanup functions via addCleanup, which are
774
allows subclasses to register functions into the _cleanups list, which is
995
775
run in order as the object is torn down. It's less likely this will be
996
776
accidentally overlooked.
779
_log_file_name = None
781
_keep_log_file = False
1000
782
# record lsprof data when performing benchmark calls.
1001
783
_gather_lsprof_in_benchmarks = False
1003
785
def __init__(self, methodName='testMethod'):
1004
786
super(TestCase, self).__init__(methodName)
1005
self._directory_isolation = True
1006
self.exception_handlers.insert(0,
1007
(UnavailableFeature, self._do_unsupported_or_skip))
1008
self.exception_handlers.insert(0,
1009
(TestNotApplicable, self._do_not_applicable))
1011
789
def setUp(self):
1012
super(TestCase, self).setUp()
1014
# At this point we're still accessing the config files in $BZR_HOME (as
1015
# set by the user running selftest).
1016
timeout = config.GlobalStack().get('selftest.timeout')
1018
timeout_fixture = fixtures.TimeoutFixture(timeout)
1019
timeout_fixture.setUp()
1020
self.addCleanup(timeout_fixture.cleanUp)
1022
for feature in getattr(self, '_test_needs_features', []):
1023
self.requireFeature(feature)
790
unittest.TestCase.setUp(self)
1024
791
self._cleanEnvironment()
1026
if bzrlib.global_state is not None:
1027
self.overrideAttr(bzrlib.global_state, 'cmdline_overrides',
1028
config.CommandLineStore())
792
bzrlib.trace.disable_default_logging()
1030
793
self._silenceUI()
1031
794
self._startLogFile()
1032
795
self._benchcalls = []
1033
796
self._benchtime = None
1034
797
self._clear_hooks()
1035
self._track_transports()
1037
798
self._clear_debug_flags()
1038
# Isolate global verbosity level, to make sure it's reproducible
1039
# between tests. We should get rid of this altogether: bug 656694. --
1041
self.overrideAttr(bzrlib.trace, '_verbosity_level', 0)
1042
self._log_files = set()
1043
# Each key in the ``_counters`` dict holds a value for a different
1044
# counter. When the test ends, addDetail() should be used to output the
1045
# counter values. This happens in install_counter_hook().
1047
if 'config_stats' in selftest_debug_flags:
1048
self._install_config_stats_hooks()
1049
# Do not use i18n for tests (unless the test reverses this)
1055
# The sys preserved stdin/stdout should allow blackbox tests debugging
1056
pdb.Pdb(stdin=sys.__stdin__, stdout=sys.__stdout__
1057
).set_trace(sys._getframe().f_back)
1059
def discardDetail(self, name):
1060
"""Extend the addDetail, getDetails api so we can remove a detail.
1062
eg. bzr always adds the 'log' detail at startup, but we don't want to
1063
include it for skipped, xfail, etc tests.
1065
It is safe to call this for a detail that doesn't exist, in case this
1066
gets called multiple times.
1068
# We cheat. details is stored in __details which means we shouldn't
1069
# touch it. but getDetails() returns the dict directly, so we can
1071
details = self.getDetails()
1075
def install_counter_hook(self, hooks, name, counter_name=None):
1076
"""Install a counting hook.
1078
Any hook can be counted as long as it doesn't need to return a value.
1080
:param hooks: Where the hook should be installed.
1082
:param name: The hook name that will be counted.
1084
:param counter_name: The counter identifier in ``_counters``, defaults
1087
_counters = self._counters # Avoid closing over self
1088
if counter_name is None:
1090
if _counters.has_key(counter_name):
1091
raise AssertionError('%s is already used as a counter name'
1093
_counters[counter_name] = 0
1094
self.addDetail(counter_name, content.Content(content.UTF8_TEXT,
1095
lambda: ['%d' % (_counters[counter_name],)]))
1096
def increment_counter(*args, **kwargs):
1097
_counters[counter_name] += 1
1098
label = 'count %s calls' % (counter_name,)
1099
hooks.install_named_hook(name, increment_counter, label)
1100
self.addCleanup(hooks.uninstall_named_hook, name, label)
1102
def _install_config_stats_hooks(self):
1103
"""Install config hooks to count hook calls.
1106
for hook_name in ('get', 'set', 'remove', 'load', 'save'):
1107
self.install_counter_hook(config.ConfigHooks, hook_name,
1108
'config.%s' % (hook_name,))
1110
# The OldConfigHooks are private and need special handling to protect
1111
# against recursive tests (tests that run other tests), so we just do
1112
# manually what registering them into _builtin_known_hooks will provide
1114
self.overrideAttr(config, 'OldConfigHooks', config._OldConfigHooks())
1115
for hook_name in ('get', 'set', 'remove', 'load', 'save'):
1116
self.install_counter_hook(config.OldConfigHooks, hook_name,
1117
'old_config.%s' % (hook_name,))
1119
800
def _clear_debug_flags(self):
1120
801
"""Prevent externally set debug flags affecting tests.
1122
803
Tests that want to use debug flags can just set them in the
1123
804
debug_flags set during setup/teardown.
1125
# Start with a copy of the current debug flags we can safely modify.
1126
self.overrideAttr(debug, 'debug_flags', set(debug.debug_flags))
1127
if 'allow_debug' not in selftest_debug_flags:
1128
debug.debug_flags.clear()
1129
if 'disable_lock_checks' not in selftest_debug_flags:
1130
debug.debug_flags.add('strict_locks')
806
self._preserved_debug_flags = set(debug.debug_flags)
807
debug.debug_flags.clear()
808
self.addCleanup(self._restore_debug_flags)
1132
810
def _clear_hooks(self):
1133
811
# prevent hooks affecting tests
1134
known_hooks = hooks.known_hooks
1135
self._preserved_hooks = {}
1136
for key, (parent, name) in known_hooks.iter_parent_objects():
1137
current_hooks = getattr(parent, name)
1138
self._preserved_hooks[parent] = (name, current_hooks)
1139
self._preserved_lazy_hooks = hooks._lazy_hooks
1140
hooks._lazy_hooks = {}
813
import bzrlib.smart.server
814
self._preserved_hooks = {
815
bzrlib.branch.Branch: bzrlib.branch.Branch.hooks,
816
bzrlib.smart.server.SmartTCPServer: bzrlib.smart.server.SmartTCPServer.hooks,
1141
818
self.addCleanup(self._restoreHooks)
1142
for key, (parent, name) in known_hooks.iter_parent_objects():
1143
factory = known_hooks.get(key)
1144
setattr(parent, name, factory())
1145
# this hook should always be installed
1146
request._install_hook()
1148
def disable_directory_isolation(self):
1149
"""Turn off directory isolation checks."""
1150
self._directory_isolation = False
1152
def enable_directory_isolation(self):
1153
"""Enable directory isolation checks."""
1154
self._directory_isolation = True
819
# reset all hooks to an empty instance of the appropriate type
820
bzrlib.branch.Branch.hooks = bzrlib.branch.BranchHooks()
821
bzrlib.smart.server.SmartTCPServer.hooks = bzrlib.smart.server.SmartServerHooks()
1156
823
def _silenceUI(self):
1157
824
"""Turn off UI for duration of test"""
1158
825
# by default the UI is off; tests can turn it on if they want it.
1159
self.overrideAttr(ui, 'ui_factory', ui.SilentUIFactory())
1161
def _check_locks(self):
1162
"""Check that all lock take/release actions have been paired."""
1163
# We always check for mismatched locks. If a mismatch is found, we
1164
# fail unless -Edisable_lock_checks is supplied to selftest, in which
1165
# case we just print a warning.
1167
acquired_locks = [lock for action, lock in self._lock_actions
1168
if action == 'acquired']
1169
released_locks = [lock for action, lock in self._lock_actions
1170
if action == 'released']
1171
broken_locks = [lock for action, lock in self._lock_actions
1172
if action == 'broken']
1173
# trivially, given the tests for lock acquistion and release, if we
1174
# have as many in each list, it should be ok. Some lock tests also
1175
# break some locks on purpose and should be taken into account by
1176
# considering that breaking a lock is just a dirty way of releasing it.
1177
if len(acquired_locks) != (len(released_locks) + len(broken_locks)):
1179
'Different number of acquired and '
1180
'released or broken locks.\n'
1184
(acquired_locks, released_locks, broken_locks))
1185
if not self._lock_check_thorough:
1186
# Rather than fail, just warn
1187
print "Broken test %s: %s" % (self, message)
1191
def _track_locks(self):
1192
"""Track lock activity during tests."""
1193
self._lock_actions = []
1194
if 'disable_lock_checks' in selftest_debug_flags:
1195
self._lock_check_thorough = False
1197
self._lock_check_thorough = True
1199
self.addCleanup(self._check_locks)
1200
_mod_lock.Lock.hooks.install_named_hook('lock_acquired',
1201
self._lock_acquired, None)
1202
_mod_lock.Lock.hooks.install_named_hook('lock_released',
1203
self._lock_released, None)
1204
_mod_lock.Lock.hooks.install_named_hook('lock_broken',
1205
self._lock_broken, None)
1207
def _lock_acquired(self, result):
1208
self._lock_actions.append(('acquired', result))
1210
def _lock_released(self, result):
1211
self._lock_actions.append(('released', result))
1213
def _lock_broken(self, result):
1214
self._lock_actions.append(('broken', result))
1216
def permit_dir(self, name):
1217
"""Permit a directory to be used by this test. See permit_url."""
1218
name_transport = _mod_transport.get_transport_from_path(name)
1219
self.permit_url(name)
1220
self.permit_url(name_transport.base)
1222
def permit_url(self, url):
1223
"""Declare that url is an ok url to use in this test.
1225
Do this for memory transports, temporary test directory etc.
1227
Do not do this for the current working directory, /tmp, or any other
1228
preexisting non isolated url.
1230
if not url.endswith('/'):
1232
self._bzr_selftest_roots.append(url)
1234
def permit_source_tree_branch_repo(self):
1235
"""Permit the source tree bzr is running from to be opened.
1237
Some code such as bzrlib.version attempts to read from the bzr branch
1238
that bzr is executing from (if any). This method permits that directory
1239
to be used in the test suite.
1241
path = self.get_source_path()
1242
self.record_directory_isolation()
1245
workingtree.WorkingTree.open(path)
1246
except (errors.NotBranchError, errors.NoWorkingTree):
1247
raise TestSkipped('Needs a working tree of bzr sources')
1249
self.enable_directory_isolation()
1251
def _preopen_isolate_transport(self, transport):
1252
"""Check that all transport openings are done in the test work area."""
1253
while isinstance(transport, pathfilter.PathFilteringTransport):
1254
# Unwrap pathfiltered transports
1255
transport = transport.server.backing_transport.clone(
1256
transport._filter('.'))
1257
url = transport.base
1258
# ReadonlySmartTCPServer_for_testing decorates the backing transport
1259
# urls it is given by prepending readonly+. This is appropriate as the
1260
# client shouldn't know that the server is readonly (or not readonly).
1261
# We could register all servers twice, with readonly+ prepending, but
1262
# that makes for a long list; this is about the same but easier to
1264
if url.startswith('readonly+'):
1265
url = url[len('readonly+'):]
1266
self._preopen_isolate_url(url)
1268
def _preopen_isolate_url(self, url):
1269
if not self._directory_isolation:
1271
if self._directory_isolation == 'record':
1272
self._bzr_selftest_roots.append(url)
1274
# This prevents all transports, including e.g. sftp ones backed on disk
1275
# from working unless they are explicitly granted permission. We then
1276
# depend on the code that sets up test transports to check that they are
1277
# appropriately isolated and enable their use by calling
1278
# self.permit_transport()
1279
if not osutils.is_inside_any(self._bzr_selftest_roots, url):
1280
raise errors.BzrError("Attempt to escape test isolation: %r %r"
1281
% (url, self._bzr_selftest_roots))
1283
def record_directory_isolation(self):
1284
"""Gather accessed directories to permit later access.
1286
This is used for tests that access the branch bzr is running from.
1288
self._directory_isolation = "record"
1290
def start_server(self, transport_server, backing_server=None):
1291
"""Start transport_server for this test.
1293
This starts the server, registers a cleanup for it and permits the
1294
server's urls to be used.
1296
if backing_server is None:
1297
transport_server.start_server()
1299
transport_server.start_server(backing_server)
1300
self.addCleanup(transport_server.stop_server)
1301
# Obtain a real transport because if the server supplies a password, it
1302
# will be hidden from the base on the client side.
1303
t = _mod_transport.get_transport_from_url(transport_server.get_url())
1304
# Some transport servers effectively chroot the backing transport;
1305
# others like SFTPServer don't - users of the transport can walk up the
1306
# transport to read the entire backing transport. This wouldn't matter
1307
# except that the workdir tests are given - and that they expect the
1308
# server's url to point at - is one directory under the safety net. So
1309
# Branch operations into the transport will attempt to walk up one
1310
# directory. Chrooting all servers would avoid this but also mean that
1311
# we wouldn't be testing directly against non-root urls. Alternatively
1312
# getting the test framework to start the server with a backing server
1313
# at the actual safety net directory would work too, but this then
1314
# means that the self.get_url/self.get_transport methods would need
1315
# to transform all their results. On balance its cleaner to handle it
1316
# here, and permit a higher url when we have one of these transports.
1317
if t.base.endswith('/work/'):
1318
# we have safety net/test root/work
1319
t = t.clone('../..')
1320
elif isinstance(transport_server,
1321
test_server.SmartTCPServer_for_testing):
1322
# The smart server adds a path similar to work, which is traversed
1323
# up from by the client. But the server is chrooted - the actual
1324
# backing transport is not escaped from, and VFS requests to the
1325
# root will error (because they try to escape the chroot).
1327
while t2.base != t.base:
1330
self.permit_url(t.base)
1332
def _track_transports(self):
1333
"""Install checks for transport usage."""
1334
# TestCase has no safe place it can write to.
1335
self._bzr_selftest_roots = []
1336
# Currently the easiest way to be sure that nothing is going on is to
1337
# hook into bzr dir opening. This leaves a small window of error for
1338
# transport tests, but they are well known, and we can improve on this
1340
controldir.ControlDir.hooks.install_named_hook("pre_open",
1341
self._preopen_isolate_transport, "Check bzr directories are safe.")
826
saved = ui.ui_factory
828
ui.ui_factory = saved
829
ui.ui_factory = ui.SilentUIFactory()
830
self.addCleanup(_restore)
1343
832
def _ndiff_strings(self, a, b):
1344
833
"""Return ndiff between two strings containing lines.
1346
835
A trailing newline is added if missing to make the strings
1347
836
print properly."""
1348
837
if b and b[-1] != '\n':
1745
1147
def _startLogFile(self):
1746
"""Setup a in-memory target for bzr and testcase log messages"""
1747
pseudo_log_file = StringIO()
1748
def _get_log_contents_for_weird_testtools_api():
1749
return [pseudo_log_file.getvalue().decode(
1750
"utf-8", "replace").encode("utf-8")]
1751
self.addDetail("log", content.Content(content.ContentType("text",
1752
"plain", {"charset": "utf8"}),
1753
_get_log_contents_for_weird_testtools_api))
1754
self._log_file = pseudo_log_file
1755
self._log_memento = trace.push_log_file(self._log_file)
1148
"""Send bzr and test log messages to a temporary file.
1150
The file is removed as the test is torn down.
1152
fileno, name = tempfile.mkstemp(suffix='.log', prefix='testbzr')
1153
self._log_file = os.fdopen(fileno, 'w+')
1154
self._log_nonce = bzrlib.trace.enable_test_log(self._log_file)
1155
self._log_file_name = name
1756
1156
self.addCleanup(self._finishLogFile)
1758
1158
def _finishLogFile(self):
1759
"""Flush and dereference the in-memory log for this testcase"""
1760
if trace._trace_file:
1761
# flush the log file, to get all content
1762
trace._trace_file.flush()
1763
trace.pop_log_file(self._log_memento)
1764
# The logging module now tracks references for cleanup so discard ours
1765
del self._log_memento
1767
def thisFailsStrictLockCheck(self):
1768
"""It is known that this test would fail with -Dstrict_locks.
1770
By default, all tests are run with strict lock checking unless
1771
-Edisable_lock_checks is supplied. However there are some tests which
1772
we know fail strict locks at this point that have not been fixed.
1773
They should call this function to disable the strict checking.
1775
This should be used sparingly, it is much better to fix the locking
1776
issues rather than papering over the problem by calling this function.
1778
debug.debug_flags.discard('strict_locks')
1780
def overrideAttr(self, obj, attr_name, new=_unitialized_attr):
1781
"""Overrides an object attribute restoring it after the test.
1783
:note: This should be used with discretion; you should think about
1784
whether it's better to make the code testable without monkey-patching.
1786
:param obj: The object that will be mutated.
1788
:param attr_name: The attribute name we want to preserve/override in
1791
:param new: The optional value we want to set the attribute to.
1793
:returns: The actual attr value.
1795
# The actual value is captured by the call below
1796
value = getattr(obj, attr_name, _unitialized_attr)
1797
if value is _unitialized_attr:
1798
# When the test completes, the attribute should not exist, but if
1799
# we aren't setting a value, we don't need to do anything.
1800
if new is not _unitialized_attr:
1801
self.addCleanup(delattr, obj, attr_name)
1803
self.addCleanup(setattr, obj, attr_name, value)
1804
if new is not _unitialized_attr:
1805
setattr(obj, attr_name, new)
1808
def overrideEnv(self, name, new):
1809
"""Set an environment variable, and reset it after the test.
1811
:param name: The environment variable name.
1813
:param new: The value to set the variable to. If None, the
1814
variable is deleted from the environment.
1816
:returns: The actual variable value.
1818
value = osutils.set_or_unset_env(name, new)
1819
self.addCleanup(osutils.set_or_unset_env, name, value)
1822
def recordCalls(self, obj, attr_name):
1823
"""Monkeypatch in a wrapper that will record calls.
1825
The monkeypatch is automatically removed when the test concludes.
1827
:param obj: The namespace holding the reference to be replaced;
1828
typically a module, class, or object.
1829
:param attr_name: A string for the name of the attribute to
1831
:returns: A list that will be extended with one item every time the
1832
function is called, with a tuple of (args, kwargs).
1836
def decorator(*args, **kwargs):
1837
calls.append((args, kwargs))
1838
return orig(*args, **kwargs)
1839
orig = self.overrideAttr(obj, attr_name, decorator)
1159
"""Finished with the log file.
1161
Close the file and delete it, unless setKeepLogfile was called.
1163
if self._log_file is None:
1165
bzrlib.trace.disable_test_log(self._log_nonce)
1166
self._log_file.close()
1167
self._log_file = None
1168
if not self._keep_log_file:
1169
os.remove(self._log_file_name)
1170
self._log_file_name = None
1172
def setKeepLogfile(self):
1173
"""Make the logfile not be deleted when _finishLogFile is called."""
1174
self._keep_log_file = True
1176
def addCleanup(self, callable):
1177
"""Arrange to run a callable when this case is torn down.
1179
Callables are run in the reverse of the order they are registered,
1180
ie last-in first-out.
1182
if callable in self._cleanups:
1183
raise ValueError("cleanup function %r already registered on %s"
1185
self._cleanups.append(callable)
1842
1187
def _cleanEnvironment(self):
1843
for name, value in isolated_environ.iteritems():
1844
self.overrideEnv(name, value)
1189
'BZR_HOME': None, # Don't inherit BZR_HOME to all the tests.
1190
'HOME': os.getcwd(),
1191
'APPDATA': None, # bzr now use Win32 API and don't rely on APPDATA
1192
'BZR_EDITOR': None, # test_msgeditor manipulates this variable
1194
'BZREMAIL': None, # may still be present in the environment
1196
'BZR_PROGRESS_BAR': None,
1198
'SSH_AUTH_SOCK': None,
1202
'https_proxy': None,
1203
'HTTPS_PROXY': None,
1208
# Nobody cares about these ones AFAIK. So far at
1209
# least. If you do (care), please update this comment
1213
'BZR_REMOTE_PATH': None,
1216
self.addCleanup(self._restoreEnvironment)
1217
for name, value in new_env.iteritems():
1218
self._captureVar(name, value)
1220
def _captureVar(self, name, newvalue):
1221
"""Set an environment variable, and reset it when finished."""
1222
self.__old_env[name] = osutils.set_or_unset_env(name, newvalue)
1224
def _restore_debug_flags(self):
1225
debug.debug_flags.clear()
1226
debug.debug_flags.update(self._preserved_debug_flags)
1228
def _restoreEnvironment(self):
1229
for name, value in self.__old_env.iteritems():
1230
osutils.set_or_unset_env(name, value)
1846
1232
def _restoreHooks(self):
1847
for klass, (name, hooks) in self._preserved_hooks.items():
1848
setattr(klass, name, hooks)
1849
self._preserved_hooks.clear()
1850
bzrlib.hooks._lazy_hooks = self._preserved_lazy_hooks
1851
self._preserved_lazy_hooks.clear()
1233
for klass, hooks in self._preserved_hooks.items():
1234
setattr(klass, 'hooks', hooks)
1853
1236
def knownFailure(self, reason):
1854
"""Declare that this test fails for a known reason
1856
Tests that are known to fail should generally be using expectedFailure
1857
with an appropriate reverse assertion if a change could cause the test
1858
to start passing. Conversely if the test has no immediate prospect of
1859
succeeding then using skip is more suitable.
1861
When this method is called while an exception is being handled, that
1862
traceback will be used, otherwise a new exception will be thrown to
1863
provide one but won't be reported.
1865
self._add_reason(reason)
1867
exc_info = sys.exc_info()
1868
if exc_info != (None, None, None):
1869
self._report_traceback(exc_info)
1872
raise self.failureException(reason)
1873
except self.failureException:
1874
exc_info = sys.exc_info()
1875
# GZ 02-08-2011: Maybe cleanup this err.exc_info attribute too?
1876
raise testtools.testcase._ExpectedFailure(exc_info)
1880
def _suppress_log(self):
1881
"""Remove the log info from details."""
1882
self.discardDetail('log')
1884
def _do_skip(self, result, reason):
1885
self._suppress_log()
1886
addSkip = getattr(result, 'addSkip', None)
1887
if not callable(addSkip):
1888
result.addSuccess(result)
1890
addSkip(self, reason)
1893
def _do_known_failure(self, result, e):
1894
self._suppress_log()
1895
err = sys.exc_info()
1896
addExpectedFailure = getattr(result, 'addExpectedFailure', None)
1897
if addExpectedFailure is not None:
1898
addExpectedFailure(self, err)
1900
result.addSuccess(self)
1903
def _do_not_applicable(self, result, e):
1905
reason = 'No reason given'
1908
self._suppress_log ()
1909
addNotApplicable = getattr(result, 'addNotApplicable', None)
1910
if addNotApplicable is not None:
1911
result.addNotApplicable(self, reason)
1913
self._do_skip(result, reason)
1916
def _report_skip(self, result, err):
1917
"""Override the default _report_skip.
1919
We want to strip the 'log' detail. If we waint until _do_skip, it has
1920
already been formatted into the 'reason' string, and we can't pull it
1923
self._suppress_log()
1924
super(TestCase, self)._report_skip(self, result, err)
1927
def _report_expected_failure(self, result, err):
1930
See _report_skip for motivation.
1932
self._suppress_log()
1933
super(TestCase, self)._report_expected_failure(self, result, err)
1936
def _do_unsupported_or_skip(self, result, e):
1938
self._suppress_log()
1939
addNotSupported = getattr(result, 'addNotSupported', None)
1940
if addNotSupported is not None:
1941
result.addNotSupported(self, reason)
1943
self._do_skip(result, reason)
1237
"""This test has failed for some known reason."""
1238
raise KnownFailure(reason)
1240
def run(self, result=None):
1241
if result is None: result = self.defaultTestResult()
1242
for feature in getattr(self, '_test_needs_features', []):
1243
if not feature.available():
1244
result.startTest(self)
1245
if getattr(result, 'addNotSupported', None):
1246
result.addNotSupported(self, feature)
1248
result.addSuccess(self)
1249
result.stopTest(self)
1251
return unittest.TestCase.run(self, result)
1255
unittest.TestCase.tearDown(self)
1945
1257
def time(self, callable, *args, **kwargs):
1946
1258
"""Run callable and accrue the time it takes to the benchmark time.
1948
1260
If lsprofiling is enabled (i.e. by --lsprof-time to bzr selftest) then
1949
1261
this will cause lsprofile statistics to be gathered and stored in
1950
1262
self._benchcalls.
1952
1264
if self._benchtime is None:
1953
self.addDetail('benchtime', content.Content(content.ContentType(
1954
"text", "plain"), lambda:[str(self._benchtime)]))
1955
1265
self._benchtime = 0
1956
1266
start = time.time()
3082
2217
for readonly urls.
3084
2219
TODO RBC 20060127: make this an option to TestCaseWithTransport so it can
3085
be used without needed to redo it when a different
2220
be used without needed to redo it when a different
3086
2221
subclass is in use ?
3089
2224
def setUp(self):
3090
from bzrlib.tests import http_server
3091
2225
super(ChrootedTestCase, self).setUp()
3092
if not self.vfs_transport_factory == memory.MemoryServer:
3093
self.transport_readonly_server = http_server.HttpServer
3096
def condition_id_re(pattern):
3097
"""Create a condition filter which performs a re check on a test's id.
3099
:param pattern: A regular expression string.
3100
:return: A callable that returns True if the re matches.
3102
filter_re = re.compile(pattern, 0)
3103
def condition(test):
2226
if not self.vfs_transport_factory == MemoryServer:
2227
self.transport_readonly_server = HttpServer
2230
def filter_suite_by_re(suite, pattern, exclude_pattern=None,
2231
random_order=False):
2232
"""Create a test suite by filtering another one.
2234
:param suite: the source suite
2235
:param pattern: pattern that names must match
2236
:param exclude_pattern: pattern that names must not match, if any
2237
:param random_order: if True, tests in the new suite will be put in
2239
:returns: the newly created suite
2241
return sort_suite_by_re(suite, pattern, exclude_pattern,
2242
random_order, False)
2245
def sort_suite_by_re(suite, pattern, exclude_pattern=None,
2246
random_order=False, append_rest=True):
2247
"""Create a test suite by sorting another one.
2249
:param suite: the source suite
2250
:param pattern: pattern that names must match in order to go
2251
first in the new suite
2252
:param exclude_pattern: pattern that names must not match, if any
2253
:param random_order: if True, tests in the new suite will be put in
2255
:param append_rest: if False, pattern is a strict filter and not
2256
just an ordering directive
2257
:returns: the newly created suite
2261
filter_re = re.compile(pattern)
2262
if exclude_pattern is not None:
2263
exclude_re = re.compile(exclude_pattern)
2264
for test in iter_suite_tests(suite):
3104
2265
test_id = test.id()
3105
return filter_re.search(test_id)
3109
def condition_isinstance(klass_or_klass_list):
3110
"""Create a condition filter which returns isinstance(param, klass).
3112
:return: A callable which when called with one parameter obj return the
3113
result of isinstance(obj, klass_or_klass_list).
3116
return isinstance(obj, klass_or_klass_list)
3120
def condition_id_in_list(id_list):
3121
"""Create a condition filter which verify that test's id in a list.
3123
:param id_list: A TestIdList object.
3124
:return: A callable that returns True if the test's id appears in the list.
3126
def condition(test):
3127
return id_list.includes(test.id())
3131
def condition_id_startswith(starts):
3132
"""Create a condition filter verifying that test's id starts with a string.
3134
:param starts: A list of string.
3135
:return: A callable that returns True if the test's id starts with one of
3138
def condition(test):
3139
for start in starts:
3140
if test.id().startswith(start):
3146
def exclude_tests_by_condition(suite, condition):
3147
"""Create a test suite which excludes some tests from suite.
3149
:param suite: The suite to get tests from.
3150
:param condition: A callable whose result evaluates True when called with a
3151
test case which should be excluded from the result.
3152
:return: A suite which contains the tests found in suite that fail
3156
for test in iter_suite_tests(suite):
3157
if not condition(test):
3159
return TestUtil.TestSuite(result)
3162
def filter_suite_by_condition(suite, condition):
3163
"""Create a test suite by filtering another one.
3165
:param suite: The source suite.
3166
:param condition: A callable whose result evaluates True when called with a
3167
test case which should be included in the result.
3168
:return: A suite which contains the tests found in suite that pass
3172
for test in iter_suite_tests(suite):
3175
return TestUtil.TestSuite(result)
3178
def filter_suite_by_re(suite, pattern):
3179
"""Create a test suite by filtering another one.
3181
:param suite: the source suite
3182
:param pattern: pattern that names must match
3183
:returns: the newly created suite
3185
condition = condition_id_re(pattern)
3186
result_suite = filter_suite_by_condition(suite, condition)
3190
def filter_suite_by_id_list(suite, test_id_list):
3191
"""Create a test suite by filtering another one.
3193
:param suite: The source suite.
3194
:param test_id_list: A list of the test ids to keep as strings.
3195
:returns: the newly created suite
3197
condition = condition_id_in_list(test_id_list)
3198
result_suite = filter_suite_by_condition(suite, condition)
3202
def filter_suite_by_id_startswith(suite, start):
3203
"""Create a test suite by filtering another one.
3205
:param suite: The source suite.
3206
:param start: A list of string the test id must start with one of.
3207
:returns: the newly created suite
3209
condition = condition_id_startswith(start)
3210
result_suite = filter_suite_by_condition(suite, condition)
3214
def exclude_tests_by_re(suite, pattern):
3215
"""Create a test suite which excludes some tests from suite.
3217
:param suite: The suite to get tests from.
3218
:param pattern: A regular expression string. Test ids that match this
3219
pattern will be excluded from the result.
3220
:return: A TestSuite that contains all the tests from suite without the
3221
tests that matched pattern. The order of tests is the same as it was in
3224
return exclude_tests_by_condition(suite, condition_id_re(pattern))
3227
def preserve_input(something):
3228
"""A helper for performing test suite transformation chains.
3230
:param something: Anything you want to preserve.
3236
def randomize_suite(suite):
3237
"""Return a new TestSuite with suite's tests in random order.
3239
The tests in the input suite are flattened into a single suite in order to
3240
accomplish this. Any nested TestSuites are removed to provide global
3243
tests = list(iter_suite_tests(suite))
3244
random.shuffle(tests)
3245
return TestUtil.TestSuite(tests)
3248
def split_suite_by_condition(suite, condition):
3249
"""Split a test suite into two by a condition.
3251
:param suite: The suite to split.
3252
:param condition: The condition to match on. Tests that match this
3253
condition are returned in the first test suite, ones that do not match
3254
are in the second suite.
3255
:return: A tuple of two test suites, where the first contains tests from
3256
suite matching the condition, and the second contains the remainder
3257
from suite. The order within each output suite is the same as it was in
3262
for test in iter_suite_tests(suite):
3264
matched.append(test)
3266
did_not_match.append(test)
3267
return TestUtil.TestSuite(matched), TestUtil.TestSuite(did_not_match)
3270
def split_suite_by_re(suite, pattern):
3271
"""Split a test suite into two by a regular expression.
3273
:param suite: The suite to split.
3274
:param pattern: A regular expression string. Test ids that match this
3275
pattern will be in the first test suite returned, and the others in the
3276
second test suite returned.
3277
:return: A tuple of two test suites, where the first contains tests from
3278
suite matching pattern, and the second contains the remainder from
3279
suite. The order within each output suite is the same as it was in
3282
return split_suite_by_condition(suite, condition_id_re(pattern))
2266
if exclude_pattern is None or not exclude_re.search(test_id):
2267
if filter_re.search(test_id):
2272
random.shuffle(first)
2273
random.shuffle(second)
2274
return TestUtil.TestSuite(first + second)
3285
2277
def run_suite(suite, name='test', verbose=False, pattern=".*",
3290
2282
random_seed=None,
3291
2283
exclude_pattern=None,
3294
suite_decorators=None,
3296
result_decorators=None,
3298
"""Run a test suite for bzr selftest.
3300
:param runner_class: The class of runner to use. Must support the
3301
constructor arguments passed by run_suite which are more than standard
3303
:return: A boolean indicating success.
3305
2286
TestCase._gather_lsprof_in_benchmarks = lsprof_timed
3310
if runner_class is None:
3311
runner_class = TextTestRunner
3314
runner = runner_class(stream=stream,
2291
runner = TextTestRunner(stream=sys.stdout,
3315
2292
descriptions=0,
3316
2293
verbosity=verbosity,
3317
2294
bench_history=bench_history,
3319
result_decorators=result_decorators,
2295
list_only=list_only,
3321
2297
runner.stop_on_failure=stop_on_failure
3322
if isinstance(suite, unittest.TestSuite):
3323
# Empty out _tests list of passed suite and populate new TestSuite
3324
suite._tests[:], suite = [], TestSuite(suite)
3325
# built in decorator factories:
3327
random_order(random_seed, runner),
3328
exclude_tests(exclude_pattern),
3330
if matching_tests_first:
3331
decorators.append(tests_first(pattern))
3333
decorators.append(filter_tests(pattern))
3334
if suite_decorators:
3335
decorators.extend(suite_decorators)
3336
# tell the result object how many tests will be running: (except if
3337
# --parallel=fork is being used. Robert said he will provide a better
3338
# progress design later -- vila 20090817)
3339
if fork_decorator not in decorators:
3340
decorators.append(CountingDecorator)
3341
for decorator in decorators:
3342
suite = decorator(suite)
3344
# Done after test suite decoration to allow randomisation etc
3345
# to take effect, though that is of marginal benefit.
3347
stream.write("Listing tests only ...\n")
3348
for t in iter_suite_tests(suite):
3349
stream.write("%s\n" % (t.id()))
2298
# Initialise the random number generator and display the seed used.
2299
# We convert the seed to a long to make it reuseable across invocations.
2300
random_order = False
2301
if random_seed is not None:
2303
if random_seed == "now":
2304
random_seed = long(time.time())
2306
# Convert the seed to a long if we can
2308
random_seed = long(random_seed)
2311
runner.stream.writeln("Randomizing test order using seed %s\n" %
2313
random.seed(random_seed)
2314
# Customise the list of tests if requested
2315
if pattern != '.*' or exclude_pattern is not None or random_order:
2316
if matching_tests_first:
2317
suite = sort_suite_by_re(suite, pattern, exclude_pattern,
2320
suite = filter_suite_by_re(suite, pattern, exclude_pattern,
3351
2322
result = runner.run(suite)
3353
2325
return result.wasStrictlySuccessful()
3355
return result.wasSuccessful()
3358
# A registry where get() returns a suite decorator.
3359
parallel_registry = registry.Registry()
3362
def fork_decorator(suite):
3363
if getattr(os, "fork", None) is None:
3364
raise errors.BzrCommandError("platform does not support fork,"
3365
" try --parallel=subprocess instead.")
3366
concurrency = osutils.local_concurrency()
3367
if concurrency == 1:
3369
from testtools import ConcurrentTestSuite
3370
return ConcurrentTestSuite(suite, fork_for_tests)
3371
parallel_registry.register('fork', fork_decorator)
3374
def subprocess_decorator(suite):
3375
concurrency = osutils.local_concurrency()
3376
if concurrency == 1:
3378
from testtools import ConcurrentTestSuite
3379
return ConcurrentTestSuite(suite, reinvoke_for_tests)
3380
parallel_registry.register('subprocess', subprocess_decorator)
3383
def exclude_tests(exclude_pattern):
3384
"""Return a test suite decorator that excludes tests."""
3385
if exclude_pattern is None:
3386
return identity_decorator
3387
def decorator(suite):
3388
return ExcludeDecorator(suite, exclude_pattern)
3392
def filter_tests(pattern):
3394
return identity_decorator
3395
def decorator(suite):
3396
return FilterTestsDecorator(suite, pattern)
3400
def random_order(random_seed, runner):
3401
"""Return a test suite decorator factory for randomising tests order.
3403
:param random_seed: now, a string which casts to a long, or a long.
3404
:param runner: A test runner with a stream attribute to report on.
3406
if random_seed is None:
3407
return identity_decorator
3408
def decorator(suite):
3409
return RandomDecorator(suite, random_seed, runner.stream)
3413
def tests_first(pattern):
3415
return identity_decorator
3416
def decorator(suite):
3417
return TestFirstDecorator(suite, pattern)
3421
def identity_decorator(suite):
3426
class TestDecorator(TestUtil.TestSuite):
3427
"""A decorator for TestCase/TestSuite objects.
3429
Contains rather than flattening suite passed on construction
3432
def __init__(self, suite=None):
3433
super(TestDecorator, self).__init__()
3434
if suite is not None:
3437
# Don't need subclass run method with suite emptying
3438
run = unittest.TestSuite.run
3441
class CountingDecorator(TestDecorator):
3442
"""A decorator which calls result.progress(self.countTestCases)."""
3444
def run(self, result):
3445
progress_method = getattr(result, 'progress', None)
3446
if callable(progress_method):
3447
progress_method(self.countTestCases(), SUBUNIT_SEEK_SET)
3448
return super(CountingDecorator, self).run(result)
3451
class ExcludeDecorator(TestDecorator):
3452
"""A decorator which excludes test matching an exclude pattern."""
3454
def __init__(self, suite, exclude_pattern):
3455
super(ExcludeDecorator, self).__init__(
3456
exclude_tests_by_re(suite, exclude_pattern))
3459
class FilterTestsDecorator(TestDecorator):
3460
"""A decorator which filters tests to those matching a pattern."""
3462
def __init__(self, suite, pattern):
3463
super(FilterTestsDecorator, self).__init__(
3464
filter_suite_by_re(suite, pattern))
3467
class RandomDecorator(TestDecorator):
3468
"""A decorator which randomises the order of its tests."""
3470
def __init__(self, suite, random_seed, stream):
3471
random_seed = self.actual_seed(random_seed)
3472
stream.write("Randomizing test order using seed %s\n\n" %
3474
# Initialise the random number generator.
3475
random.seed(random_seed)
3476
super(RandomDecorator, self).__init__(randomize_suite(suite))
3479
def actual_seed(seed):
3481
# We convert the seed to a long to make it reuseable across
3482
# invocations (because the user can reenter it).
3483
return long(time.time())
3485
# Convert the seed to a long if we can
3488
except (TypeError, ValueError):
3493
class TestFirstDecorator(TestDecorator):
3494
"""A decorator which moves named tests to the front."""
3496
def __init__(self, suite, pattern):
3497
super(TestFirstDecorator, self).__init__()
3498
self.addTests(split_suite_by_re(suite, pattern))
3501
def partition_tests(suite, count):
3502
"""Partition suite into count lists of tests."""
3503
# This just assigns tests in a round-robin fashion. On one hand this
3504
# splits up blocks of related tests that might run faster if they shared
3505
# resources, but on the other it avoids assigning blocks of slow tests to
3506
# just one partition. So the slowest partition shouldn't be much slower
3508
partitions = [list() for i in range(count)]
3509
tests = iter_suite_tests(suite)
3510
for partition, test in itertools.izip(itertools.cycle(partitions), tests):
3511
partition.append(test)
3515
def workaround_zealous_crypto_random():
3516
"""Crypto.Random want to help us being secure, but we don't care here.
3518
This workaround some test failure related to the sftp server. Once paramiko
3519
stop using the controversial API in Crypto.Random, we may get rid of it.
3522
from Crypto.Random import atfork
3528
def fork_for_tests(suite):
3529
"""Take suite and start up one runner per CPU by forking()
3531
:return: An iterable of TestCase-like objects which can each have
3532
run(result) called on them to feed tests to result.
3534
concurrency = osutils.local_concurrency()
3536
from subunit import ProtocolTestCase
3537
from subunit.test_results import AutoTimingTestResultDecorator
3538
class TestInOtherProcess(ProtocolTestCase):
3539
# Should be in subunit, I think. RBC.
3540
def __init__(self, stream, pid):
3541
ProtocolTestCase.__init__(self, stream)
3544
def run(self, result):
3546
ProtocolTestCase.run(self, result)
3548
pid, status = os.waitpid(self.pid, 0)
3549
# GZ 2011-10-18: If status is nonzero, should report to the result
3550
# that something went wrong.
3552
test_blocks = partition_tests(suite, concurrency)
3553
# Clear the tests from the original suite so it doesn't keep them alive
3554
suite._tests[:] = []
3555
for process_tests in test_blocks:
3556
process_suite = TestUtil.TestSuite(process_tests)
3557
# Also clear each split list so new suite has only reference
3558
process_tests[:] = []
3559
c2pread, c2pwrite = os.pipe()
3563
stream = os.fdopen(c2pwrite, 'wb', 1)
3564
workaround_zealous_crypto_random()
3566
# Leave stderr and stdout open so we can see test noise
3567
# Close stdin so that the child goes away if it decides to
3568
# read from stdin (otherwise its a roulette to see what
3569
# child actually gets keystrokes for pdb etc).
3571
subunit_result = AutoTimingTestResultDecorator(
3572
SubUnitBzrProtocolClient(stream))
3573
process_suite.run(subunit_result)
3575
# Try and report traceback on stream, but exit with error even
3576
# if stream couldn't be created or something else goes wrong.
3577
# The traceback is formatted to a string and written in one go
3578
# to avoid interleaving lines from multiple failing children.
3580
stream.write(traceback.format_exc())
3586
stream = os.fdopen(c2pread, 'rb', 1)
3587
test = TestInOtherProcess(stream, pid)
3592
def reinvoke_for_tests(suite):
3593
"""Take suite and start up one runner per CPU using subprocess().
3595
:return: An iterable of TestCase-like objects which can each have
3596
run(result) called on them to feed tests to result.
3598
concurrency = osutils.local_concurrency()
3600
from subunit import ProtocolTestCase
3601
class TestInSubprocess(ProtocolTestCase):
3602
def __init__(self, process, name):
3603
ProtocolTestCase.__init__(self, process.stdout)
3604
self.process = process
3605
self.process.stdin.close()
3608
def run(self, result):
3610
ProtocolTestCase.run(self, result)
3613
os.unlink(self.name)
3614
# print "pid %d finished" % finished_process
3615
test_blocks = partition_tests(suite, concurrency)
3616
for process_tests in test_blocks:
3617
# ugly; currently reimplement rather than reuses TestCase methods.
3618
bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
3619
if not os.path.isfile(bzr_path):
3620
# We are probably installed. Assume sys.argv is the right file
3621
bzr_path = sys.argv[0]
3622
bzr_path = [bzr_path]
3623
if sys.platform == "win32":
3624
# if we're on windows, we can't execute the bzr script directly
3625
bzr_path = [sys.executable] + bzr_path
3626
fd, test_list_file_name = tempfile.mkstemp()
3627
test_list_file = os.fdopen(fd, 'wb', 1)
3628
for test in process_tests:
3629
test_list_file.write(test.id() + '\n')
3630
test_list_file.close()
3632
argv = bzr_path + ['selftest', '--load-list', test_list_file_name,
3634
if '--no-plugins' in sys.argv:
3635
argv.append('--no-plugins')
3636
# stderr=subprocess.STDOUT would be ideal, but until we prevent
3637
# noise on stderr it can interrupt the subunit protocol.
3638
process = subprocess.Popen(argv, stdin=subprocess.PIPE,
3639
stdout=subprocess.PIPE,
3640
stderr=subprocess.PIPE,
3642
test = TestInSubprocess(process, test_list_file_name)
3645
os.unlink(test_list_file_name)
3650
class ProfileResult(testtools.ExtendedToOriginalDecorator):
3651
"""Generate profiling data for all activity between start and success.
3653
The profile data is appended to the test's _benchcalls attribute and can
3654
be accessed by the forwarded-to TestResult.
3656
While it might be cleaner do accumulate this in stopTest, addSuccess is
3657
where our existing output support for lsprof is, and this class aims to
3658
fit in with that: while it could be moved it's not necessary to accomplish
3659
test profiling, nor would it be dramatically cleaner.
3662
def startTest(self, test):
3663
self.profiler = bzrlib.lsprof.BzrProfiler()
3664
# Prevent deadlocks in tests that use lsprof: those tests will
3666
bzrlib.lsprof.BzrProfiler.profiler_block = 0
3667
self.profiler.start()
3668
testtools.ExtendedToOriginalDecorator.startTest(self, test)
3670
def addSuccess(self, test):
3671
stats = self.profiler.stop()
3673
calls = test._benchcalls
3674
except AttributeError:
3675
test._benchcalls = []
3676
calls = test._benchcalls
3677
calls.append(((test.id(), "", ""), stats))
3678
testtools.ExtendedToOriginalDecorator.addSuccess(self, test)
3680
def stopTest(self, test):
3681
testtools.ExtendedToOriginalDecorator.stopTest(self, test)
3682
self.profiler = None
3685
# Controlled by "bzr selftest -E=..." option
3686
# Currently supported:
3687
# -Eallow_debug Will no longer clear debug.debug_flags() so it
3688
# preserves any flags supplied at the command line.
3689
# -Edisable_lock_checks Turns errors in mismatched locks into simple prints
3690
# rather than failing tests. And no longer raise
3691
# LockContention when fctnl locks are not being used
3692
# with proper exclusion rules.
3693
# -Ethreads Will display thread ident at creation/join time to
3694
# help track thread leaks
3695
# -Euncollected_cases Display the identity of any test cases that weren't
3696
# deallocated after being completed.
3697
# -Econfig_stats Will collect statistics using addDetail
3698
selftest_debug_flags = set()
2327
return result.wasSuccessful()
3701
2330
def selftest(verbose=False, pattern=".*", stop_on_failure=True,
3761
2364
list_only=list_only,
3762
2365
random_seed=random_seed,
3763
2366
exclude_pattern=exclude_pattern,
3765
runner_class=runner_class,
3766
suite_decorators=suite_decorators,
3768
result_decorators=result_decorators,
3771
2369
default_transport = old_transport
3772
selftest_debug_flags = old_debug_flags
3775
def load_test_id_list(file_name):
3776
"""Load a test id list from a text file.
3778
The format is one test id by line. No special care is taken to impose
3779
strict rules, these test ids are used to filter the test suite so a test id
3780
that do not match an existing test will do no harm. This allows user to add
3781
comments, leave blank lines, etc.
3785
ftest = open(file_name, 'rt')
3787
if e.errno != errno.ENOENT:
3790
raise errors.NoSuchFile(file_name)
3792
for test_name in ftest.readlines():
3793
test_list.append(test_name.strip())
3798
def suite_matches_id_list(test_suite, id_list):
3799
"""Warns about tests not appearing or appearing more than once.
3801
:param test_suite: A TestSuite object.
3802
:param test_id_list: The list of test ids that should be found in
3805
:return: (absents, duplicates) absents is a list containing the test found
3806
in id_list but not in test_suite, duplicates is a list containing the
3807
tests found multiple times in test_suite.
3809
When using a prefined test id list, it may occurs that some tests do not
3810
exist anymore or that some tests use the same id. This function warns the
3811
tester about potential problems in his workflow (test lists are volatile)
3812
or in the test suite itself (using the same id for several tests does not
3813
help to localize defects).
3815
# Build a dict counting id occurrences
3817
for test in iter_suite_tests(test_suite):
3819
tests[id] = tests.get(id, 0) + 1
3824
occurs = tests.get(id, 0)
3826
not_found.append(id)
3828
duplicates.append(id)
3830
return not_found, duplicates
3833
class TestIdList(object):
3834
"""Test id list to filter a test suite.
3836
Relying on the assumption that test ids are built as:
3837
<module>[.<class>.<method>][(<param>+)], <module> being in python dotted
3838
notation, this class offers methods to :
3839
- avoid building a test suite for modules not refered to in the test list,
3840
- keep only the tests listed from the module test suite.
3843
def __init__(self, test_id_list):
3844
# When a test suite needs to be filtered against us we compare test ids
3845
# for equality, so a simple dict offers a quick and simple solution.
3846
self.tests = dict().fromkeys(test_id_list, True)
3848
# While unittest.TestCase have ids like:
3849
# <module>.<class>.<method>[(<param+)],
3850
# doctest.DocTestCase can have ids like:
3853
# <module>.<function>
3854
# <module>.<class>.<method>
3856
# Since we can't predict a test class from its name only, we settle on
3857
# a simple constraint: a test id always begins with its module name.
3860
for test_id in test_id_list:
3861
parts = test_id.split('.')
3862
mod_name = parts.pop(0)
3863
modules[mod_name] = True
3865
mod_name += '.' + part
3866
modules[mod_name] = True
3867
self.modules = modules
3869
def refers_to(self, module_name):
3870
"""Is there tests for the module or one of its sub modules."""
3871
return self.modules.has_key(module_name)
3873
def includes(self, test_id):
3874
return self.tests.has_key(test_id)
3877
class TestPrefixAliasRegistry(registry.Registry):
3878
"""A registry for test prefix aliases.
3880
This helps implement shorcuts for the --starting-with selftest
3881
option. Overriding existing prefixes is not allowed but not fatal (a
3882
warning will be emitted).
3885
def register(self, key, obj, help=None, info=None,
3886
override_existing=False):
3887
"""See Registry.register.
3889
Trying to override an existing alias causes a warning to be emitted,
3890
not a fatal execption.
3893
super(TestPrefixAliasRegistry, self).register(
3894
key, obj, help=help, info=info, override_existing=False)
3896
actual = self.get(key)
3898
'Test prefix alias %s is already used for %s, ignoring %s'
3899
% (key, actual, obj))
3901
def resolve_alias(self, id_start):
3902
"""Replace the alias by the prefix in the given string.
3904
Using an unknown prefix is an error to help catching typos.
3906
parts = id_start.split('.')
3908
parts[0] = self.get(parts[0])
3910
raise errors.BzrCommandError(
3911
'%s is not a known test prefix alias' % parts[0])
3912
return '.'.join(parts)
3915
test_prefix_alias_registry = TestPrefixAliasRegistry()
3916
"""Registry of test prefix aliases."""
3919
# This alias allows to detect typos ('bzrlin.') by making all valid test ids
3920
# appear prefixed ('bzrlib.' is "replaced" by 'bzrlib.').
3921
test_prefix_alias_registry.register('bzrlib', 'bzrlib')
3923
# Obvious highest levels prefixes, feel free to add your own via a plugin
3924
test_prefix_alias_registry.register('bd', 'bzrlib.doc')
3925
test_prefix_alias_registry.register('bu', 'bzrlib.utils')
3926
test_prefix_alias_registry.register('bt', 'bzrlib.tests')
3927
test_prefix_alias_registry.register('bb', 'bzrlib.tests.blackbox')
3928
test_prefix_alias_registry.register('bp', 'bzrlib.plugins')
3931
def _test_suite_testmod_names():
3932
"""Return the standard list of test module names to test."""
3935
'bzrlib.tests.blackbox',
3936
'bzrlib.tests.commands',
3937
'bzrlib.tests.per_branch',
3938
'bzrlib.tests.per_bzrdir',
3939
'bzrlib.tests.per_controldir',
3940
'bzrlib.tests.per_controldir_colo',
3941
'bzrlib.tests.per_foreign_vcs',
3942
'bzrlib.tests.per_interrepository',
3943
'bzrlib.tests.per_intertree',
3944
'bzrlib.tests.per_inventory',
3945
'bzrlib.tests.per_interbranch',
3946
'bzrlib.tests.per_lock',
3947
'bzrlib.tests.per_merger',
3948
'bzrlib.tests.per_transport',
3949
'bzrlib.tests.per_tree',
3950
'bzrlib.tests.per_pack_repository',
3951
'bzrlib.tests.per_repository',
3952
'bzrlib.tests.per_repository_chk',
3953
'bzrlib.tests.per_repository_reference',
3954
'bzrlib.tests.per_repository_vf',
3955
'bzrlib.tests.per_uifactory',
3956
'bzrlib.tests.per_versionedfile',
3957
'bzrlib.tests.per_workingtree',
3958
'bzrlib.tests.test__annotator',
3959
'bzrlib.tests.test__bencode',
3960
'bzrlib.tests.test__btree_serializer',
3961
'bzrlib.tests.test__chk_map',
3962
'bzrlib.tests.test__dirstate_helpers',
3963
'bzrlib.tests.test__groupcompress',
3964
'bzrlib.tests.test__known_graph',
3965
'bzrlib.tests.test__rio',
3966
'bzrlib.tests.test__simple_set',
3967
'bzrlib.tests.test__static_tuple',
3968
'bzrlib.tests.test__walkdirs_win32',
3969
'bzrlib.tests.test_ancestry',
3970
'bzrlib.tests.test_annotate',
3971
'bzrlib.tests.test_api',
3972
'bzrlib.tests.test_atomicfile',
3973
'bzrlib.tests.test_bad_files',
3974
'bzrlib.tests.test_bisect_multi',
3975
'bzrlib.tests.test_branch',
3976
'bzrlib.tests.test_branchbuilder',
3977
'bzrlib.tests.test_btree_index',
3978
'bzrlib.tests.test_bugtracker',
3979
'bzrlib.tests.test_bundle',
3980
'bzrlib.tests.test_bzrdir',
3981
'bzrlib.tests.test__chunks_to_lines',
3982
'bzrlib.tests.test_cache_utf8',
3983
'bzrlib.tests.test_chk_map',
3984
'bzrlib.tests.test_chk_serializer',
3985
'bzrlib.tests.test_chunk_writer',
3986
'bzrlib.tests.test_clean_tree',
3987
'bzrlib.tests.test_cleanup',
3988
'bzrlib.tests.test_cmdline',
3989
'bzrlib.tests.test_commands',
3990
'bzrlib.tests.test_commit',
3991
'bzrlib.tests.test_commit_merge',
3992
'bzrlib.tests.test_config',
3993
'bzrlib.tests.test_conflicts',
3994
'bzrlib.tests.test_controldir',
3995
'bzrlib.tests.test_counted_lock',
3996
'bzrlib.tests.test_crash',
3997
'bzrlib.tests.test_decorators',
3998
'bzrlib.tests.test_delta',
3999
'bzrlib.tests.test_debug',
4000
'bzrlib.tests.test_diff',
4001
'bzrlib.tests.test_directory_service',
4002
'bzrlib.tests.test_dirstate',
4003
'bzrlib.tests.test_email_message',
4004
'bzrlib.tests.test_eol_filters',
4005
'bzrlib.tests.test_errors',
4006
'bzrlib.tests.test_estimate_compressed_size',
4007
'bzrlib.tests.test_export',
4008
'bzrlib.tests.test_export_pot',
4009
'bzrlib.tests.test_extract',
4010
'bzrlib.tests.test_features',
4011
'bzrlib.tests.test_fetch',
4012
'bzrlib.tests.test_fixtures',
4013
'bzrlib.tests.test_fifo_cache',
4014
'bzrlib.tests.test_filters',
4015
'bzrlib.tests.test_filter_tree',
4016
'bzrlib.tests.test_ftp_transport',
4017
'bzrlib.tests.test_foreign',
4018
'bzrlib.tests.test_generate_docs',
4019
'bzrlib.tests.test_generate_ids',
4020
'bzrlib.tests.test_globbing',
4021
'bzrlib.tests.test_gpg',
4022
'bzrlib.tests.test_graph',
4023
'bzrlib.tests.test_groupcompress',
4024
'bzrlib.tests.test_hashcache',
4025
'bzrlib.tests.test_help',
4026
'bzrlib.tests.test_hooks',
4027
'bzrlib.tests.test_http',
4028
'bzrlib.tests.test_http_response',
4029
'bzrlib.tests.test_https_ca_bundle',
4030
'bzrlib.tests.test_https_urllib',
4031
'bzrlib.tests.test_i18n',
4032
'bzrlib.tests.test_identitymap',
4033
'bzrlib.tests.test_ignores',
4034
'bzrlib.tests.test_index',
4035
'bzrlib.tests.test_import_tariff',
4036
'bzrlib.tests.test_info',
4037
'bzrlib.tests.test_inv',
4038
'bzrlib.tests.test_inventory_delta',
4039
'bzrlib.tests.test_knit',
4040
'bzrlib.tests.test_lazy_import',
4041
'bzrlib.tests.test_lazy_regex',
4042
'bzrlib.tests.test_library_state',
4043
'bzrlib.tests.test_lock',
4044
'bzrlib.tests.test_lockable_files',
4045
'bzrlib.tests.test_lockdir',
4046
'bzrlib.tests.test_log',
4047
'bzrlib.tests.test_lru_cache',
4048
'bzrlib.tests.test_lsprof',
4049
'bzrlib.tests.test_mail_client',
4050
'bzrlib.tests.test_matchers',
4051
'bzrlib.tests.test_memorytree',
4052
'bzrlib.tests.test_merge',
4053
'bzrlib.tests.test_merge3',
4054
'bzrlib.tests.test_merge_core',
4055
'bzrlib.tests.test_merge_directive',
4056
'bzrlib.tests.test_mergetools',
4057
'bzrlib.tests.test_missing',
4058
'bzrlib.tests.test_msgeditor',
4059
'bzrlib.tests.test_multiparent',
4060
'bzrlib.tests.test_mutabletree',
4061
'bzrlib.tests.test_nonascii',
4062
'bzrlib.tests.test_options',
4063
'bzrlib.tests.test_osutils',
4064
'bzrlib.tests.test_osutils_encodings',
4065
'bzrlib.tests.test_pack',
4066
'bzrlib.tests.test_patch',
4067
'bzrlib.tests.test_patches',
4068
'bzrlib.tests.test_permissions',
4069
'bzrlib.tests.test_plugins',
4070
'bzrlib.tests.test_progress',
4071
'bzrlib.tests.test_pyutils',
4072
'bzrlib.tests.test_read_bundle',
4073
'bzrlib.tests.test_reconcile',
4074
'bzrlib.tests.test_reconfigure',
4075
'bzrlib.tests.test_registry',
4076
'bzrlib.tests.test_remote',
4077
'bzrlib.tests.test_rename_map',
4078
'bzrlib.tests.test_repository',
4079
'bzrlib.tests.test_revert',
4080
'bzrlib.tests.test_revision',
4081
'bzrlib.tests.test_revisionspec',
4082
'bzrlib.tests.test_revisiontree',
4083
'bzrlib.tests.test_rio',
4084
'bzrlib.tests.test_rules',
4085
'bzrlib.tests.test_url_policy_open',
4086
'bzrlib.tests.test_sampler',
4087
'bzrlib.tests.test_scenarios',
4088
'bzrlib.tests.test_script',
4089
'bzrlib.tests.test_selftest',
4090
'bzrlib.tests.test_serializer',
4091
'bzrlib.tests.test_setup',
4092
'bzrlib.tests.test_sftp_transport',
4093
'bzrlib.tests.test_shelf',
4094
'bzrlib.tests.test_shelf_ui',
4095
'bzrlib.tests.test_smart',
4096
'bzrlib.tests.test_smart_add',
4097
'bzrlib.tests.test_smart_request',
4098
'bzrlib.tests.test_smart_signals',
4099
'bzrlib.tests.test_smart_transport',
4100
'bzrlib.tests.test_smtp_connection',
4101
'bzrlib.tests.test_source',
4102
'bzrlib.tests.test_ssh_transport',
4103
'bzrlib.tests.test_status',
4104
'bzrlib.tests.test_store',
4105
'bzrlib.tests.test_strace',
4106
'bzrlib.tests.test_subsume',
4107
'bzrlib.tests.test_switch',
4108
'bzrlib.tests.test_symbol_versioning',
4109
'bzrlib.tests.test_tag',
4110
'bzrlib.tests.test_test_server',
4111
'bzrlib.tests.test_testament',
4112
'bzrlib.tests.test_textfile',
4113
'bzrlib.tests.test_textmerge',
4114
'bzrlib.tests.test_cethread',
4115
'bzrlib.tests.test_timestamp',
4116
'bzrlib.tests.test_trace',
4117
'bzrlib.tests.test_transactions',
4118
'bzrlib.tests.test_transform',
4119
'bzrlib.tests.test_transport',
4120
'bzrlib.tests.test_transport_log',
4121
'bzrlib.tests.test_tree',
4122
'bzrlib.tests.test_treebuilder',
4123
'bzrlib.tests.test_treeshape',
4124
'bzrlib.tests.test_tsort',
4125
'bzrlib.tests.test_tuned_gzip',
4126
'bzrlib.tests.test_ui',
4127
'bzrlib.tests.test_uncommit',
4128
'bzrlib.tests.test_upgrade',
4129
'bzrlib.tests.test_upgrade_stacked',
4130
'bzrlib.tests.test_urlutils',
4131
'bzrlib.tests.test_utextwrap',
4132
'bzrlib.tests.test_version',
4133
'bzrlib.tests.test_version_info',
4134
'bzrlib.tests.test_versionedfile',
4135
'bzrlib.tests.test_vf_search',
4136
'bzrlib.tests.test_weave',
4137
'bzrlib.tests.test_whitebox',
4138
'bzrlib.tests.test_win32utils',
4139
'bzrlib.tests.test_workingtree',
4140
'bzrlib.tests.test_workingtree_4',
4141
'bzrlib.tests.test_wsgi',
4142
'bzrlib.tests.test_xml',
4146
def _test_suite_modules_to_doctest():
4147
"""Return the list of modules to doctest."""
4149
# GZ 2009-03-31: No docstrings with -OO so there's nothing to doctest
4153
'bzrlib.branchbuilder',
4154
'bzrlib.decorators',
4156
'bzrlib.iterablefile',
4161
'bzrlib.symbol_versioning',
4163
'bzrlib.tests.fixtures',
4165
'bzrlib.transport.http',
4166
'bzrlib.version_info_formats.format_custom',
4170
def test_suite(keep_only=None, starting_with=None):
4171
2373
"""Build and return TestSuite for the whole of bzrlib.
4173
:param keep_only: A list of test ids limiting the suite returned.
4175
:param starting_with: An id limiting the suite returned to the tests
4178
2375
This function can be replaced if you need to change the default test
4179
2376
suite on a global basis, but it is not encouraged.
2379
'bzrlib.util.tests.test_bencode',
2380
'bzrlib.tests.test__dirstate_helpers',
2381
'bzrlib.tests.test_ancestry',
2382
'bzrlib.tests.test_annotate',
2383
'bzrlib.tests.test_api',
2384
'bzrlib.tests.test_atomicfile',
2385
'bzrlib.tests.test_bad_files',
2386
'bzrlib.tests.test_bisect_multi',
2387
'bzrlib.tests.test_branch',
2388
'bzrlib.tests.test_branchbuilder',
2389
'bzrlib.tests.test_bugtracker',
2390
'bzrlib.tests.test_bundle',
2391
'bzrlib.tests.test_bzrdir',
2392
'bzrlib.tests.test_cache_utf8',
2393
'bzrlib.tests.test_commands',
2394
'bzrlib.tests.test_commit',
2395
'bzrlib.tests.test_commit_merge',
2396
'bzrlib.tests.test_config',
2397
'bzrlib.tests.test_conflicts',
2398
'bzrlib.tests.test_counted_lock',
2399
'bzrlib.tests.test_decorators',
2400
'bzrlib.tests.test_delta',
2401
'bzrlib.tests.test_deprecated_graph',
2402
'bzrlib.tests.test_diff',
2403
'bzrlib.tests.test_dirstate',
2404
'bzrlib.tests.test_email_message',
2405
'bzrlib.tests.test_errors',
2406
'bzrlib.tests.test_escaped_store',
2407
'bzrlib.tests.test_extract',
2408
'bzrlib.tests.test_fetch',
2409
'bzrlib.tests.test_ftp_transport',
2410
'bzrlib.tests.test_generate_docs',
2411
'bzrlib.tests.test_generate_ids',
2412
'bzrlib.tests.test_globbing',
2413
'bzrlib.tests.test_gpg',
2414
'bzrlib.tests.test_graph',
2415
'bzrlib.tests.test_hashcache',
2416
'bzrlib.tests.test_help',
2417
'bzrlib.tests.test_hooks',
2418
'bzrlib.tests.test_http',
2419
'bzrlib.tests.test_http_response',
2420
'bzrlib.tests.test_https_ca_bundle',
2421
'bzrlib.tests.test_identitymap',
2422
'bzrlib.tests.test_ignores',
2423
'bzrlib.tests.test_index',
2424
'bzrlib.tests.test_info',
2425
'bzrlib.tests.test_inv',
2426
'bzrlib.tests.test_knit',
2427
'bzrlib.tests.test_lazy_import',
2428
'bzrlib.tests.test_lazy_regex',
2429
'bzrlib.tests.test_lockdir',
2430
'bzrlib.tests.test_lockable_files',
2431
'bzrlib.tests.test_log',
2432
'bzrlib.tests.test_lsprof',
2433
'bzrlib.tests.test_lru_cache',
2434
'bzrlib.tests.test_mail_client',
2435
'bzrlib.tests.test_memorytree',
2436
'bzrlib.tests.test_merge',
2437
'bzrlib.tests.test_merge3',
2438
'bzrlib.tests.test_merge_core',
2439
'bzrlib.tests.test_merge_directive',
2440
'bzrlib.tests.test_missing',
2441
'bzrlib.tests.test_msgeditor',
2442
'bzrlib.tests.test_multiparent',
2443
'bzrlib.tests.test_nonascii',
2444
'bzrlib.tests.test_options',
2445
'bzrlib.tests.test_osutils',
2446
'bzrlib.tests.test_osutils_encodings',
2447
'bzrlib.tests.test_pack',
2448
'bzrlib.tests.test_patch',
2449
'bzrlib.tests.test_patches',
2450
'bzrlib.tests.test_permissions',
2451
'bzrlib.tests.test_plugins',
2452
'bzrlib.tests.test_progress',
2453
'bzrlib.tests.test_reconfigure',
2454
'bzrlib.tests.test_reconcile',
2455
'bzrlib.tests.test_registry',
2456
'bzrlib.tests.test_remote',
2457
'bzrlib.tests.test_repository',
2458
'bzrlib.tests.test_revert',
2459
'bzrlib.tests.test_revision',
2460
'bzrlib.tests.test_revisionnamespaces',
2461
'bzrlib.tests.test_revisiontree',
2462
'bzrlib.tests.test_rio',
2463
'bzrlib.tests.test_sampler',
2464
'bzrlib.tests.test_selftest',
2465
'bzrlib.tests.test_setup',
2466
'bzrlib.tests.test_sftp_transport',
2467
'bzrlib.tests.test_smart',
2468
'bzrlib.tests.test_smart_add',
2469
'bzrlib.tests.test_smart_transport',
2470
'bzrlib.tests.test_smtp_connection',
2471
'bzrlib.tests.test_source',
2472
'bzrlib.tests.test_ssh_transport',
2473
'bzrlib.tests.test_status',
2474
'bzrlib.tests.test_store',
2475
'bzrlib.tests.test_strace',
2476
'bzrlib.tests.test_subsume',
2477
'bzrlib.tests.test_switch',
2478
'bzrlib.tests.test_symbol_versioning',
2479
'bzrlib.tests.test_tag',
2480
'bzrlib.tests.test_testament',
2481
'bzrlib.tests.test_textfile',
2482
'bzrlib.tests.test_textmerge',
2483
'bzrlib.tests.test_timestamp',
2484
'bzrlib.tests.test_trace',
2485
'bzrlib.tests.test_transactions',
2486
'bzrlib.tests.test_transform',
2487
'bzrlib.tests.test_transport',
2488
'bzrlib.tests.test_tree',
2489
'bzrlib.tests.test_treebuilder',
2490
'bzrlib.tests.test_tsort',
2491
'bzrlib.tests.test_tuned_gzip',
2492
'bzrlib.tests.test_ui',
2493
'bzrlib.tests.test_upgrade',
2494
'bzrlib.tests.test_urlutils',
2495
'bzrlib.tests.test_versionedfile',
2496
'bzrlib.tests.test_version',
2497
'bzrlib.tests.test_version_info',
2498
'bzrlib.tests.test_weave',
2499
'bzrlib.tests.test_whitebox',
2500
'bzrlib.tests.test_win32utils',
2501
'bzrlib.tests.test_workingtree',
2502
'bzrlib.tests.test_workingtree_4',
2503
'bzrlib.tests.test_wsgi',
2504
'bzrlib.tests.test_xml',
2506
test_transport_implementations = [
2507
'bzrlib.tests.test_transport_implementations',
2508
'bzrlib.tests.test_read_bundle',
2510
suite = TestUtil.TestSuite()
4182
2511
loader = TestUtil.TestLoader()
4184
if keep_only is not None:
4185
id_filter = TestIdList(keep_only)
4187
# We take precedence over keep_only because *at loading time* using
4188
# both options means we will load less tests for the same final result.
4189
def interesting_module(name):
4190
for start in starting_with:
4192
# Either the module name starts with the specified string
4193
name.startswith(start)
4194
# or it may contain tests starting with the specified string
4195
or start.startswith(name)
4199
loader = TestUtil.FilteredByModuleTestLoader(interesting_module)
4201
elif keep_only is not None:
4202
loader = TestUtil.FilteredByModuleTestLoader(id_filter.refers_to)
4203
def interesting_module(name):
4204
return id_filter.refers_to(name)
4207
loader = TestUtil.TestLoader()
4208
def interesting_module(name):
4209
# No filtering, all modules are interesting
4212
suite = loader.suiteClass()
4214
# modules building their suite with loadTestsFromModuleNames
4215
suite.addTest(loader.loadTestsFromModuleNames(_test_suite_testmod_names()))
4217
for mod in _test_suite_modules_to_doctest():
4218
if not interesting_module(mod):
4219
# No tests to keep here, move along
2512
suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
2513
from bzrlib.tests.test_transport_implementations import TransportTestProviderAdapter
2514
adapter = TransportTestProviderAdapter()
2515
adapt_modules(test_transport_implementations, adapter, loader, suite)
2517
["bzrlib.tests.test_msgeditor.MsgEditorTest."
2518
"test__create_temp_file_with_commit_template_in_unicode_dir"],
2519
EncodingTestAdapter(), loader, suite)
2520
for package in packages_to_test():
2521
suite.addTest(package.test_suite())
2522
for m in MODULES_TO_TEST:
2523
suite.addTest(loader.loadTestsFromModule(m))
2524
for m in MODULES_TO_DOCTEST:
4222
# note that this really does mean "report only" -- doctest
4223
# still runs the rest of the examples
4224
doc_suite = IsolatedDocTestSuite(
4225
mod, optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)
2526
suite.addTest(doctest.DocTestSuite(m))
4226
2527
except ValueError, e:
4227
print '**failed to get doctest for: %s\n%s' % (mod, e)
2528
print '**failed to get doctest for: %s\n%s' %(m,e)
4229
if len(doc_suite._tests) == 0:
4230
raise errors.BzrError("no doctests found in %s" % (mod,))
4231
suite.addTest(doc_suite)
4233
2530
default_encoding = sys.getdefaultencoding()
4234
for name, plugin in _mod_plugin.plugins().items():
4235
if not interesting_module(plugin.module.__name__):
4237
plugin_suite = plugin.test_suite()
4238
# We used to catch ImportError here and turn it into just a warning,
4239
# but really if you don't have --no-plugins this should be a failure.
4240
# mbp 20080213 - see http://bugs.launchpad.net/bugs/189771
4241
if plugin_suite is None:
4242
plugin_suite = plugin.load_plugin_tests(loader)
4243
if plugin_suite is not None:
4244
suite.addTest(plugin_suite)
2531
for name, plugin in bzrlib.plugin.plugins().items():
2533
plugin_suite = plugin.test_suite()
2534
except ImportError, e:
2535
bzrlib.trace.warning(
2536
'Unable to test plugin "%s": %s', name, e)
2538
if plugin_suite is not None:
2539
suite.addTest(plugin_suite)
4245
2540
if default_encoding != sys.getdefaultencoding():
2541
bzrlib.trace.warning(
4247
2542
'Plugin "%s" tried to reset default encoding to: %s', name,
4248
2543
sys.getdefaultencoding())
4250
2545
sys.setdefaultencoding(default_encoding)
4252
if keep_only is not None:
4253
# Now that the referred modules have loaded their tests, keep only the
4255
suite = filter_suite_by_id_list(suite, id_filter)
4256
# Do some sanity checks on the id_list filtering
4257
not_found, duplicates = suite_matches_id_list(suite, keep_only)
4259
# The tester has used both keep_only and starting_with, so he is
4260
# already aware that some tests are excluded from the list, there
4261
# is no need to tell him which.
4264
# Some tests mentioned in the list are not in the test suite. The
4265
# list may be out of date, report to the tester.
4266
for id in not_found:
4267
trace.warning('"%s" not found in the test suite', id)
4268
for id in duplicates:
4269
trace.warning('"%s" is used as an id by several tests', id)
4274
def multiply_scenarios(*scenarios):
4275
"""Multiply two or more iterables of scenarios.
4277
It is safe to pass scenario generators or iterators.
4279
:returns: A list of compound scenarios: the cross-product of all
4280
scenarios, with the names concatenated and the parameters
2549
def multiply_tests_from_modules(module_name_list, scenario_iter):
2550
"""Adapt all tests in some given modules to given scenarios.
2552
This is the recommended public interface for test parameterization.
2553
Typically the test_suite() method for a per-implementation test
2554
suite will call multiply_tests_from_modules and return the
2557
:param module_name_list: List of fully-qualified names of test
2559
:param scenario_iter: Iterable of pairs of (scenario_name,
2560
scenario_param_dict).
2562
This returns a new TestSuite containing the cross product of
2563
all the tests in all the modules, each repeated for each scenario.
2564
Each test is adapted by adding the scenario name at the end
2565
of its name, and updating the test object's __dict__ with the
2566
scenario_param_dict.
2568
>>> r = multiply_tests_from_modules(
2569
... ['bzrlib.tests.test_sampler'],
2570
... [('one', dict(param=1)),
2571
... ('two', dict(param=2))])
2572
>>> tests = list(iter_suite_tests(r))
2576
'bzrlib.tests.test_sampler.DemoTest.test_nothing(one)'
4283
return reduce(_multiply_two_scenarios, map(list, scenarios))
4286
def _multiply_two_scenarios(scenarios_left, scenarios_right):
2582
loader = TestLoader()
2584
adapter = TestScenarioApplier()
2585
adapter.scenarios = list(scenario_iter)
2586
adapt_modules(module_name_list, adapter, loader, suite)
2590
def multiply_scenarios(scenarios_left, scenarios_right):
4287
2591
"""Multiply two sets of scenarios.
4289
2593
:returns: the cartesian product of the two sets of scenarios, that is