~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_import_tariff.py

  • Committer: John Arbash Meinel
  • Date: 2011-05-11 11:35:28 UTC
  • mto: This revision was merged to the branch mainline in revision 5851.
  • Revision ID: john@arbash-meinel.com-20110511113528-qepibuwxicjrbb2h
Break compatibility with python <2.6.

This includes auditing the code for places where we were doing
explicit 'sys.version' checks and removing them as appropriate.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2010 Canonical Ltd
 
1
# Copyright (C) 2010, 2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
17
17
 
18
18
"""Tests for how many modules are loaded in executing various commands."""
19
19
 
 
20
import os
20
21
from testtools import content
21
22
 
 
23
from bzrlib.bzrdir import BzrDir
 
24
from bzrlib.smart import medium
 
25
from bzrlib.transport import remote
 
26
 
22
27
from bzrlib.plugin import (
23
28
    are_plugins_disabled,
24
29
    )
27
32
    TestCaseWithTransport,
28
33
    )
29
34
 
 
35
old_format_modules = [
 
36
    'bzrlib.repofmt.knitrepo',
 
37
    'bzrlib.repofmt.knitpack_repo',
 
38
    'bzrlib.plugins.weave_fmt.branch',
 
39
    'bzrlib.plugins.weave_fmt.bzrdir',
 
40
    'bzrlib.plugins.weave_fmt.repository',
 
41
    'bzrlib.plugins.weave_fmt.workingtree',
 
42
    'bzrlib.weave',
 
43
    'bzrlib.weavefile',
 
44
    'bzrlib.xml4',
 
45
    'bzrlib.xml5',
 
46
    'bzrlib.xml6',
 
47
    'bzrlib.xml7',
 
48
    ]
 
49
 
30
50
 
31
51
class TestImportTariffs(TestCaseWithTransport):
32
 
 
33
52
    """Check how many modules are loaded for some representative scenarios.
34
53
 
35
54
    See the Testing Guide in the developer documentation for more explanation.
36
55
    """
37
56
 
38
 
    def run_command_check_imports(self, args, forbidden_imports):
39
 
        """Run bzr ARGS in a subprocess and check its imports.
 
57
    def setUp(self):
 
58
        # Preserve some env vars as we want to escape the isolation for them
 
59
        self.preserved_env_vars = {}
 
60
        for name in ('BZR_HOME', 'BZR_PLUGIN_PATH', 'BZR_DISABLE_PLUGINS',
 
61
                     'BZR_PLUGINS_AT', 'HOME'):
 
62
            self.preserved_env_vars[name] = os.environ.get(name)
 
63
        super(TestImportTariffs, self).setUp()
 
64
 
 
65
    def start_bzr_subprocess_with_import_check(self, args):
 
66
        """Run a bzr process and capture the imports.
40
67
 
41
68
        This is fairly expensive because we start a subprocess, so we aim to
42
69
        cover representative rather than exhaustive cases.
43
 
 
44
 
        :param forbidden_imports: List of fully-qualified Python module names
45
 
            that should not be loaded while running this command.
46
70
        """
47
71
        # We use PYTHON_VERBOSE rather than --profile-importts because in
48
72
        # experimentation the profile-imports output seems to not always show
50
74
        # more likely to always show everything.  And we use the environment
51
75
        # variable rather than 'python -v' in the hope it will work even if
52
76
        # bzr is frozen and python is not explicitly specified. -- mbp 20100208
53
 
        #
 
77
 
54
78
        # Normally we want test isolation from the real $HOME but here we
55
79
        # explicitly do want to test against things installed there, therefore
56
80
        # we pass it through.
57
 
        env_changes = dict(PYTHONVERBOSE='1')
58
 
        for name in ['BZR_HOME', 'BZR_PLUGIN_PATH',
59
 
                     'BZR_DISABLE_PLUGINS', 'BZR_PLUGINS_AT',
60
 
                     'HOME',]:
61
 
            env_changes[name] = self._old_env.get(name)
62
 
        out, err = self.run_bzr_subprocess(args,
63
 
            allow_plugins=(not are_plugins_disabled()),
64
 
            env_changes=env_changes)
65
 
 
 
81
        env_changes = dict(PYTHONVERBOSE='1', **self.preserved_env_vars)
 
82
        return self.start_bzr_subprocess(args, env_changes=env_changes,
 
83
            allow_plugins=(not are_plugins_disabled()))
 
84
 
 
85
    def check_forbidden_modules(self, err, forbidden_imports):
 
86
        """Check for forbidden modules in stderr.
 
87
 
 
88
        :param err: Standard error
 
89
        :param forbidden_imports: List of forbidden modules
 
90
        """
66
91
        self.addDetail('subprocess_stderr',
67
92
            content.Content(content.ContentType("text", "plain"),
68
93
                lambda:[err]))
73
98
                bad_modules.append(module_name)
74
99
 
75
100
        if bad_modules:
76
 
            self.fail("command %r loaded forbidden modules %r"
77
 
                % (args, bad_modules))
 
101
            self.fail("command loaded forbidden modules %r"
 
102
                % (bad_modules,))
 
103
 
 
104
    def finish_bzr_subprocess_with_import_check(self, process,
 
105
            args, forbidden_imports):
 
106
        """Finish subprocess and check specific modules have not been
 
107
        imported.
 
108
 
 
109
        :param forbidden_imports: List of fully-qualified Python module names
 
110
            that should not be loaded while running this command.
 
111
        """
 
112
        (out, err) = self.finish_bzr_subprocess(process,
 
113
            universal_newlines=False, process_args=args)
 
114
        self.check_forbidden_modules(err, forbidden_imports)
78
115
        return out, err
79
116
 
 
117
    def run_command_check_imports(self, args, forbidden_imports):
 
118
        """Run bzr ARGS in a subprocess and check its imports.
 
119
 
 
120
        This is fairly expensive because we start a subprocess, so we aim to
 
121
        cover representative rather than exhaustive cases.
 
122
 
 
123
        :param forbidden_imports: List of fully-qualified Python module names
 
124
            that should not be loaded while running this command.
 
125
        """
 
126
        process = self.start_bzr_subprocess_with_import_check(args)
 
127
        self.finish_bzr_subprocess_with_import_check(process, args,
 
128
            forbidden_imports)
 
129
 
80
130
    def test_import_tariffs_working(self):
81
131
        # check some guaranteed-true and false imports to be sure we're
82
132
        # measuring correctly
89
139
            ['bzrlib.tree'])
90
140
 
91
141
    def test_simple_local(self):
92
 
        # 'st' in a working tree shouldn't need many modules
 
142
        # 'st' in a default format working tree shouldn't need many modules
93
143
        self.make_branch_and_tree('.')
94
144
        self.run_command_check_imports(['st'], [
 
145
            'bzrlib.annotate',
 
146
            'bzrlib.atomicfile',
 
147
            'bzrlib.bugtracker',
95
148
            'bzrlib.bundle.commands',
96
149
            'bzrlib.cmd_version_info',
97
 
            'bzrlib.foreign',
 
150
            'bzrlib.externalcommand',
 
151
            'bzrlib.filters',
 
152
            # foreign branch plugins import the foreign_vcs_registry from 
 
153
            # bzrlib.foreign so it can't be blacklisted
 
154
            'bzrlib.gpg',
 
155
            'bzrlib.info',
 
156
            'bzrlib.knit',
98
157
            'bzrlib.merge3',
 
158
            'bzrlib.merge_directive',
 
159
            'bzrlib.msgeditor',
99
160
            'bzrlib.patiencediff',
100
161
            'bzrlib.remote',
 
162
            'bzrlib.rules',
101
163
            'bzrlib.sign_my_commits',
102
164
            'bzrlib.smart',
 
165
            'bzrlib.smart.client',
 
166
            'bzrlib.smart.medium',
 
167
            'bzrlib.smart.server',
103
168
            'bzrlib.transform',
 
169
            'bzrlib.version_info_formats.format_rio',
 
170
            'getpass',
104
171
            'kerberos',
105
172
            'smtplib',
106
173
            'tarfile',
107
 
            ])
 
174
            'tempfile',
 
175
            ] + old_format_modules)
108
176
        # TODO: similar test for repository-only operations, checking we avoid
109
177
        # loading wt-specific stuff
110
178
        #
111
179
        # See https://bugs.launchpad.net/bzr/+bug/553017
 
180
 
 
181
    def test_help_commands(self):
 
182
        # See https://bugs.launchpad.net/bzr/+bug/663773
 
183
        self.run_command_check_imports(['help', 'commands'], [
 
184
            'testtools',
 
185
            ])
 
186
 
 
187
    def test_simple_serve(self):
 
188
        # 'serve' in a default format working tree shouldn't need many modules
 
189
        tree = self.make_branch_and_tree('.')
 
190
        process = self.start_bzr_subprocess_with_import_check(['serve',
 
191
            '--inet', '-d', tree.basedir])
 
192
        url = 'bzr://localhost/'
 
193
        self.permit_url(url)
 
194
        client_medium = medium.SmartSimplePipesClientMedium(
 
195
            process.stdout, process.stdin, url)
 
196
        transport = remote.RemoteTransport(url, medium=client_medium)
 
197
        branch = BzrDir.open_from_transport(transport).open_branch()
 
198
        process.stdin.close()
 
199
        # Hide stdin from the subprocess module, so it won't fail to close it.
 
200
        process.stdin = None
 
201
        (out, err) = self.finish_bzr_subprocess(process,
 
202
            universal_newlines=False)
 
203
        self.check_forbidden_modules(err,
 
204
            ['bzrlib.annotate',
 
205
            'bzrlib.atomicfile',
 
206
            'bzrlib.bugtracker',
 
207
            'bzrlib.bundle.commands',
 
208
            'bzrlib.cmd_version_info',
 
209
            'bzrlib.dirstate',
 
210
            'bzrlib._dirstate_helpers_py',
 
211
            'bzrlib._dirstate_helpers_pyx',
 
212
            'bzrlib.externalcommand',
 
213
            'bzrlib.filters',
 
214
            # foreign branch plugins import the foreign_vcs_registry from 
 
215
            # bzrlib.foreign so it can't be blacklisted
 
216
            'bzrlib.gpg',
 
217
            'bzrlib.info',
 
218
            'bzrlib.knit',
 
219
            'bzrlib.merge3',
 
220
            'bzrlib.merge_directive',
 
221
            'bzrlib.msgeditor',
 
222
            'bzrlib.patiencediff',
 
223
            'bzrlib.remote',
 
224
            'bzrlib.rules',
 
225
            'bzrlib.sign_my_commits',
 
226
            'bzrlib.smart.client',
 
227
            'bzrlib.transform',
 
228
            'bzrlib.version_info_formats.format_rio',
 
229
            'bzrlib.workingtree_4',
 
230
            'getpass',
 
231
            'kerberos',
 
232
            'smtplib',
 
233
            'tarfile',
 
234
            'tempfile',
 
235
            ] + old_format_modules)