17
17
"""Testing framework extensions"""
19
from __future__ import absolute_import
21
19
# NOTE: Some classes in here use camelCaseNaming() rather than
22
20
# underscore_naming(). That's for consistency with unittest; it's not the
23
21
# general style of bzrlib. Please continue that consistency when adding e.g.
99
96
from bzrlib.tests import (
105
101
from bzrlib.ui import NullProgressView
106
102
from bzrlib.ui.text import TextUIFactory
107
from bzrlib.tests.features import _CompatabilityThunkFeature
109
104
# Mark this python module as being part of the implementation
110
105
# of unittest: this gives us better tracebacks where the last
1000
995
def setUp(self):
1001
996
super(TestCase, self).setUp()
1003
timeout = config.GlobalStack().get('selftest.timeout')
1005
timeout_fixture = fixtures.TimeoutFixture(timeout)
1006
timeout_fixture.setUp()
1007
self.addCleanup(timeout_fixture.cleanUp)
1009
997
for feature in getattr(self, '_test_needs_features', []):
1010
998
self.requireFeature(feature)
1011
999
self._cleanEnvironment()
1013
1000
if bzrlib.global_state is not None:
1014
1001
self.overrideAttr(bzrlib.global_state, 'cmdline_overrides',
1015
config.CommandLineStore())
1002
config.CommandLineSection())
1017
1003
self._silenceUI()
1018
1004
self._startLogFile()
1019
1005
self._benchcalls = []
1734
1720
def _startLogFile(self):
1735
"""Setup a in-memory target for bzr and testcase log messages"""
1721
"""Send bzr and test log messages to a temporary file.
1723
The file is removed as the test is torn down.
1736
1725
pseudo_log_file = StringIO()
1737
1726
def _get_log_contents_for_weird_testtools_api():
1738
1727
return [pseudo_log_file.getvalue().decode(
1745
1734
self.addCleanup(self._finishLogFile)
1747
1736
def _finishLogFile(self):
1748
"""Flush and dereference the in-memory log for this testcase"""
1737
"""Finished with the log file.
1739
Close the file and delete it.
1749
1741
if trace._trace_file:
1750
1742
# flush the log file, to get all content
1751
1743
trace._trace_file.flush()
1752
1744
trace.pop_log_file(self._log_memento)
1753
# The logging module now tracks references for cleanup so discard ours
1754
del self._log_memento
1756
1746
def thisFailsStrictLockCheck(self):
1757
1747
"""It is known that this test would fail with -Dstrict_locks.
1993
1983
self.log('run bzr: %r', args)
1994
1984
# FIXME: don't call into logging here
1995
handler = trace.EncodedStreamHandler(stderr, errors="replace",
1985
handler = logging.StreamHandler(stderr)
1986
handler.setLevel(logging.INFO)
1997
1987
logger = logging.getLogger('')
1998
1988
logger.addHandler(handler)
1999
1989
old_ui_factory = ui.ui_factory
2188
2178
if env_changes is None:
2189
2179
env_changes = {}
2190
# Because $HOME is set to a tempdir for the context of a test, modules
2191
# installed in the user dir will not be found unless $PYTHONUSERBASE
2192
# gets set to the computed directory of this parent process.
2193
if site.USER_BASE is not None:
2194
env_changes["PYTHONUSERBASE"] = site.USER_BASE
2197
2182
def cleanup_environment():
2388
2373
from bzrlib.smart import request
2389
2374
request_handlers = request.request_handlers
2390
2375
orig_method = request_handlers.get(verb)
2391
orig_info = request_handlers.get_info(verb)
2392
2376
request_handlers.remove(verb)
2393
self.addCleanup(request_handlers.register, verb, orig_method,
2377
self.addCleanup(request_handlers.register, verb, orig_method)
2397
2380
class CapturedCall(object):
2658
2641
self.test_home_dir = self.test_dir + "/MemoryTransportMissingHomeDir"
2659
2642
self.permit_dir(self.test_dir)
2661
def make_branch(self, relpath, format=None, name=None):
2644
def make_branch(self, relpath, format=None):
2662
2645
"""Create a branch on the transport at relpath."""
2663
2646
repo = self.make_repository(relpath, format=format)
2664
return repo.bzrdir.create_branch(append_revisions_only=False,
2647
return repo.bzrdir.create_branch(append_revisions_only=False)
2667
2649
def get_default_format(self):
2668
2650
return 'default'
2736
2718
def setUp(self):
2737
2719
super(TestCaseWithMemoryTransport, self).setUp()
2739
def _add_disconnect_cleanup(transport):
2740
"""Schedule disconnection of given transport at test cleanup
2742
This needs to happen for all connected transports or leaks occur.
2744
Note reconnections may mean we call disconnect multiple times per
2745
transport which is suboptimal but seems harmless.
2747
self.addCleanup(transport.disconnect)
2749
_mod_transport.Transport.hooks.install_named_hook('post_connect',
2750
_add_disconnect_cleanup, None)
2720
# Ensure that ConnectedTransport doesn't leak sockets
2721
def get_transport_from_url_with_cleanup(*args, **kwargs):
2722
t = orig_get_transport_from_url(*args, **kwargs)
2723
if isinstance(t, _mod_transport.ConnectedTransport):
2724
self.addCleanup(t.disconnect)
2727
orig_get_transport_from_url = self.overrideAttr(
2728
_mod_transport, 'get_transport_from_url',
2729
get_transport_from_url_with_cleanup)
2752
2730
self._make_test_root()
2753
2731
self.addCleanup(os.chdir, os.getcwdu())
2754
2732
self.makeAndChdirToTestDir()
2760
2738
def setup_smart_server_with_call_log(self):
2761
2739
"""Sets up a smart server as the transport server with a call log."""
2762
2740
self.transport_server = test_server.SmartTCPServer_for_testing
2763
self.hpss_connections = []
2764
2741
self.hpss_calls = []
2765
2742
import traceback
2766
2743
# Skip the current stack down to the caller of
2769
2746
def capture_hpss_call(params):
2770
2747
self.hpss_calls.append(
2771
2748
CapturedCall(params, prefix_length))
2772
def capture_connect(transport):
2773
self.hpss_connections.append(transport)
2774
2749
client._SmartClient.hooks.install_named_hook(
2775
2750
'call', capture_hpss_call, None)
2776
_mod_transport.Transport.hooks.install_named_hook(
2777
'post_connect', capture_connect, None)
2779
2752
def reset_smart_call_log(self):
2780
2753
self.hpss_calls = []
2781
self.hpss_connections = []
2784
2756
class TestCaseInTempDir(TestCaseWithMemoryTransport):
3521
3493
ProtocolTestCase.run(self, result)
3523
pid, status = os.waitpid(self.pid, 0)
3524
# GZ 2011-10-18: If status is nonzero, should report to the result
3525
# that something went wrong.
3495
os.waitpid(self.pid, 0)
3527
3497
test_blocks = partition_tests(suite, concurrency)
3528
3498
# Clear the tests from the original suite so it doesn't keep them alive
3534
3504
c2pread, c2pwrite = os.pipe()
3535
3505
pid = os.fork()
3507
workaround_zealous_crypto_random()
3538
stream = os.fdopen(c2pwrite, 'wb', 1)
3539
workaround_zealous_crypto_random()
3540
3509
os.close(c2pread)
3541
3510
# Leave stderr and stdout open so we can see test noise
3542
3511
# Close stdin so that the child goes away if it decides to
3543
3512
# read from stdin (otherwise its a roulette to see what
3544
3513
# child actually gets keystrokes for pdb etc).
3545
3514
sys.stdin.close()
3515
# GZ 2011-06-16: Why set stdin to None? Breaks multi fork.
3517
stream = os.fdopen(c2pwrite, 'wb', 1)
3546
3518
subunit_result = AutoTimingTestResultDecorator(
3547
3519
SubUnitBzrProtocolClient(stream))
3548
3520
process_suite.run(subunit_result)
3550
# Try and report traceback on stream, but exit with error even
3551
# if stream couldn't be created or something else goes wrong.
3552
# The traceback is formatted to a string and written in one go
3553
# to avoid interleaving lines from multiple failing children.
3555
stream.write(traceback.format_exc())
3522
# GZ 2011-06-16: Is always exiting with silent success
3523
# really the right thing? Hurts debugging.
3560
3526
os.close(c2pwrite)
3561
3527
stream = os.fdopen(c2pread, 'rb', 1)
4003
3969
'bzrlib.tests.test_http',
4004
3970
'bzrlib.tests.test_http_response',
4005
3971
'bzrlib.tests.test_https_ca_bundle',
4006
'bzrlib.tests.test_https_urllib',
4007
3972
'bzrlib.tests.test_i18n',
4008
3973
'bzrlib.tests.test_identitymap',
4009
3974
'bzrlib.tests.test_ignores',
4058
4023
'bzrlib.tests.test_revisiontree',
4059
4024
'bzrlib.tests.test_rio',
4060
4025
'bzrlib.tests.test_rules',
4061
'bzrlib.tests.test_url_policy_open',
4062
4026
'bzrlib.tests.test_sampler',
4063
4027
'bzrlib.tests.test_scenarios',
4064
4028
'bzrlib.tests.test_script',
4108
4072
'bzrlib.tests.test_version',
4109
4073
'bzrlib.tests.test_version_info',
4110
4074
'bzrlib.tests.test_versionedfile',
4111
'bzrlib.tests.test_vf_search',
4112
4075
'bzrlib.tests.test_weave',
4113
4076
'bzrlib.tests.test_whitebox',
4114
4077
'bzrlib.tests.test_win32utils',
4500
# API compatibility for old plugins; see bug 892622.
4503
'HTTPServerFeature',
4504
'ModuleAvailableFeature',
4505
'HTTPSServerFeature', 'SymlinkFeature', 'HardlinkFeature',
4506
'OsFifoFeature', 'UnicodeFilenameFeature',
4507
'ByteStringNamedFilesystem', 'UTF8Filesystem',
4508
'BreakinFeature', 'CaseInsCasePresFilenameFeature',
4509
'CaseInsensitiveFilesystemFeature', 'case_sensitive_filesystem_feature',
4510
'posix_permissions_feature',
4512
globals()[name] = _CompatabilityThunkFeature(
4513
symbol_versioning.deprecated_in((2, 5, 0)),
4514
'bzrlib.tests', name,
4515
name, 'bzrlib.tests.features')
4518
for (old_name, new_name) in [
4519
('UnicodeFilename', 'UnicodeFilenameFeature'),
4521
globals()[name] = _CompatabilityThunkFeature(
4522
symbol_versioning.deprecated_in((2, 5, 0)),
4523
'bzrlib.tests', old_name,
4524
new_name, 'bzrlib.tests.features')
4463
@deprecated_function(deprecated_in((2, 5, 0)))
4464
def ModuleAvailableFeature(name):
4465
from bzrlib.tests import features
4466
return features.ModuleAvailableFeature(name)