~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

  • Committer: Patch Queue Manager
  • Date: 2014-04-09 13:36:25 UTC
  • mfrom: (6592.1.2 1303879-py27-issues)
  • Revision ID: pqm@pqm.ubuntu.com-20140409133625-s24spv3kha2w2860
(vila) Fix python-2.7.6 test failures. (Vincent Ladeuil)

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
57
60
import bzrlib
58
61
from bzrlib import (
59
62
    branchbuilder,
60
 
    bzrdir,
 
63
    controldir,
61
64
    chk_map,
62
65
    commands as _mod_commands,
63
66
    config,
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
132
137
isolated_environ = {
133
138
    'BZR_HOME': None,
134
139
    'HOME': None,
 
140
    'XDG_CONFIG_HOME': None,
135
141
    # bzr now uses the Win32 API and doesn't rely on APPDATA, but the
136
142
    # tests do check our impls match APPDATA
137
143
    'BZR_EDITOR': None, # test_msgeditor manipulates this variable
242
248
    different types of display.
243
249
 
244
250
    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
 
251
    addFailure or addError methods.  These in turn may redirect to a more
246
252
    specific case for the special test results supported by our extended
247
253
    tests.
248
254
 
994
1000
 
995
1001
    def setUp(self):
996
1002
        super(TestCase, self).setUp()
 
1003
 
 
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')
 
1007
        if timeout:
 
1008
            timeout_fixture = fixtures.TimeoutFixture(timeout)
 
1009
            timeout_fixture.setUp()
 
1010
            self.addCleanup(timeout_fixture.cleanUp)
 
1011
 
997
1012
        for feature in getattr(self, '_test_needs_features', []):
998
1013
            self.requireFeature(feature)
999
1014
        self._cleanEnvironment()
 
1015
 
1000
1016
        if bzrlib.global_state is not None:
1001
1017
            self.overrideAttr(bzrlib.global_state, 'cmdline_overrides',
1002
 
                              config.CommandLineSection())
 
1018
                              config.CommandLineStore())
 
1019
 
1003
1020
        self._silenceUI()
1004
1021
        self._startLogFile()
1005
1022
        self._benchcalls = []
1012
1029
        # between tests.  We should get rid of this altogether: bug 656694. --
1013
1030
        # mbp 20101008
1014
1031
        self.overrideAttr(bzrlib.trace, '_verbosity_level', 0)
1015
 
        # Isolate config option expansion until its default value for bzrlib is
1016
 
        # settled on or a the FIXME associated with _get_expand_default_value
1017
 
        # is addressed -- vila 20110219
1018
 
        self.overrideAttr(config, '_expand_default_value', None)
1019
1032
        self._log_files = set()
1020
1033
        # Each key in the ``_counters`` dict holds a value for a different
1021
1034
        # counter. When the test ends, addDetail() should be used to output the
1314
1327
        # hook into bzr dir opening. This leaves a small window of error for
1315
1328
        # transport tests, but they are well known, and we can improve on this
1316
1329
        # step.
1317
 
        bzrdir.BzrDir.hooks.install_named_hook("pre_open",
 
1330
        controldir.ControlDir.hooks.install_named_hook("pre_open",
1318
1331
            self._preopen_isolate_transport, "Check bzr directories are safe.")
1319
1332
 
1320
1333
    def _ndiff_strings(self, a, b):
1718
1731
        return result
1719
1732
 
1720
1733
    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
 
        """
 
1734
        """Setup a in-memory target for bzr and testcase log messages"""
1725
1735
        pseudo_log_file = StringIO()
1726
1736
        def _get_log_contents_for_weird_testtools_api():
1727
1737
            return [pseudo_log_file.getvalue().decode(
1734
1744
        self.addCleanup(self._finishLogFile)
1735
1745
 
1736
1746
    def _finishLogFile(self):
1737
 
        """Finished with the log file.
1738
 
 
1739
 
        Close the file and delete it.
1740
 
        """
 
1747
        """Flush and dereference the in-memory log for this testcase"""
1741
1748
        if trace._trace_file:
1742
1749
            # flush the log file, to get all content
1743
1750
            trace._trace_file.flush()
1744
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
1745
1754
 
1746
1755
    def thisFailsStrictLockCheck(self):
1747
1756
        """It is known that this test would fail with -Dstrict_locks.
1771
1780
 
1772
1781
        :returns: The actual attr value.
1773
1782
        """
1774
 
        value = getattr(obj, attr_name)
1775
1783
        # The actual value is captured by the call below
1776
 
        self.addCleanup(setattr, obj, attr_name, value)
 
1784
        value = getattr(obj, attr_name, _unitialized_attr)
 
1785
        if value is _unitialized_attr:
 
1786
            # When the test completes, the attribute should not exist, but if
 
1787
            # we aren't setting a value, we don't need to do anything.
 
1788
            if new is not _unitialized_attr:
 
1789
                self.addCleanup(delattr, obj, attr_name)
 
1790
        else:
 
1791
            self.addCleanup(setattr, obj, attr_name, value)
1777
1792
        if new is not _unitialized_attr:
1778
1793
            setattr(obj, attr_name, new)
1779
1794
        return value
1982
1997
 
1983
1998
        self.log('run bzr: %r', args)
1984
1999
        # FIXME: don't call into logging here
1985
 
        handler = logging.StreamHandler(stderr)
1986
 
        handler.setLevel(logging.INFO)
 
2000
        handler = trace.EncodedStreamHandler(stderr, errors="replace",
 
2001
            level=logging.INFO)
1987
2002
        logger = logging.getLogger('')
1988
2003
        logger.addHandler(handler)
1989
2004
        old_ui_factory = ui.ui_factory
2177
2192
 
2178
2193
        if env_changes is None:
2179
2194
            env_changes = {}
 
2195
        # Because $HOME is set to a tempdir for the context of a test, modules
 
2196
        # installed in the user dir will not be found unless $PYTHONUSERBASE
 
2197
        # gets set to the computed directory of this parent process.
 
2198
        if site.USER_BASE is not None:
 
2199
            env_changes["PYTHONUSERBASE"] = site.USER_BASE
2180
2200
        old_env = {}
2181
2201
 
2182
2202
        def cleanup_environment():
2373
2393
        from bzrlib.smart import request
2374
2394
        request_handlers = request.request_handlers
2375
2395
        orig_method = request_handlers.get(verb)
 
2396
        orig_info = request_handlers.get_info(verb)
2376
2397
        request_handlers.remove(verb)
2377
 
        self.addCleanup(request_handlers.register, verb, orig_method)
 
2398
        self.addCleanup(request_handlers.register, verb, orig_method,
 
2399
            info=orig_info)
2378
2400
 
2379
2401
 
2380
2402
class CapturedCall(object):
2433
2455
        self.transport_readonly_server = None
2434
2456
        self.__vfs_server = None
2435
2457
 
 
2458
    def setUp(self):
 
2459
        super(TestCaseWithMemoryTransport, self).setUp()
 
2460
 
 
2461
        def _add_disconnect_cleanup(transport):
 
2462
            """Schedule disconnection of given transport at test cleanup
 
2463
 
 
2464
            This needs to happen for all connected transports or leaks occur.
 
2465
 
 
2466
            Note reconnections may mean we call disconnect multiple times per
 
2467
            transport which is suboptimal but seems harmless.
 
2468
            """
 
2469
            self.addCleanup(transport.disconnect)
 
2470
 
 
2471
        _mod_transport.Transport.hooks.install_named_hook('post_connect',
 
2472
            _add_disconnect_cleanup, None)
 
2473
 
 
2474
        self._make_test_root()
 
2475
        self.addCleanup(os.chdir, os.getcwdu())
 
2476
        self.makeAndChdirToTestDir()
 
2477
        self.overrideEnvironmentForTesting()
 
2478
        self.__readonly_server = None
 
2479
        self.__server = None
 
2480
        self.reduceLockdirTimeout()
 
2481
        # Each test may use its own config files even if the local config files
 
2482
        # don't actually exist. They'll rightly fail if they try to create them
 
2483
        # though.
 
2484
        self.overrideAttr(config, '_shared_stores', {})
 
2485
 
2436
2486
    def get_transport(self, relpath=None):
2437
2487
        """Return a writeable transport.
2438
2488
 
2581
2631
        real branch.
2582
2632
        """
2583
2633
        root = TestCaseWithMemoryTransport.TEST_ROOT
2584
 
        # Make sure we get a readable and accessible home for .bzr.log
2585
 
        # and/or config files, and not fallback to weird defaults (see
2586
 
        # http://pad.lv/825027).
2587
 
        self.assertIs(None, os.environ.get('BZR_HOME', None))
2588
 
        os.environ['BZR_HOME'] = root
2589
 
        wt = bzrdir.BzrDir.create_standalone_workingtree(root)
2590
 
        del os.environ['BZR_HOME']
 
2634
        try:
 
2635
            # Make sure we get a readable and accessible home for .bzr.log
 
2636
            # and/or config files, and not fallback to weird defaults (see
 
2637
            # http://pad.lv/825027).
 
2638
            self.assertIs(None, os.environ.get('BZR_HOME', None))
 
2639
            os.environ['BZR_HOME'] = root
 
2640
            wt = controldir.ControlDir.create_standalone_workingtree(root)
 
2641
            del os.environ['BZR_HOME']
 
2642
        except Exception, e:
 
2643
            self.fail("Fail to initialize the safety net: %r\n" % (e,))
2591
2644
        # Hack for speed: remember the raw bytes of the dirstate file so that
2592
2645
        # we don't need to re-open the wt to check it hasn't changed.
2593
2646
        TestCaseWithMemoryTransport._SAFETY_NET_PRISTINE_DIRSTATE = (
2641
2694
        self.test_home_dir = self.test_dir + "/MemoryTransportMissingHomeDir"
2642
2695
        self.permit_dir(self.test_dir)
2643
2696
 
2644
 
    def make_branch(self, relpath, format=None):
 
2697
    def make_branch(self, relpath, format=None, name=None):
2645
2698
        """Create a branch on the transport at relpath."""
2646
2699
        repo = self.make_repository(relpath, format=format)
2647
 
        return repo.bzrdir.create_branch(append_revisions_only=False)
 
2700
        return repo.bzrdir.create_branch(append_revisions_only=False,
 
2701
                                         name=name)
2648
2702
 
2649
2703
    def get_default_format(self):
2650
2704
        return 'default'
2662
2716
        if format is None:
2663
2717
            format = self.get_default_format()
2664
2718
        if isinstance(format, basestring):
2665
 
            format = bzrdir.format_registry.make_bzrdir(format)
 
2719
            format = controldir.format_registry.make_bzrdir(format)
2666
2720
        return format
2667
2721
 
2668
2722
    def make_bzrdir(self, relpath, format=None):
2715
2769
        self.overrideEnv('HOME', test_home_dir)
2716
2770
        self.overrideEnv('BZR_HOME', test_home_dir)
2717
2771
 
2718
 
    def setUp(self):
2719
 
        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)
2730
 
        self._make_test_root()
2731
 
        self.addCleanup(os.chdir, os.getcwdu())
2732
 
        self.makeAndChdirToTestDir()
2733
 
        self.overrideEnvironmentForTesting()
2734
 
        self.__readonly_server = None
2735
 
        self.__server = None
2736
 
        self.reduceLockdirTimeout()
2737
 
 
2738
2772
    def setup_smart_server_with_call_log(self):
2739
2773
        """Sets up a smart server as the transport server with a call log."""
2740
2774
        self.transport_server = test_server.SmartTCPServer_for_testing
 
2775
        self.hpss_connections = []
2741
2776
        self.hpss_calls = []
2742
2777
        import traceback
2743
2778
        # Skip the current stack down to the caller of
2746
2781
        def capture_hpss_call(params):
2747
2782
            self.hpss_calls.append(
2748
2783
                CapturedCall(params, prefix_length))
 
2784
        def capture_connect(transport):
 
2785
            self.hpss_connections.append(transport)
2749
2786
        client._SmartClient.hooks.install_named_hook(
2750
2787
            'call', capture_hpss_call, None)
 
2788
        _mod_transport.Transport.hooks.install_named_hook(
 
2789
            'post_connect', capture_connect, None)
2751
2790
 
2752
2791
    def reset_smart_call_log(self):
2753
2792
        self.hpss_calls = []
 
2793
        self.hpss_connections = []
2754
2794
 
2755
2795
 
2756
2796
class TestCaseInTempDir(TestCaseWithMemoryTransport):
2826
2866
        # stacking policy to honour; create a bzr dir with an unshared
2827
2867
        # repository (but not a branch - our code would be trying to escape
2828
2868
        # then!) to stop them, and permit it to be read.
2829
 
        # control = bzrdir.BzrDir.create(self.test_base_dir)
 
2869
        # control = controldir.ControlDir.create(self.test_base_dir)
2830
2870
        # control.create_repository()
2831
2871
        self.test_home_dir = self.test_base_dir + '/home'
2832
2872
        os.mkdir(self.test_home_dir)
2921
2961
    readwrite one must both define get_url() as resolving to os.getcwd().
2922
2962
    """
2923
2963
 
 
2964
    def setUp(self):
 
2965
        super(TestCaseWithTransport, self).setUp()
 
2966
        self.__vfs_server = None
 
2967
 
2924
2968
    def get_vfs_only_server(self):
2925
2969
        """See TestCaseWithMemoryTransport.
2926
2970
 
2972
3016
            if self.vfs_transport_factory is test_server.LocalURLServer:
2973
3017
                # the branch is colocated on disk, we cannot create a checkout.
2974
3018
                # hopefully callers will expect this.
2975
 
                local_controldir= bzrdir.BzrDir.open(self.get_vfs_only_url(relpath))
 
3019
                local_controldir = controldir.ControlDir.open(
 
3020
                    self.get_vfs_only_url(relpath))
2976
3021
                wt = local_controldir.create_workingtree()
2977
3022
                if wt.branch._format != b._format:
2978
3023
                    wt._branch = b
3008
3053
        self.assertFalse(differences.has_changed(),
3009
3054
            "Trees %r and %r are different: %r" % (left, right, differences))
3010
3055
 
3011
 
    def setUp(self):
3012
 
        super(TestCaseWithTransport, self).setUp()
3013
 
        self.__vfs_server = None
3014
 
 
3015
3056
    def disable_missing_extensions_warning(self):
3016
3057
        """Some tests expect a precise stderr content.
3017
3058
 
3018
3059
        There is no point in forcing them to duplicate the extension related
3019
3060
        warning.
3020
3061
        """
3021
 
        config.GlobalConfig().set_user_option('ignore_missing_extensions', True)
 
3062
        config.GlobalStack().set('ignore_missing_extensions', True)
3022
3063
 
3023
3064
 
3024
3065
class ChrootedTestCase(TestCaseWithTransport):
3492
3533
            try:
3493
3534
                ProtocolTestCase.run(self, result)
3494
3535
            finally:
3495
 
                os.waitpid(self.pid, 0)
 
3536
                pid, status = os.waitpid(self.pid, 0)
 
3537
            # GZ 2011-10-18: If status is nonzero, should report to the result
 
3538
            #                that something went wrong.
3496
3539
 
3497
3540
    test_blocks = partition_tests(suite, concurrency)
3498
3541
    # Clear the tests from the original suite so it doesn't keep them alive
3504
3547
        c2pread, c2pwrite = os.pipe()
3505
3548
        pid = os.fork()
3506
3549
        if pid == 0:
3507
 
            workaround_zealous_crypto_random()
3508
3550
            try:
 
3551
                stream = os.fdopen(c2pwrite, 'wb', 1)
 
3552
                workaround_zealous_crypto_random()
3509
3553
                os.close(c2pread)
3510
3554
                # Leave stderr and stdout open so we can see test noise
3511
3555
                # Close stdin so that the child goes away if it decides to
3512
3556
                # read from stdin (otherwise its a roulette to see what
3513
3557
                # child actually gets keystrokes for pdb etc).
3514
3558
                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
3559
                subunit_result = AutoTimingTestResultDecorator(
3519
3560
                    SubUnitBzrProtocolClient(stream))
3520
3561
                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)
 
3562
            except:
 
3563
                # Try and report traceback on stream, but exit with error even
 
3564
                # if stream couldn't be created or something else goes wrong.
 
3565
                # The traceback is formatted to a string and written in one go
 
3566
                # to avoid interleaving lines from multiple failing children.
 
3567
                try:
 
3568
                    stream.write(traceback.format_exc())
 
3569
                finally:
 
3570
                    os._exit(1)
 
3571
            os._exit(0)
3525
3572
        else:
3526
3573
            os.close(c2pwrite)
3527
3574
            stream = os.fdopen(c2pread, 'rb', 1)
3745
3792
 
3746
3793
    :return: (absents, duplicates) absents is a list containing the test found
3747
3794
        in id_list but not in test_suite, duplicates is a list containing the
3748
 
        test found multiple times in test_suite.
 
3795
        tests found multiple times in test_suite.
3749
3796
 
3750
3797
    When using a prefined test id list, it may occurs that some tests do not
3751
3798
    exist anymore or that some tests use the same id. This function warns the
3875
3922
        'bzrlib.doc',
3876
3923
        'bzrlib.tests.blackbox',
3877
3924
        'bzrlib.tests.commands',
3878
 
        'bzrlib.tests.doc_generate',
3879
3925
        'bzrlib.tests.per_branch',
3880
3926
        'bzrlib.tests.per_bzrdir',
3881
3927
        'bzrlib.tests.per_controldir',
3969
4015
        'bzrlib.tests.test_http',
3970
4016
        'bzrlib.tests.test_http_response',
3971
4017
        'bzrlib.tests.test_https_ca_bundle',
 
4018
        'bzrlib.tests.test_https_urllib',
3972
4019
        'bzrlib.tests.test_i18n',
3973
4020
        'bzrlib.tests.test_identitymap',
3974
4021
        'bzrlib.tests.test_ignores',
4023
4070
        'bzrlib.tests.test_revisiontree',
4024
4071
        'bzrlib.tests.test_rio',
4025
4072
        'bzrlib.tests.test_rules',
 
4073
        'bzrlib.tests.test_url_policy_open',
4026
4074
        'bzrlib.tests.test_sampler',
4027
4075
        'bzrlib.tests.test_scenarios',
4028
4076
        'bzrlib.tests.test_script',
4072
4120
        'bzrlib.tests.test_version',
4073
4121
        'bzrlib.tests.test_version_info',
4074
4122
        'bzrlib.tests.test_versionedfile',
 
4123
        'bzrlib.tests.test_vf_search',
4075
4124
        'bzrlib.tests.test_weave',
4076
4125
        'bzrlib.tests.test_whitebox',
4077
4126
        'bzrlib.tests.test_win32utils',
4292
4341
    """Copy test and apply scenario to it.
4293
4342
 
4294
4343
    :param test: A test to adapt.
4295
 
    :param scenario: A tuple describing the scenarion.
 
4344
    :param scenario: A tuple describing the scenario.
4296
4345
        The first element of the tuple is the new test id.
4297
4346
        The second element is a dict containing attributes to set on the
4298
4347
        test.
4460
4509
    pass
4461
4510
 
4462
4511
 
4463
 
@deprecated_function(deprecated_in((2, 5, 0)))
4464
 
def ModuleAvailableFeature(name):
4465
 
    from bzrlib.tests import features
4466
 
    return features.ModuleAvailableFeature(name)
4467
 
    
 
4512
# API compatibility for old plugins; see bug 892622.
 
4513
for name in [
 
4514
    'Feature',
 
4515
    'HTTPServerFeature', 
 
4516
    'ModuleAvailableFeature',
 
4517
    'HTTPSServerFeature', 'SymlinkFeature', 'HardlinkFeature',
 
4518
    'OsFifoFeature', 'UnicodeFilenameFeature',
 
4519
    'ByteStringNamedFilesystem', 'UTF8Filesystem',
 
4520
    'BreakinFeature', 'CaseInsCasePresFilenameFeature',
 
4521
    'CaseInsensitiveFilesystemFeature', 'case_sensitive_filesystem_feature',
 
4522
    'posix_permissions_feature',
 
4523
    ]:
 
4524
    globals()[name] = _CompatabilityThunkFeature(
 
4525
        symbol_versioning.deprecated_in((2, 5, 0)),
 
4526
        'bzrlib.tests', name,
 
4527
        name, 'bzrlib.tests.features')
 
4528
 
 
4529
 
 
4530
for (old_name, new_name) in [
 
4531
    ('UnicodeFilename', 'UnicodeFilenameFeature'),
 
4532
    ]:
 
4533
    globals()[name] = _CompatabilityThunkFeature(
 
4534
        symbol_versioning.deprecated_in((2, 5, 0)),
 
4535
        'bzrlib.tests', old_name,
 
4536
        new_name, 'bzrlib.tests.features')