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 (
97
81
deprecated_function,
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
89
from bzrlib.transport import get_transport
90
import bzrlib.transport
91
from bzrlib.transport.local import LocalURLServer
92
from bzrlib.transport.memory import MemoryServer
93
from bzrlib.transport.readonly import ReadonlyServer
94
from bzrlib.trace import mutter, note
95
from bzrlib.tests import TestUtil
96
from bzrlib.tests.http_server import HttpServer
97
from bzrlib.tests.TestUtil import (
101
from bzrlib.tests.treeshape import build_tree_contents
102
import bzrlib.version_info_formats.format_custom
103
from bzrlib.workingtree import WorkingTree, WorkingTreeFormat2
110
105
# Mark this python module as being part of the implementation
111
106
# of unittest: this gives us better tracebacks where the last
112
107
# 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):
110
default_transport = LocalURLServer
113
MODULES_TO_DOCTEST = [
124
bzrlib.version_info_formats.format_custom,
125
# quoted to avoid module-loading circularity
130
def packages_to_test():
131
"""Return a list of packages to test.
133
The packages are not globally imported so that import failures are
134
triggered when running selftest, not when importing the command.
137
import bzrlib.tests.blackbox
138
import bzrlib.tests.branch_implementations
139
import bzrlib.tests.bzrdir_implementations
140
import bzrlib.tests.commands
141
import bzrlib.tests.interrepository_implementations
142
import bzrlib.tests.interversionedfile_implementations
143
import bzrlib.tests.intertree_implementations
144
import bzrlib.tests.inventory_implementations
145
import bzrlib.tests.per_lock
146
import bzrlib.tests.repository_implementations
147
import bzrlib.tests.revisionstore_implementations
148
import bzrlib.tests.tree_implementations
149
import bzrlib.tests.workingtree_implementations
152
bzrlib.tests.blackbox,
153
bzrlib.tests.branch_implementations,
154
bzrlib.tests.bzrdir_implementations,
155
bzrlib.tests.commands,
156
bzrlib.tests.interrepository_implementations,
157
bzrlib.tests.interversionedfile_implementations,
158
bzrlib.tests.intertree_implementations,
159
bzrlib.tests.inventory_implementations,
160
bzrlib.tests.per_lock,
161
bzrlib.tests.repository_implementations,
162
bzrlib.tests.revisionstore_implementations,
163
bzrlib.tests.tree_implementations,
164
bzrlib.tests.workingtree_implementations,
168
class ExtendedTestResult(unittest._TextTestResult):
244
169
"""Accepts, reports and accumulates the results of running tests.
246
171
Compared to the unittest version this class adds support for
468
289
Called from the TestCase run() method when the test
469
290
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)
292
self._testConcluded(test)
293
if isinstance(err[1], KnownFailure):
294
return self._addKnownFailure(test, err)
296
self._cleanupLogFile(test)
297
unittest.TestResult.addFailure(self, test, err)
298
self.failure_count += 1
299
self.report_failure(test, err)
478
def addSuccess(self, test, details=None):
303
def addSuccess(self, test):
479
304
"""Tell result that test completed successfully.
481
306
Called from the TestCase run()
308
self._testConcluded(test)
483
309
if self._bench_history is not None:
484
benchmark_time = self._extractBenchmarkTime(test, details)
310
benchmark_time = self._extractBenchmarkTime(test)
485
311
if benchmark_time is not None:
486
312
self._bench_history.write("%s %s\n" % (
487
313
self._formatTime(benchmark_time),
489
315
self.report_success(test)
490
super(ExtendedTestResult, self).addSuccess(test)
491
test._log_contents = ''
493
def addExpectedFailure(self, test, err):
316
self._cleanupLogFile(test)
317
unittest.TestResult.addSuccess(self, test)
319
def _testConcluded(self, test):
320
"""Common code when a test has finished.
322
Called regardless of whether it succeded, failed, etc.
326
def _addKnownFailure(self, test, err):
494
327
self.known_failure_count += 1
495
328
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
330
def addNotSupported(self, test, feature):
511
331
"""The test will not be run because of a missing feature.
513
333
# this can be called in two different ways: it may be that the
514
# test started running, and then raised (through requireFeature)
334
# test started running, and then raised (through addError)
515
335
# 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.
336
# while probing for features before running the tests; in that
337
# case we will see startTest and stopTest, but the test will never
519
339
self.unsupported.setdefault(str(feature), 0)
520
340
self.unsupported[str(feature)] += 1
521
341
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()
343
def _addSkipped(self, test, skip_excinfo):
344
if isinstance(skip_excinfo[1], TestNotApplicable):
345
self.not_applicable_count += 1
346
self.report_not_applicable(test, skip_excinfo)
349
self.report_skip(test, skip_excinfo)
352
except KeyboardInterrupt:
355
self.addError(test, test._exc_info())
357
# seems best to treat this as success from point-of-view of unittest
358
# -- it actually does nothing so it barely matters :)
359
unittest.TestResult.addSuccess(self, test)
361
def printErrorList(self, flavour, errors):
362
for test, err in errors:
363
self.stream.writeln(self.separator1)
364
self.stream.write("%s: " % flavour)
365
self.stream.writeln(self.getDescription(test))
366
if getattr(test, '_get_log', None) is not None:
367
self.stream.write('\n')
369
('vvvv[log from %s]' % test.id()).ljust(78,'-'))
370
self.stream.write('\n')
371
self.stream.write(test._get_log())
372
self.stream.write('\n')
374
('^^^^[log from %s]' % test.id()).ljust(78,'-'))
375
self.stream.write('\n')
376
self.stream.writeln(self.separator2)
377
self.stream.writeln("%s" % err)
382
def report_cleaning_up(self):
586
385
def report_success(self, test):
986
775
retrieved by _get_log(). We use a real OS file, not an in-memory object,
987
776
so that it can also capture file IO. When the test completes this file
988
777
is read into memory and removed from disk.
990
779
There are also convenience functions to invoke bzr's command-line
991
780
routine, and to build and check bzr trees.
993
782
In addition to the usual method of overriding tearDown(), this class also
994
allows subclasses to register cleanup functions via addCleanup, which are
783
allows subclasses to register functions into the _cleanups list, which is
995
784
run in order as the object is torn down. It's less likely this will be
996
785
accidentally overlooked.
788
_log_file_name = None
790
_keep_log_file = False
1000
791
# record lsprof data when performing benchmark calls.
1001
792
_gather_lsprof_in_benchmarks = False
1003
794
def __init__(self, methodName='testMethod'):
1004
795
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
798
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)
799
unittest.TestCase.setUp(self)
1024
800
self._cleanEnvironment()
1026
if bzrlib.global_state is not None:
1027
self.overrideAttr(bzrlib.global_state, 'cmdline_overrides',
1028
config.CommandLineStore())
1030
801
self._silenceUI()
1031
802
self._startLogFile()
1032
803
self._benchcalls = []
1033
804
self._benchtime = None
1034
805
self._clear_hooks()
1035
self._track_transports()
1037
806
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
808
def _clear_debug_flags(self):
1120
809
"""Prevent externally set debug flags affecting tests.
1122
811
Tests that want to use debug flags can just set them in the
1123
812
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')
814
self._preserved_debug_flags = set(debug.debug_flags)
815
debug.debug_flags.clear()
816
self.addCleanup(self._restore_debug_flags)
1132
818
def _clear_hooks(self):
1133
819
# 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 = {}
821
import bzrlib.smart.server
822
self._preserved_hooks = {
823
bzrlib.branch.Branch: bzrlib.branch.Branch.hooks,
824
bzrlib.smart.server.SmartTCPServer: bzrlib.smart.server.SmartTCPServer.hooks,
1141
826
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
827
# reset all hooks to an empty instance of the appropriate type
828
bzrlib.branch.Branch.hooks = bzrlib.branch.BranchHooks()
829
bzrlib.smart.server.SmartTCPServer.hooks = bzrlib.smart.server.SmartServerHooks()
1156
831
def _silenceUI(self):
1157
832
"""Turn off UI for duration of test"""
1158
833
# 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.")
834
saved = ui.ui_factory
836
ui.ui_factory = saved
837
ui.ui_factory = ui.SilentUIFactory()
838
self.addCleanup(_restore)
1343
840
def _ndiff_strings(self, a, b):
1344
841
"""Return ndiff between two strings containing lines.
1346
843
A trailing newline is added if missing to make the strings
1347
844
print properly."""
1348
845
if b and b[-1] != '\n':
1745
1181
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)
1182
"""Send bzr and test log messages to a temporary file.
1184
The file is removed as the test is torn down.
1186
fileno, name = tempfile.mkstemp(suffix='.log', prefix='testbzr')
1187
self._log_file = os.fdopen(fileno, 'w+')
1188
self._log_memento = bzrlib.trace.push_log_file(self._log_file)
1189
self._log_file_name = name
1756
1190
self.addCleanup(self._finishLogFile)
1758
1192
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)
1193
"""Finished with the log file.
1195
Close the file and delete it, unless setKeepLogfile was called.
1197
if self._log_file is None:
1199
bzrlib.trace.pop_log_file(self._log_memento)
1200
self._log_file.close()
1201
self._log_file = None
1202
if not self._keep_log_file:
1203
os.remove(self._log_file_name)
1204
self._log_file_name = None
1206
def setKeepLogfile(self):
1207
"""Make the logfile not be deleted when _finishLogFile is called."""
1208
self._keep_log_file = True
1210
def addCleanup(self, callable):
1211
"""Arrange to run a callable when this case is torn down.
1213
Callables are run in the reverse of the order they are registered,
1214
ie last-in first-out.
1216
if callable in self._cleanups:
1217
raise ValueError("cleanup function %r already registered on %s"
1219
self._cleanups.append(callable)
1842
1221
def _cleanEnvironment(self):
1843
for name, value in isolated_environ.iteritems():
1844
self.overrideEnv(name, value)
1223
'BZR_HOME': None, # Don't inherit BZR_HOME to all the tests.
1224
'HOME': os.getcwd(),
1225
'APPDATA': None, # bzr now use Win32 API and don't rely on APPDATA
1226
'BZR_EDITOR': None, # test_msgeditor manipulates this variable
1228
'BZREMAIL': None, # may still be present in the environment
1230
'BZR_PROGRESS_BAR': None,
1233
'SSH_AUTH_SOCK': None,
1237
'https_proxy': None,
1238
'HTTPS_PROXY': None,
1243
# Nobody cares about these ones AFAIK. So far at
1244
# least. If you do (care), please update this comment
1248
'BZR_REMOTE_PATH': None,
1251
self.addCleanup(self._restoreEnvironment)
1252
for name, value in new_env.iteritems():
1253
self._captureVar(name, value)
1255
def _captureVar(self, name, newvalue):
1256
"""Set an environment variable, and reset it when finished."""
1257
self.__old_env[name] = osutils.set_or_unset_env(name, newvalue)
1259
def _restore_debug_flags(self):
1260
debug.debug_flags.clear()
1261
debug.debug_flags.update(self._preserved_debug_flags)
1263
def _restoreEnvironment(self):
1264
for name, value in self.__old_env.iteritems():
1265
osutils.set_or_unset_env(name, value)
1846
1267
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()
1268
for klass, hooks in self._preserved_hooks.items():
1269
setattr(klass, 'hooks', hooks)
1853
1271
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)
1272
"""This test has failed for some known reason."""
1273
raise KnownFailure(reason)
1275
def run(self, result=None):
1276
if result is None: result = self.defaultTestResult()
1277
for feature in getattr(self, '_test_needs_features', []):
1278
if not feature.available():
1279
result.startTest(self)
1280
if getattr(result, 'addNotSupported', None):
1281
result.addNotSupported(self, feature)
1283
result.addSuccess(self)
1284
result.stopTest(self)
1286
return unittest.TestCase.run(self, result)
1290
unittest.TestCase.tearDown(self)
1945
1292
def time(self, callable, *args, **kwargs):
1946
1293
"""Run callable and accrue the time it takes to the benchmark time.
1948
1295
If lsprofiling is enabled (i.e. by --lsprof-time to bzr selftest) then
1949
1296
this will cause lsprofile statistics to be gathered and stored in
1950
1297
self._benchcalls.
1952
1299
if self._benchtime is None:
1953
self.addDetail('benchtime', content.Content(content.ContentType(
1954
"text", "plain"), lambda:[str(self._benchtime)]))
1955
1300
self._benchtime = 0
1956
1301
start = time.time()
3289
2453
list_only=False,
3290
2454
random_seed=None,
3291
2455
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
2457
TestCase._gather_lsprof_in_benchmarks = lsprof_timed
3310
if runner_class is None:
3311
runner_class = TextTestRunner
3314
runner = runner_class(stream=stream,
2462
runner = TextTestRunner(stream=sys.stdout,
3315
2463
descriptions=0,
3316
2464
verbosity=verbosity,
3317
2465
bench_history=bench_history,
3319
result_decorators=result_decorators,
2466
list_only=list_only,
3321
2468
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))
2469
# Initialise the random number generator and display the seed used.
2470
# We convert the seed to a long to make it reuseable across invocations.
2471
random_order = False
2472
if random_seed is not None:
2474
if random_seed == "now":
2475
random_seed = long(time.time())
2477
# Convert the seed to a long if we can
2479
random_seed = long(random_seed)
2482
runner.stream.writeln("Randomizing test order using seed %s\n" %
2484
random.seed(random_seed)
2485
# Customise the list of tests if requested
2486
if exclude_pattern is not None:
2487
suite = exclude_tests_by_re(suite, exclude_pattern)
2489
order_changer = randomize_suite
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()))
2491
order_changer = preserve_input
2492
if pattern != '.*' or random_order:
2493
if matching_tests_first:
2494
suites = map(order_changer, split_suite_by_re(suite, pattern))
2495
suite = TestUtil.TestSuite(suites)
2497
suite = order_changer(filter_suite_by_re(suite, pattern))
3351
2499
result = runner.run(suite)
3353
2502
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()
2504
return result.wasSuccessful()
3701
2507
def selftest(verbose=False, pattern=".*", stop_on_failure=True,
3866
2610
modules[mod_name] = True
3867
2611
self.modules = modules
3869
def refers_to(self, module_name):
2613
def is_module_name_used(self, module_name):
3870
2614
"""Is there tests for the module or one of its sub modules."""
3871
2615
return self.modules.has_key(module_name)
3873
def includes(self, test_id):
2617
def test_in(self, test_id):
3874
2618
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):
2621
def test_suite(keep_only=None):
4171
2622
"""Build and return TestSuite for the whole of bzrlib.
4173
2624
: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
2626
This function can be replaced if you need to change the default test
4179
2627
suite on a global basis, but it is not encouraged.
2630
'bzrlib.util.tests.test_bencode',
2631
'bzrlib.tests.test__dirstate_helpers',
2632
'bzrlib.tests.test_ancestry',
2633
'bzrlib.tests.test_annotate',
2634
'bzrlib.tests.test_api',
2635
'bzrlib.tests.test_atomicfile',
2636
'bzrlib.tests.test_bad_files',
2637
'bzrlib.tests.test_bisect_multi',
2638
'bzrlib.tests.test_branch',
2639
'bzrlib.tests.test_branchbuilder',
2640
'bzrlib.tests.test_bugtracker',
2641
'bzrlib.tests.test_bundle',
2642
'bzrlib.tests.test_bzrdir',
2643
'bzrlib.tests.test_cache_utf8',
2644
'bzrlib.tests.test_commands',
2645
'bzrlib.tests.test_commit',
2646
'bzrlib.tests.test_commit_merge',
2647
'bzrlib.tests.test_config',
2648
'bzrlib.tests.test_conflicts',
2649
'bzrlib.tests.test_counted_lock',
2650
'bzrlib.tests.test_decorators',
2651
'bzrlib.tests.test_delta',
2652
'bzrlib.tests.test_deprecated_graph',
2653
'bzrlib.tests.test_diff',
2654
'bzrlib.tests.test_dirstate',
2655
'bzrlib.tests.test_directory_service',
2656
'bzrlib.tests.test_email_message',
2657
'bzrlib.tests.test_errors',
2658
'bzrlib.tests.test_escaped_store',
2659
'bzrlib.tests.test_extract',
2660
'bzrlib.tests.test_fetch',
2661
'bzrlib.tests.test_ftp_transport',
2662
'bzrlib.tests.test_generate_docs',
2663
'bzrlib.tests.test_generate_ids',
2664
'bzrlib.tests.test_globbing',
2665
'bzrlib.tests.test_gpg',
2666
'bzrlib.tests.test_graph',
2667
'bzrlib.tests.test_hashcache',
2668
'bzrlib.tests.test_help',
2669
'bzrlib.tests.test_hooks',
2670
'bzrlib.tests.test_http',
2671
'bzrlib.tests.test_http_implementations',
2672
'bzrlib.tests.test_http_response',
2673
'bzrlib.tests.test_https_ca_bundle',
2674
'bzrlib.tests.test_identitymap',
2675
'bzrlib.tests.test_ignores',
2676
'bzrlib.tests.test_index',
2677
'bzrlib.tests.test_info',
2678
'bzrlib.tests.test_inv',
2679
'bzrlib.tests.test_knit',
2680
'bzrlib.tests.test_lazy_import',
2681
'bzrlib.tests.test_lazy_regex',
2682
'bzrlib.tests.test_lockdir',
2683
'bzrlib.tests.test_lockable_files',
2684
'bzrlib.tests.test_log',
2685
'bzrlib.tests.test_lsprof',
2686
'bzrlib.tests.test_lru_cache',
2687
'bzrlib.tests.test_mail_client',
2688
'bzrlib.tests.test_memorytree',
2689
'bzrlib.tests.test_merge',
2690
'bzrlib.tests.test_merge3',
2691
'bzrlib.tests.test_merge_core',
2692
'bzrlib.tests.test_merge_directive',
2693
'bzrlib.tests.test_missing',
2694
'bzrlib.tests.test_msgeditor',
2695
'bzrlib.tests.test_multiparent',
2696
'bzrlib.tests.test_nonascii',
2697
'bzrlib.tests.test_options',
2698
'bzrlib.tests.test_osutils',
2699
'bzrlib.tests.test_osutils_encodings',
2700
'bzrlib.tests.test_pack',
2701
'bzrlib.tests.test_patch',
2702
'bzrlib.tests.test_patches',
2703
'bzrlib.tests.test_permissions',
2704
'bzrlib.tests.test_plugins',
2705
'bzrlib.tests.test_progress',
2706
'bzrlib.tests.test_reconfigure',
2707
'bzrlib.tests.test_reconcile',
2708
'bzrlib.tests.test_registry',
2709
'bzrlib.tests.test_remote',
2710
'bzrlib.tests.test_repository',
2711
'bzrlib.tests.test_revert',
2712
'bzrlib.tests.test_revision',
2713
'bzrlib.tests.test_revisionnamespaces',
2714
'bzrlib.tests.test_revisiontree',
2715
'bzrlib.tests.test_rio',
2716
'bzrlib.tests.test_sampler',
2717
'bzrlib.tests.test_selftest',
2718
'bzrlib.tests.test_setup',
2719
'bzrlib.tests.test_sftp_transport',
2720
'bzrlib.tests.test_smart',
2721
'bzrlib.tests.test_smart_add',
2722
'bzrlib.tests.test_smart_transport',
2723
'bzrlib.tests.test_smtp_connection',
2724
'bzrlib.tests.test_source',
2725
'bzrlib.tests.test_ssh_transport',
2726
'bzrlib.tests.test_status',
2727
'bzrlib.tests.test_store',
2728
'bzrlib.tests.test_strace',
2729
'bzrlib.tests.test_subsume',
2730
'bzrlib.tests.test_switch',
2731
'bzrlib.tests.test_symbol_versioning',
2732
'bzrlib.tests.test_tag',
2733
'bzrlib.tests.test_testament',
2734
'bzrlib.tests.test_textfile',
2735
'bzrlib.tests.test_textmerge',
2736
'bzrlib.tests.test_timestamp',
2737
'bzrlib.tests.test_trace',
2738
'bzrlib.tests.test_transactions',
2739
'bzrlib.tests.test_transform',
2740
'bzrlib.tests.test_transport',
2741
'bzrlib.tests.test_tree',
2742
'bzrlib.tests.test_treebuilder',
2743
'bzrlib.tests.test_tsort',
2744
'bzrlib.tests.test_tuned_gzip',
2745
'bzrlib.tests.test_ui',
2746
'bzrlib.tests.test_uncommit',
2747
'bzrlib.tests.test_upgrade',
2748
'bzrlib.tests.test_urlutils',
2749
'bzrlib.tests.test_versionedfile',
2750
'bzrlib.tests.test_version',
2751
'bzrlib.tests.test_version_info',
2752
'bzrlib.tests.test_weave',
2753
'bzrlib.tests.test_whitebox',
2754
'bzrlib.tests.test_win32utils',
2755
'bzrlib.tests.test_workingtree',
2756
'bzrlib.tests.test_workingtree_4',
2757
'bzrlib.tests.test_wsgi',
2758
'bzrlib.tests.test_xml',
2760
test_transport_implementations = [
2761
'bzrlib.tests.test_transport_implementations',
2762
'bzrlib.tests.test_read_bundle',
2764
suite = TestUtil.TestSuite()
4182
2765
loader = TestUtil.TestLoader()
4184
2767
if keep_only is not None:
4185
2768
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
2770
# 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
2771
if keep_only is None:
2772
suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
2774
for mod in [m for m in testmod_names
2775
if id_filter.is_module_name_used(m)]:
2776
mod_suite = loader.loadTestsFromModuleNames([mod])
2777
mod_suite = filter_suite_by_id_list(mod_suite, id_filter)
2778
suite.addTest(mod_suite)
2780
# modules adapted for transport implementations
2781
from bzrlib.tests.test_transport_implementations import TransportTestProviderAdapter
2782
adapter = TransportTestProviderAdapter()
2783
if keep_only is None:
2784
adapt_modules(test_transport_implementations, adapter, loader, suite)
2786
for mod in [m for m in test_transport_implementations
2787
if id_filter.is_module_name_used(m)]:
2788
mod_suite = TestUtil.TestSuite()
2789
adapt_modules([mod], adapter, loader, mod_suite)
2790
mod_suite = filter_suite_by_id_list(mod_suite, id_filter)
2791
suite.addTest(mod_suite)
2793
# modules defining their own test_suite()
2794
for package in [p for p in packages_to_test()
2795
if (keep_only is None
2796
or id_filter.is_module_name_used(p.__name__))]:
2797
pack_suite = package.test_suite()
2798
if keep_only is not None:
2799
pack_suite = filter_suite_by_id_list(pack_suite, id_filter)
2800
suite.addTest(pack_suite)
2802
# XXX: MODULES_TO_TEST should be obsoleted ?
2803
for mod in [m for m in MODULES_TO_TEST
2804
if keep_only is None or id_filter.is_module_name_used(m)]:
2805
mod_suite = loader.loadTestsFromModule(mod)
2806
if keep_only is not None:
2807
mod_suite = filter_suite_by_id_list(mod_suite, id_filter)
2808
suite.addTest(mod_suite)
2810
for mod 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)
2812
doc_suite = doctest.DocTestSuite(mod)
4226
2813
except ValueError, e:
4227
2814
print '**failed to get doctest for: %s\n%s' % (mod, e)
4229
if len(doc_suite._tests) == 0:
4230
raise errors.BzrError("no doctests found in %s" % (mod,))
2816
if keep_only is not None:
2817
# DocTests may use ids which doesn't contain the module name
2818
doc_suite = filter_suite_by_id_list(doc_suite, id_filter)
4231
2819
suite.addTest(doc_suite)
4233
2821
default_encoding = sys.getdefaultencoding()
4234
for name, plugin in _mod_plugin.plugins().items():
4235
if not interesting_module(plugin.module.__name__):
2822
for name, plugin in bzrlib.plugin.plugins().items():
2823
if keep_only is not None:
2824
if not id_filter.is_module_name_used(plugin.module.__name__):
4237
2826
plugin_suite = plugin.test_suite()
4238
2827
# We used to catch ImportError here and turn it into just a warning,
4239
2828
# but really if you don't have --no-plugins this should be a failure.
4240
2829
# mbp 20080213 - see http://bugs.launchpad.net/bugs/189771
4241
if plugin_suite is None:
4242
plugin_suite = plugin.load_plugin_tests(loader)
4243
2830
if plugin_suite is not None:
2831
if keep_only is not None:
2832
plugin_suite = filter_suite_by_id_list(plugin_suite,
4244
2834
suite.addTest(plugin_suite)
4245
2835
if default_encoding != sys.getdefaultencoding():
2836
bzrlib.trace.warning(
4247
2837
'Plugin "%s" tried to reset default encoding to: %s', name,
4248
2838
sys.getdefaultencoding())
4250
2840
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
2844
def multiply_tests_from_modules(module_name_list, scenario_iter):
2845
"""Adapt all tests in some given modules to given scenarios.
2847
This is the recommended public interface for test parameterization.
2848
Typically the test_suite() method for a per-implementation test
2849
suite will call multiply_tests_from_modules and return the
2852
:param module_name_list: List of fully-qualified names of test
2854
:param scenario_iter: Iterable of pairs of (scenario_name,
2855
scenario_param_dict).
2857
This returns a new TestSuite containing the cross product of
2858
all the tests in all the modules, each repeated for each scenario.
2859
Each test is adapted by adding the scenario name at the end
2860
of its name, and updating the test object's __dict__ with the
2861
scenario_param_dict.
2863
>>> r = multiply_tests_from_modules(
2864
... ['bzrlib.tests.test_sampler'],
2865
... [('one', dict(param=1)),
2866
... ('two', dict(param=2))])
2867
>>> tests = list(iter_suite_tests(r))
2871
'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):
2877
loader = TestLoader()
2879
adapter = TestScenarioApplier()
2880
adapter.scenarios = list(scenario_iter)
2881
adapt_modules(module_name_list, adapter, loader, suite)
2885
def multiply_scenarios(scenarios_left, scenarios_right):
4287
2886
"""Multiply two sets of scenarios.
4289
2888
:returns: the cartesian product of the two sets of scenarios, that is