212
218
osutils.set_or_unset_env(var, value)
221
def _clear__type_equality_funcs(test):
222
"""Cleanup bound methods stored on TestCase instances
224
Clear the dict breaking a few (mostly) harmless cycles in the affected
225
unittests released with Python 2.6 and initial Python 2.7 versions.
227
For a few revisions between Python 2.7.1 and Python 2.7.2 that annoyingly
228
shipped in Oneiric, an object with no clear method was used, hence the
229
extra complications, see bug 809048 for details.
231
type_equality_funcs = getattr(test, "_type_equality_funcs", None)
232
if type_equality_funcs is not None:
233
tef_clear = getattr(type_equality_funcs, "clear", None)
234
if tef_clear is None:
235
tef_instance_dict = getattr(type_equality_funcs, "__dict__", None)
236
if tef_instance_dict is not None:
237
tef_clear = tef_instance_dict.clear
238
if tef_clear is not None:
215
242
class ExtendedTestResult(testtools.TextTestResult):
216
243
"""Accepts, reports and accumulates the results of running tests.
385
412
getDetails = getattr(test, "getDetails", None)
386
413
if getDetails is not None:
387
414
getDetails().clear()
388
# Clear _type_equality_funcs to try to stop TestCase instances
389
# from wasting memory. 'clear' is not available in all Python
390
# versions (bug 809048)
391
type_equality_funcs = getattr(test, "_type_equality_funcs", None)
392
if type_equality_funcs is not None:
393
tef_clear = getattr(type_equality_funcs, "clear", None)
394
if tef_clear is None:
395
tef_instance_dict = getattr(type_equality_funcs, "__dict__", None)
396
if tef_instance_dict is not None:
397
tef_clear = tef_instance_dict.clear
398
if tef_clear is not None:
415
_clear__type_equality_funcs(test)
400
416
self._traceback_from_test = None
402
418
def startTests(self):
503
519
self.not_applicable_count += 1
504
520
self.report_not_applicable(test, reason)
522
def _count_stored_tests(self):
523
"""Count of tests instances kept alive due to not succeeding"""
524
return self.error_count + self.failure_count + self.known_failure_count
506
526
def _post_mortem(self, tb=None):
507
527
"""Start a PDB post mortem session."""
508
528
if os.environ.get('BZR_TEST_PDB', None):
981
1001
def setUp(self):
982
1002
super(TestCase, self).setUp()
1004
# At this point we're still accessing the config files in $BZR_HOME (as
1005
# set by the user running selftest).
1006
timeout = config.GlobalStack().get('selftest.timeout')
1008
timeout_fixture = fixtures.TimeoutFixture(timeout)
1009
timeout_fixture.setUp()
1010
self.addCleanup(timeout_fixture.cleanUp)
983
1012
for feature in getattr(self, '_test_needs_features', []):
984
1013
self.requireFeature(feature)
985
1014
self._cleanEnvironment()
1016
if bzrlib.global_state is not None:
1017
self.overrideAttr(bzrlib.global_state, 'cmdline_overrides',
1018
config.CommandLineStore())
986
1020
self._silenceUI()
987
1021
self._startLogFile()
988
1022
self._benchcalls = []
995
1029
# between tests. We should get rid of this altogether: bug 656694. --
997
1031
self.overrideAttr(bzrlib.trace, '_verbosity_level', 0)
998
# Isolate config option expansion until its default value for bzrlib is
999
# settled on or a the FIXME associated with _get_expand_default_value
1000
# is addressed -- vila 20110219
1001
self.overrideAttr(config, '_expand_default_value', None)
1002
1032
self._log_files = set()
1003
1033
# Each key in the ``_counters`` dict holds a value for a different
1004
1034
# counter. When the test ends, addDetail() should be used to output the
1297
1327
# hook into bzr dir opening. This leaves a small window of error for
1298
1328
# transport tests, but they are well known, and we can improve on this
1300
bzrdir.BzrDir.hooks.install_named_hook("pre_open",
1330
controldir.ControlDir.hooks.install_named_hook("pre_open",
1301
1331
self._preopen_isolate_transport, "Check bzr directories are safe.")
1303
1333
def _ndiff_strings(self, a, b):
1717
1744
self.addCleanup(self._finishLogFile)
1719
1746
def _finishLogFile(self):
1720
"""Finished with the log file.
1722
Close the file and delete it.
1747
"""Flush and dereference the in-memory log for this testcase"""
1724
1748
if trace._trace_file:
1725
1749
# flush the log file, to get all content
1726
1750
trace._trace_file.flush()
1727
1751
trace.pop_log_file(self._log_memento)
1752
# The logging module now tracks references for cleanup so discard ours
1753
del self._log_memento
1729
1755
def thisFailsStrictLockCheck(self):
1730
1756
"""It is known that this test would fail with -Dstrict_locks.
1966
1992
self.log('run bzr: %r', args)
1967
1993
# FIXME: don't call into logging here
1968
handler = logging.StreamHandler(stderr)
1969
handler.setLevel(logging.INFO)
1994
handler = trace.EncodedStreamHandler(stderr, errors="replace",
1970
1996
logger = logging.getLogger('')
1971
1997
logger.addHandler(handler)
1972
1998
old_ui_factory = ui.ui_factory
2356
2387
from bzrlib.smart import request
2357
2388
request_handlers = request.request_handlers
2358
2389
orig_method = request_handlers.get(verb)
2390
orig_info = request_handlers.get_info(verb)
2359
2391
request_handlers.remove(verb)
2360
self.addCleanup(request_handlers.register, verb, orig_method)
2392
self.addCleanup(request_handlers.register, verb, orig_method,
2363
2396
class CapturedCall(object):
2416
2449
self.transport_readonly_server = None
2417
2450
self.__vfs_server = None
2453
super(TestCaseWithMemoryTransport, self).setUp()
2455
def _add_disconnect_cleanup(transport):
2456
"""Schedule disconnection of given transport at test cleanup
2458
This needs to happen for all connected transports or leaks occur.
2460
Note reconnections may mean we call disconnect multiple times per
2461
transport which is suboptimal but seems harmless.
2463
self.addCleanup(transport.disconnect)
2465
_mod_transport.Transport.hooks.install_named_hook('post_connect',
2466
_add_disconnect_cleanup, None)
2468
self._make_test_root()
2469
self.addCleanup(os.chdir, os.getcwdu())
2470
self.makeAndChdirToTestDir()
2471
self.overrideEnvironmentForTesting()
2472
self.__readonly_server = None
2473
self.__server = None
2474
self.reduceLockdirTimeout()
2475
# Each test may use its own config files even if the local config files
2476
# don't actually exist. They'll rightly fail if they try to create them
2478
self.overrideAttr(config, '_shared_stores', {})
2419
2480
def get_transport(self, relpath=None):
2420
2481
"""Return a writeable transport.
2570
2631
# http://pad.lv/825027).
2571
2632
self.assertIs(None, os.environ.get('BZR_HOME', None))
2572
2633
os.environ['BZR_HOME'] = root
2573
wt = bzrdir.BzrDir.create_standalone_workingtree(root)
2634
wt = controldir.ControlDir.create_standalone_workingtree(root)
2574
2635
del os.environ['BZR_HOME']
2575
2636
except Exception, e:
2576
self.fail("Fail to initialize the safety net: %r\nExiting\n" % (e,))
2637
self.fail("Fail to initialize the safety net: %r\n" % (e,))
2577
2638
# Hack for speed: remember the raw bytes of the dirstate file so that
2578
2639
# we don't need to re-open the wt to check it hasn't changed.
2579
2640
TestCaseWithMemoryTransport._SAFETY_NET_PRISTINE_DIRSTATE = (
2627
2688
self.test_home_dir = self.test_dir + "/MemoryTransportMissingHomeDir"
2628
2689
self.permit_dir(self.test_dir)
2630
def make_branch(self, relpath, format=None):
2691
def make_branch(self, relpath, format=None, name=None):
2631
2692
"""Create a branch on the transport at relpath."""
2632
2693
repo = self.make_repository(relpath, format=format)
2633
return repo.bzrdir.create_branch(append_revisions_only=False)
2635
def resolve_format(self, format):
2636
"""Resolve an object to a ControlDir format object.
2638
The initial format object can either already be
2639
a ControlDirFormat, None (for the default format),
2640
or a string with the name of the control dir format.
2642
:param format: Object to resolve
2643
:return A ControlDirFormat instance
2647
if isinstance(format, basestring):
2648
format = bzrdir.format_registry.make_bzrdir(format)
2651
def resolve_format(self, format):
2652
"""Resolve an object to a ControlDir format object.
2654
The initial format object can either already be
2655
a ControlDirFormat, None (for the default format),
2656
or a string with the name of the control dir format.
2658
:param format: Object to resolve
2659
:return A ControlDirFormat instance
2663
if isinstance(format, basestring):
2664
format = bzrdir.format_registry.make_bzrdir(format)
2694
return repo.bzrdir.create_branch(append_revisions_only=False,
2697
def get_default_format(self):
2700
def resolve_format(self, format):
2701
"""Resolve an object to a ControlDir format object.
2703
The initial format object can either already be
2704
a ControlDirFormat, None (for the default format),
2705
or a string with the name of the control dir format.
2707
:param format: Object to resolve
2708
:return A ControlDirFormat instance
2711
format = self.get_default_format()
2712
if isinstance(format, basestring):
2713
format = controldir.format_registry.make_bzrdir(format)
2667
2716
def make_bzrdir(self, relpath, format=None):
2714
2763
self.overrideEnv('HOME', test_home_dir)
2715
2764
self.overrideEnv('BZR_HOME', test_home_dir)
2718
super(TestCaseWithMemoryTransport, self).setUp()
2719
# Ensure that ConnectedTransport doesn't leak sockets
2720
def get_transport_from_url_with_cleanup(*args, **kwargs):
2721
t = orig_get_transport_from_url(*args, **kwargs)
2722
if isinstance(t, _mod_transport.ConnectedTransport):
2723
self.addCleanup(t.disconnect)
2726
orig_get_transport_from_url = self.overrideAttr(
2727
_mod_transport, 'get_transport_from_url',
2728
get_transport_from_url_with_cleanup)
2729
self._make_test_root()
2730
self.addCleanup(os.chdir, os.getcwdu())
2731
self.makeAndChdirToTestDir()
2732
self.overrideEnvironmentForTesting()
2733
self.__readonly_server = None
2734
self.__server = None
2735
self.reduceLockdirTimeout()
2737
2766
def setup_smart_server_with_call_log(self):
2738
2767
"""Sets up a smart server as the transport server with a call log."""
2739
2768
self.transport_server = test_server.SmartTCPServer_for_testing
2769
self.hpss_connections = []
2740
2770
self.hpss_calls = []
2741
2771
import traceback
2742
2772
# Skip the current stack down to the caller of
2745
2775
def capture_hpss_call(params):
2746
2776
self.hpss_calls.append(
2747
2777
CapturedCall(params, prefix_length))
2778
def capture_connect(transport):
2779
self.hpss_connections.append(transport)
2748
2780
client._SmartClient.hooks.install_named_hook(
2749
2781
'call', capture_hpss_call, None)
2782
_mod_transport.Transport.hooks.install_named_hook(
2783
'post_connect', capture_connect, None)
2751
2785
def reset_smart_call_log(self):
2752
2786
self.hpss_calls = []
2787
self.hpss_connections = []
2755
2790
class TestCaseInTempDir(TestCaseWithMemoryTransport):
2825
2860
# stacking policy to honour; create a bzr dir with an unshared
2826
2861
# repository (but not a branch - our code would be trying to escape
2827
2862
# then!) to stop them, and permit it to be read.
2828
# control = bzrdir.BzrDir.create(self.test_base_dir)
2863
# control = controldir.ControlDir.create(self.test_base_dir)
2829
2864
# control.create_repository()
2830
2865
self.test_home_dir = self.test_base_dir + '/home'
2831
2866
os.mkdir(self.test_home_dir)
2957
2996
# this obviously requires a format that supports branch references
2958
2997
# so check for that by checking bzrdir.BzrDirFormat.get_default_format()
2999
format = self.resolve_format(format=format)
3000
if not format.supports_workingtrees:
3001
b = self.make_branch(relpath+'.branch', format=format)
3002
return b.create_checkout(relpath, lightweight=True)
2960
3003
b = self.make_branch(relpath, format=format)
2962
3005
return b.bzrdir.create_workingtree()
2967
3010
if self.vfs_transport_factory is test_server.LocalURLServer:
2968
3011
# the branch is colocated on disk, we cannot create a checkout.
2969
3012
# hopefully callers will expect this.
2970
local_controldir= bzrdir.BzrDir.open(self.get_vfs_only_url(relpath))
3013
local_controldir = controldir.ControlDir.open(
3014
self.get_vfs_only_url(relpath))
2971
3015
wt = local_controldir.create_workingtree()
2972
3016
if wt.branch._format != b._format:
3003
3047
self.assertFalse(differences.has_changed(),
3004
3048
"Trees %r and %r are different: %r" % (left, right, differences))
3007
super(TestCaseWithTransport, self).setUp()
3008
self.__vfs_server = None
3010
3050
def disable_missing_extensions_warning(self):
3011
3051
"""Some tests expect a precise stderr content.
3013
3053
There is no point in forcing them to duplicate the extension related
3016
config.GlobalConfig().set_user_option('ignore_missing_extensions', True)
3056
config.GlobalStack().set('ignore_missing_extensions', True)
3019
3059
class ChrootedTestCase(TestCaseWithTransport):
3261
3301
result_decorators=result_decorators,
3263
3303
runner.stop_on_failure=stop_on_failure
3304
if isinstance(suite, unittest.TestSuite):
3305
# Empty out _tests list of passed suite and populate new TestSuite
3306
suite._tests[:], suite = [], TestSuite(suite)
3264
3307
# built in decorator factories:
3266
3309
random_order(random_seed, runner),
3365
3408
class TestDecorator(TestUtil.TestSuite):
3366
3409
"""A decorator for TestCase/TestSuite objects.
3368
Usually, subclasses should override __iter__(used when flattening test
3369
suites), which we do to filter, reorder, parallelise and so on, run() and
3411
Contains rather than flattening suite passed on construction
3373
def __init__(self, suite):
3374
TestUtil.TestSuite.__init__(self)
3377
def countTestCases(self):
3380
cases += test.countTestCases()
3387
def run(self, result):
3388
# Use iteration on self, not self._tests, to allow subclasses to hook
3391
if result.shouldStop:
3414
def __init__(self, suite=None):
3415
super(TestDecorator, self).__init__()
3416
if suite is not None:
3419
# Don't need subclass run method with suite emptying
3420
run = unittest.TestSuite.run
3397
3423
class CountingDecorator(TestDecorator):
3408
3434
"""A decorator which excludes test matching an exclude pattern."""
3410
3436
def __init__(self, suite, exclude_pattern):
3411
TestDecorator.__init__(self, suite)
3412
self.exclude_pattern = exclude_pattern
3413
self.excluded = False
3417
return iter(self._tests)
3418
self.excluded = True
3419
suite = exclude_tests_by_re(self, self.exclude_pattern)
3421
self.addTests(suite)
3422
return iter(self._tests)
3437
super(ExcludeDecorator, self).__init__(
3438
exclude_tests_by_re(suite, exclude_pattern))
3425
3441
class FilterTestsDecorator(TestDecorator):
3426
3442
"""A decorator which filters tests to those matching a pattern."""
3428
3444
def __init__(self, suite, pattern):
3429
TestDecorator.__init__(self, suite)
3430
self.pattern = pattern
3431
self.filtered = False
3435
return iter(self._tests)
3436
self.filtered = True
3437
suite = filter_suite_by_re(self, self.pattern)
3439
self.addTests(suite)
3440
return iter(self._tests)
3445
super(FilterTestsDecorator, self).__init__(
3446
filter_suite_by_re(suite, pattern))
3443
3449
class RandomDecorator(TestDecorator):
3444
3450
"""A decorator which randomises the order of its tests."""
3446
3452
def __init__(self, suite, random_seed, stream):
3447
TestDecorator.__init__(self, suite)
3448
self.random_seed = random_seed
3449
self.randomised = False
3450
self.stream = stream
3454
return iter(self._tests)
3455
self.randomised = True
3456
self.stream.write("Randomizing test order using seed %s\n\n" %
3457
(self.actual_seed()))
3453
random_seed = self.actual_seed(random_seed)
3454
stream.write("Randomizing test order using seed %s\n\n" %
3458
3456
# Initialise the random number generator.
3459
random.seed(self.actual_seed())
3460
suite = randomize_suite(self)
3462
self.addTests(suite)
3463
return iter(self._tests)
3457
random.seed(random_seed)
3458
super(RandomDecorator, self).__init__(randomize_suite(suite))
3465
def actual_seed(self):
3466
if self.random_seed == "now":
3461
def actual_seed(seed):
3467
3463
# We convert the seed to a long to make it reuseable across
3468
3464
# invocations (because the user can reenter it).
3469
self.random_seed = long(time.time())
3465
return long(time.time())
3471
3467
# Convert the seed to a long if we can
3473
self.random_seed = long(self.random_seed)
3470
except (TypeError, ValueError):
3476
return self.random_seed
3479
3475
class TestFirstDecorator(TestDecorator):
3480
3476
"""A decorator which moves named tests to the front."""
3482
3478
def __init__(self, suite, pattern):
3483
TestDecorator.__init__(self, suite)
3484
self.pattern = pattern
3485
self.filtered = False
3489
return iter(self._tests)
3490
self.filtered = True
3491
suites = split_suite_by_re(self, self.pattern)
3493
self.addTests(suites)
3494
return iter(self._tests)
3479
super(TestFirstDecorator, self).__init__()
3480
self.addTests(split_suite_by_re(suite, pattern))
3497
3483
def partition_tests(suite, count):
3542
3528
ProtocolTestCase.run(self, result)
3544
os.waitpid(self.pid, 0)
3530
pid, status = os.waitpid(self.pid, 0)
3531
# GZ 2011-10-18: If status is nonzero, should report to the result
3532
# that something went wrong.
3546
3534
test_blocks = partition_tests(suite, concurrency)
3535
# Clear the tests from the original suite so it doesn't keep them alive
3536
suite._tests[:] = []
3547
3537
for process_tests in test_blocks:
3548
process_suite = TestUtil.TestSuite()
3549
process_suite.addTests(process_tests)
3538
process_suite = TestUtil.TestSuite(process_tests)
3539
# Also clear each split list so new suite has only reference
3540
process_tests[:] = []
3550
3541
c2pread, c2pwrite = os.pipe()
3551
3542
pid = os.fork()
3553
workaround_zealous_crypto_random()
3545
stream = os.fdopen(c2pwrite, 'wb', 1)
3546
workaround_zealous_crypto_random()
3555
3547
os.close(c2pread)
3556
3548
# Leave stderr and stdout open so we can see test noise
3557
3549
# Close stdin so that the child goes away if it decides to
3558
3550
# read from stdin (otherwise its a roulette to see what
3559
3551
# child actually gets keystrokes for pdb etc).
3560
3552
sys.stdin.close()
3562
stream = os.fdopen(c2pwrite, 'wb', 1)
3563
3553
subunit_result = AutoTimingTestResultDecorator(
3564
TestProtocolClient(stream))
3554
SubUnitBzrProtocolClient(stream))
3565
3555
process_suite.run(subunit_result)
3557
# Try and report traceback on stream, but exit with error even
3558
# if stream couldn't be created or something else goes wrong.
3559
# The traceback is formatted to a string and written in one go
3560
# to avoid interleaving lines from multiple failing children.
3562
stream.write(traceback.format_exc())
3569
3567
os.close(c2pwrite)
3570
3568
stream = os.fdopen(c2pread, 'rb', 1)
3676
3674
# with proper exclusion rules.
3677
3675
# -Ethreads Will display thread ident at creation/join time to
3678
3676
# help track thread leaks
3677
# -Euncollected_cases Display the identity of any test cases that weren't
3678
# deallocated after being completed.
3680
3679
# -Econfig_stats Will collect statistics using addDetail
3681
3680
selftest_debug_flags = set()
4011
4009
'bzrlib.tests.test_http',
4012
4010
'bzrlib.tests.test_http_response',
4013
4011
'bzrlib.tests.test_https_ca_bundle',
4012
'bzrlib.tests.test_https_urllib',
4014
4013
'bzrlib.tests.test_i18n',
4015
4014
'bzrlib.tests.test_identitymap',
4016
4015
'bzrlib.tests.test_ignores',
4065
4064
'bzrlib.tests.test_revisiontree',
4066
4065
'bzrlib.tests.test_rio',
4067
4066
'bzrlib.tests.test_rules',
4067
'bzrlib.tests.test_url_policy_open',
4068
4068
'bzrlib.tests.test_sampler',
4069
4069
'bzrlib.tests.test_scenarios',
4070
4070
'bzrlib.tests.test_script',
4077
4077
'bzrlib.tests.test_smart',
4078
4078
'bzrlib.tests.test_smart_add',
4079
4079
'bzrlib.tests.test_smart_request',
4080
'bzrlib.tests.test_smart_signals',
4080
4081
'bzrlib.tests.test_smart_transport',
4081
4082
'bzrlib.tests.test_smtp_connection',
4082
4083
'bzrlib.tests.test_source',
4113
4114
'bzrlib.tests.test_version',
4114
4115
'bzrlib.tests.test_version_info',
4115
4116
'bzrlib.tests.test_versionedfile',
4117
'bzrlib.tests.test_vf_search',
4116
4118
'bzrlib.tests.test_weave',
4117
4119
'bzrlib.tests.test_whitebox',
4118
4120
'bzrlib.tests.test_win32utils',
4479
4481
from subunit.test_results import AutoTimingTestResultDecorator
4480
4482
class SubUnitBzrProtocolClient(TestProtocolClient):
4484
def stopTest(self, test):
4485
super(SubUnitBzrProtocolClient, self).stopTest(test)
4486
_clear__type_equality_funcs(test)
4482
4488
def addSuccess(self, test, details=None):
4483
4489
# The subunit client always includes the details in the subunit
4484
4490
# stream, but we don't want to include it in ours.
4500
@deprecated_function(deprecated_in((2, 5, 0)))
4501
def ModuleAvailableFeature(name):
4502
from bzrlib.tests import features
4503
return features.ModuleAvailableFeature(name)
4506
# API compatibility for old plugins; see bug 892622.
4509
'HTTPServerFeature',
4510
'ModuleAvailableFeature',
4511
'HTTPSServerFeature', 'SymlinkFeature', 'HardlinkFeature',
4512
'OsFifoFeature', 'UnicodeFilenameFeature',
4513
'ByteStringNamedFilesystem', 'UTF8Filesystem',
4514
'BreakinFeature', 'CaseInsCasePresFilenameFeature',
4515
'CaseInsensitiveFilesystemFeature', 'case_sensitive_filesystem_feature',
4516
'posix_permissions_feature',
4518
globals()[name] = _CompatabilityThunkFeature(
4519
symbol_versioning.deprecated_in((2, 5, 0)),
4520
'bzrlib.tests', name,
4521
name, 'bzrlib.tests.features')
4524
for (old_name, new_name) in [
4525
('UnicodeFilename', 'UnicodeFilenameFeature'),
4527
globals()[name] = _CompatabilityThunkFeature(
4528
symbol_versioning.deprecated_in((2, 5, 0)),
4529
'bzrlib.tests', old_name,
4530
new_name, 'bzrlib.tests.features')