~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

  • Committer: Jelmer Vernooij
  • Date: 2012-02-18 16:55:04 UTC
  • mfrom: (6437.23.10 2.5)
  • mto: This revision was merged to the branch mainline in revision 6469.
  • Revision ID: jelmer@samba.org-20120218165504-c9oe5c5ue805y8wp
Merge bzr/2.5.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Testing framework extensions"""
18
18
 
 
19
from __future__ import absolute_import
 
20
 
19
21
# NOTE: Some classes in here use camelCaseNaming() rather than
20
22
# underscore_naming().  That's for consistency with unittest; it's not the
21
23
# general style of bzrlib.  Please continue that consistency when adding e.g.
36
38
import random
37
39
import re
38
40
import shlex
 
41
import site
39
42
import stat
40
43
import subprocess
41
44
import sys
94
97
    deprecated_in,
95
98
    )
96
99
from bzrlib.tests import (
 
100
    fixtures,
97
101
    test_server,
98
102
    TestUtil,
99
103
    treeshape,
100
104
    )
101
105
from bzrlib.ui import NullProgressView
102
106
from bzrlib.ui.text import TextUIFactory
 
107
from bzrlib.tests.features import _CompatabilityThunkFeature
103
108
 
104
109
# Mark this python module as being part of the implementation
105
110
# of unittest: this gives us better tracebacks where the last
242
247
    different types of display.
243
248
 
244
249
    When a test finishes, in whatever way, it calls one of the addSuccess,
245
 
    addFailure or addError classes.  These in turn may redirect to a more
 
250
    addFailure or addError methods.  These in turn may redirect to a more
246
251
    specific case for the special test results supported by our extended
247
252
    tests.
248
253
 
994
999
 
995
1000
    def setUp(self):
996
1001
        super(TestCase, self).setUp()
 
1002
 
 
1003
        timeout = config.GlobalStack().get('selftest.timeout')
 
1004
        if timeout:
 
1005
            timeout_fixture = fixtures.TimeoutFixture(timeout)
 
1006
            timeout_fixture.setUp()
 
1007
            self.addCleanup(timeout_fixture.cleanUp)
 
1008
 
997
1009
        for feature in getattr(self, '_test_needs_features', []):
998
1010
            self.requireFeature(feature)
999
1011
        self._cleanEnvironment()
 
1012
 
1000
1013
        if bzrlib.global_state is not None:
1001
1014
            self.overrideAttr(bzrlib.global_state, 'cmdline_overrides',
1002
 
                              config.CommandLineSection())
 
1015
                              config.CommandLineStore())
 
1016
 
1003
1017
        self._silenceUI()
1004
1018
        self._startLogFile()
1005
1019
        self._benchcalls = []
1718
1732
        return result
1719
1733
 
1720
1734
    def _startLogFile(self):
1721
 
        """Send bzr and test log messages to a temporary file.
1722
 
 
1723
 
        The file is removed as the test is torn down.
1724
 
        """
 
1735
        """Setup a in-memory target for bzr and testcase log messages"""
1725
1736
        pseudo_log_file = StringIO()
1726
1737
        def _get_log_contents_for_weird_testtools_api():
1727
1738
            return [pseudo_log_file.getvalue().decode(
1734
1745
        self.addCleanup(self._finishLogFile)
1735
1746
 
1736
1747
    def _finishLogFile(self):
1737
 
        """Finished with the log file.
1738
 
 
1739
 
        Close the file and delete it.
1740
 
        """
 
1748
        """Flush and dereference the in-memory log for this testcase"""
1741
1749
        if trace._trace_file:
1742
1750
            # flush the log file, to get all content
1743
1751
            trace._trace_file.flush()
1744
1752
        trace.pop_log_file(self._log_memento)
 
1753
        # The logging module now tracks references for cleanup so discard ours
 
1754
        del self._log_memento
1745
1755
 
1746
1756
    def thisFailsStrictLockCheck(self):
1747
1757
        """It is known that this test would fail with -Dstrict_locks.
1982
1992
 
1983
1993
        self.log('run bzr: %r', args)
1984
1994
        # FIXME: don't call into logging here
1985
 
        handler = logging.StreamHandler(stderr)
1986
 
        handler.setLevel(logging.INFO)
 
1995
        handler = trace.EncodedStreamHandler(stderr, errors="replace",
 
1996
            level=logging.INFO)
1987
1997
        logger = logging.getLogger('')
1988
1998
        logger.addHandler(handler)
1989
1999
        old_ui_factory = ui.ui_factory
2177
2187
 
2178
2188
        if env_changes is None:
2179
2189
            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
2180
2195
        old_env = {}
2181
2196
 
2182
2197
        def cleanup_environment():
2373
2388
        from bzrlib.smart import request
2374
2389
        request_handlers = request.request_handlers
2375
2390
        orig_method = request_handlers.get(verb)
 
2391
        orig_info = request_handlers.get_info(verb)
2376
2392
        request_handlers.remove(verb)
2377
 
        self.addCleanup(request_handlers.register, verb, orig_method)
 
2393
        self.addCleanup(request_handlers.register, verb, orig_method,
 
2394
            info=orig_info)
2378
2395
 
2379
2396
 
2380
2397
class CapturedCall(object):
2641
2658
        self.test_home_dir = self.test_dir + "/MemoryTransportMissingHomeDir"
2642
2659
        self.permit_dir(self.test_dir)
2643
2660
 
2644
 
    def make_branch(self, relpath, format=None):
 
2661
    def make_branch(self, relpath, format=None, name=None):
2645
2662
        """Create a branch on the transport at relpath."""
2646
2663
        repo = self.make_repository(relpath, format=format)
2647
 
        return repo.bzrdir.create_branch(append_revisions_only=False)
 
2664
        return repo.bzrdir.create_branch(append_revisions_only=False,
 
2665
                                         name=name)
2648
2666
 
2649
2667
    def get_default_format(self):
2650
2668
        return 'default'
2717
2735
 
2718
2736
    def setUp(self):
2719
2737
        super(TestCaseWithMemoryTransport, self).setUp()
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)
2725
 
            return t
2726
 
 
2727
 
        orig_get_transport_from_url = self.overrideAttr(
2728
 
            _mod_transport, 'get_transport_from_url',
2729
 
            get_transport_from_url_with_cleanup)
 
2738
 
 
2739
        def _add_disconnect_cleanup(transport):
 
2740
            """Schedule disconnection of given transport at test cleanup
 
2741
 
 
2742
            This needs to happen for all connected transports or leaks occur.
 
2743
 
 
2744
            Note reconnections may mean we call disconnect multiple times per
 
2745
            transport which is suboptimal but seems harmless.
 
2746
            """
 
2747
            self.addCleanup(transport.disconnect)
 
2748
 
 
2749
        _mod_transport.Transport.hooks.install_named_hook('post_connect',
 
2750
            _add_disconnect_cleanup, None)
 
2751
 
2730
2752
        self._make_test_root()
2731
2753
        self.addCleanup(os.chdir, os.getcwdu())
2732
2754
        self.makeAndChdirToTestDir()
2738
2760
    def setup_smart_server_with_call_log(self):
2739
2761
        """Sets up a smart server as the transport server with a call log."""
2740
2762
        self.transport_server = test_server.SmartTCPServer_for_testing
 
2763
        self.hpss_connections = []
2741
2764
        self.hpss_calls = []
2742
2765
        import traceback
2743
2766
        # Skip the current stack down to the caller of
2746
2769
        def capture_hpss_call(params):
2747
2770
            self.hpss_calls.append(
2748
2771
                CapturedCall(params, prefix_length))
 
2772
        def capture_connect(transport):
 
2773
            self.hpss_connections.append(transport)
2749
2774
        client._SmartClient.hooks.install_named_hook(
2750
2775
            'call', capture_hpss_call, None)
 
2776
        _mod_transport.Transport.hooks.install_named_hook(
 
2777
            'post_connect', capture_connect, None)
2751
2778
 
2752
2779
    def reset_smart_call_log(self):
2753
2780
        self.hpss_calls = []
 
2781
        self.hpss_connections = []
2754
2782
 
2755
2783
 
2756
2784
class TestCaseInTempDir(TestCaseWithMemoryTransport):
3492
3520
            try:
3493
3521
                ProtocolTestCase.run(self, result)
3494
3522
            finally:
3495
 
                os.waitpid(self.pid, 0)
 
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.
3496
3526
 
3497
3527
    test_blocks = partition_tests(suite, concurrency)
3498
3528
    # Clear the tests from the original suite so it doesn't keep them alive
3504
3534
        c2pread, c2pwrite = os.pipe()
3505
3535
        pid = os.fork()
3506
3536
        if pid == 0:
3507
 
            workaround_zealous_crypto_random()
3508
3537
            try:
 
3538
                stream = os.fdopen(c2pwrite, 'wb', 1)
 
3539
                workaround_zealous_crypto_random()
3509
3540
                os.close(c2pread)
3510
3541
                # Leave stderr and stdout open so we can see test noise
3511
3542
                # Close stdin so that the child goes away if it decides to
3512
3543
                # read from stdin (otherwise its a roulette to see what
3513
3544
                # child actually gets keystrokes for pdb etc).
3514
3545
                sys.stdin.close()
3515
 
                # GZ 2011-06-16: Why set stdin to None? Breaks multi fork.
3516
 
                #sys.stdin = None
3517
 
                stream = os.fdopen(c2pwrite, 'wb', 1)
3518
3546
                subunit_result = AutoTimingTestResultDecorator(
3519
3547
                    SubUnitBzrProtocolClient(stream))
3520
3548
                process_suite.run(subunit_result)
3521
 
            finally:
3522
 
                # GZ 2011-06-16: Is always exiting with silent success
3523
 
                #                really the right thing? Hurts debugging.
3524
 
                os._exit(0)
 
3549
            except:
 
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.
 
3554
                try:
 
3555
                    stream.write(traceback.format_exc())
 
3556
                finally:
 
3557
                    os._exit(1)
 
3558
            os._exit(0)
3525
3559
        else:
3526
3560
            os.close(c2pwrite)
3527
3561
            stream = os.fdopen(c2pread, 'rb', 1)
3969
4003
        'bzrlib.tests.test_http',
3970
4004
        'bzrlib.tests.test_http_response',
3971
4005
        'bzrlib.tests.test_https_ca_bundle',
 
4006
        'bzrlib.tests.test_https_urllib',
3972
4007
        'bzrlib.tests.test_i18n',
3973
4008
        'bzrlib.tests.test_identitymap',
3974
4009
        'bzrlib.tests.test_ignores',
4023
4058
        'bzrlib.tests.test_revisiontree',
4024
4059
        'bzrlib.tests.test_rio',
4025
4060
        'bzrlib.tests.test_rules',
 
4061
        'bzrlib.tests.test_url_policy_open',
4026
4062
        'bzrlib.tests.test_sampler',
4027
4063
        'bzrlib.tests.test_scenarios',
4028
4064
        'bzrlib.tests.test_script',
4072
4108
        'bzrlib.tests.test_version',
4073
4109
        'bzrlib.tests.test_version_info',
4074
4110
        'bzrlib.tests.test_versionedfile',
 
4111
        'bzrlib.tests.test_vf_search',
4075
4112
        'bzrlib.tests.test_weave',
4076
4113
        'bzrlib.tests.test_whitebox',
4077
4114
        'bzrlib.tests.test_win32utils',
4460
4497
    pass
4461
4498
 
4462
4499
 
4463
 
@deprecated_function(deprecated_in((2, 5, 0)))
4464
 
def ModuleAvailableFeature(name):
4465
 
    from bzrlib.tests import features
4466
 
    return features.ModuleAvailableFeature(name)
4467
 
    
 
4500
# API compatibility for old plugins; see bug 892622.
 
4501
for name in [
 
4502
    'Feature',
 
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',
 
4511
    ]:
 
4512
    globals()[name] = _CompatabilityThunkFeature(
 
4513
        symbol_versioning.deprecated_in((2, 5, 0)),
 
4514
        'bzrlib.tests', name,
 
4515
        name, 'bzrlib.tests.features')
 
4516
 
 
4517
 
 
4518
for (old_name, new_name) in [
 
4519
    ('UnicodeFilename', 'UnicodeFilenameFeature'),
 
4520
    ]:
 
4521
    globals()[name] = _CompatabilityThunkFeature(
 
4522
        symbol_versioning.deprecated_in((2, 5, 0)),
 
4523
        'bzrlib.tests', old_name,
 
4524
        new_name, 'bzrlib.tests.features')