~bzr-pqm/bzr/bzr.dev

5557.1.7 by John Arbash Meinel
Merge in the bzr.dev 5582
1
# Copyright (C) 2010, 2011 Canonical Ltd
5017.2.2 by Martin Pool
Add import tariff tests
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17
18
"""Tests for how many modules are loaded in executing various commands."""
19
5939.3.2 by Andrew Bennetts
Take a slightly more direct approach by largely preserving BZR_DISABLE_PLUGINS/BZR_PLUGINS_AT.
20
import os
21
5017.2.2 by Martin Pool
Add import tariff tests
22
from testtools import content
23
5935.1.1 by Vincent Ladeuil
Preserve $HOME/.bzr.log from tests
24
from bzrlib import (
5939.3.2 by Andrew Bennetts
Take a slightly more direct approach by largely preserving BZR_DISABLE_PLUGINS/BZR_PLUGINS_AT.
25
    plugins as _mod_plugins,
5935.1.1 by Vincent Ladeuil
Preserve $HOME/.bzr.log from tests
26
    trace,
27
    )
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
28
from bzrlib.controldir import ControlDir
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
29
from bzrlib.smart import medium
30
from bzrlib.transport import remote
31
5017.2.2 by Martin Pool
Add import tariff tests
32
from bzrlib.plugin import (
33
    are_plugins_disabled,
34
    )
35
36
from bzrlib.tests import (
37
    TestCaseWithTransport,
38
    )
39
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
40
old_format_modules = [
41
    'bzrlib.repofmt.knitrepo',
42
    'bzrlib.repofmt.knitpack_repo',
43
    'bzrlib.plugins.weave_fmt.branch',
44
    'bzrlib.plugins.weave_fmt.bzrdir',
45
    'bzrlib.plugins.weave_fmt.repository',
46
    'bzrlib.plugins.weave_fmt.workingtree',
47
    'bzrlib.weave',
48
    'bzrlib.weavefile',
49
    'bzrlib.xml4',
50
    'bzrlib.xml5',
51
    'bzrlib.xml6',
52
    'bzrlib.xml7',
53
    ]
54
5017.2.2 by Martin Pool
Add import tariff tests
55
5956.1.1 by Jelmer Vernooij
Add ImportTariffTestCase.
56
class ImportTariffTestCase(TestCaseWithTransport):
5956.1.2 by Jelmer Vernooij
Review feedback from Vincent.
57
    """Check how many modules are loaded for some representative scenarios.
58
59
    See the Testing Guide in the developer documentation for more explanation.
60
61
62
    We must respect the setup used by the selftest command regarding
63
    plugins. This allows the user to control which plugins are in effect while
64
    running these tests and respect the import policies defined here.
65
66
    When failures are encountered for a given plugin, they can generally be
67
    addressed by using lazy import or lazy hook registration.
68
    """
5017.2.2 by Martin Pool
Add import tariff tests
69
5939.3.2 by Andrew Bennetts
Take a slightly more direct approach by largely preserving BZR_DISABLE_PLUGINS/BZR_PLUGINS_AT.
70
    def setUp(self):
71
        self.preserved_env_vars = {}
5939.3.4 by Vincent Ladeuil
Even better to not rely on an implementation detail.
72
        for name in ('BZR_PLUGIN_PATH', 'BZR_DISABLE_PLUGINS', 'BZR_PLUGINS_AT'
73
                     ):
5939.3.2 by Andrew Bennetts
Take a slightly more direct approach by largely preserving BZR_DISABLE_PLUGINS/BZR_PLUGINS_AT.
74
            self.preserved_env_vars[name] = os.environ.get(name)
5956.1.1 by Jelmer Vernooij
Add ImportTariffTestCase.
75
        super(ImportTariffTestCase, self).setUp()
5939.3.2 by Andrew Bennetts
Take a slightly more direct approach by largely preserving BZR_DISABLE_PLUGINS/BZR_PLUGINS_AT.
76
5898.2.1 by Andrew Bennetts
Fix deadlock in TestImportTariffs.test_simple_serve.
77
    def start_bzr_subprocess_with_import_check(self, args, stderr_file=None):
5816.1.2 by Jelmer Vernooij
Factor out start_bzr_subprocess_with_import_check
78
        """Run a bzr process and capture the imports.
5018.1.8 by Martin Pool
doc
79
80
        This is fairly expensive because we start a subprocess, so we aim to
81
        cover representative rather than exhaustive cases.
82
        """
5939.3.1 by Andrew Bennetts
Don't use real /home/andrew in test_import_tariffs. We can test the real plugins and be properly isolated from the user's config and log.
83
        # We use PYTHON_VERBOSE rather than --profile-imports because in
5017.2.2 by Martin Pool
Add import tariff tests
84
        # experimentation the profile-imports output seems to not always show
85
        # the modules you'd expect; this can be debugged but python -v seems
86
        # more likely to always show everything.  And we use the environment
87
        # variable rather than 'python -v' in the hope it will work even if
88
        # bzr is frozen and python is not explicitly specified. -- mbp 20100208
5939.3.4 by Vincent Ladeuil
Even better to not rely on an implementation detail.
89
        env_changes = dict(PYTHONVERBOSE='1', **self.preserved_env_vars)
5939.3.1 by Andrew Bennetts
Don't use real /home/andrew in test_import_tariffs. We can test the real plugins and be properly isolated from the user's config and log.
90
        trace.mutter('Setting env for bzr subprocess: %r', env_changes)
5898.2.6 by Vincent Ladeuil
The missing bit ! stderr_file needs to be propagated with care down to Popen or we either don't use it or override useful default values.
91
        kwargs = dict(env_changes=env_changes,
92
                      allow_plugins=(not are_plugins_disabled()))
93
        if stderr_file:
94
            # We don't want to update the whole call chain so we insert stderr
95
            # *iff* we need to
96
            kwargs['stderr'] = stderr_file
97
        return self.start_bzr_subprocess(args, **kwargs)
5816.1.2 by Jelmer Vernooij
Factor out start_bzr_subprocess_with_import_check
98
5816.1.3 by Jelmer Vernooij
Split up tariff functions.
99
    def check_forbidden_modules(self, err, forbidden_imports):
100
        """Check for forbidden modules in stderr.
101
102
        :param err: Standard error
103
        :param forbidden_imports: List of forbidden modules
5816.1.2 by Jelmer Vernooij
Factor out start_bzr_subprocess_with_import_check
104
        """
5304.1.1 by Vincent Ladeuil
Pass BZR_PLUGINS_AT and BZR_DISABLE_PLINGS to the subprocess fpr test_import_tariff
105
        self.addDetail('subprocess_stderr',
5017.2.2 by Martin Pool
Add import tariff tests
106
            content.Content(content.ContentType("text", "plain"),
107
                lambda:[err]))
108
109
        bad_modules = []
110
        for module_name in forbidden_imports:
111
            if err.find("\nimport %s " % module_name) != -1:
112
                bad_modules.append(module_name)
113
114
        if bad_modules:
5816.1.3 by Jelmer Vernooij
Split up tariff functions.
115
            self.fail("command loaded forbidden modules %r"
116
                % (bad_modules,))
117
118
    def finish_bzr_subprocess_with_import_check(self, process,
119
            args, forbidden_imports):
120
        """Finish subprocess and check specific modules have not been
121
        imported.
122
123
        :param forbidden_imports: List of fully-qualified Python module names
124
            that should not be loaded while running this command.
125
        """
126
        (out, err) = self.finish_bzr_subprocess(process,
127
            universal_newlines=False, process_args=args)
128
        self.check_forbidden_modules(err, forbidden_imports)
5017.2.2 by Martin Pool
Add import tariff tests
129
        return out, err
130
5816.1.3 by Jelmer Vernooij
Split up tariff functions.
131
    def run_command_check_imports(self, args, forbidden_imports):
132
        """Run bzr ARGS in a subprocess and check its imports.
133
134
        This is fairly expensive because we start a subprocess, so we aim to
135
        cover representative rather than exhaustive cases.
136
137
        :param forbidden_imports: List of fully-qualified Python module names
138
            that should not be loaded while running this command.
139
        """
140
        process = self.start_bzr_subprocess_with_import_check(args)
141
        self.finish_bzr_subprocess_with_import_check(process, args,
142
            forbidden_imports)
143
5956.1.1 by Jelmer Vernooij
Add ImportTariffTestCase.
144
145
class TestImportTariffs(ImportTariffTestCase):
5956.1.2 by Jelmer Vernooij
Review feedback from Vincent.
146
    """Basic import tariff tests for some common bzr commands"""
5956.1.1 by Jelmer Vernooij
Add ImportTariffTestCase.
147
5017.2.2 by Martin Pool
Add import tariff tests
148
    def test_import_tariffs_working(self):
149
        # check some guaranteed-true and false imports to be sure we're
150
        # measuring correctly
151
        self.make_branch_and_tree('.')
152
        self.run_command_check_imports(['st'],
153
            ['nonexistentmodulename', 'anothernonexistentmodule'])
154
        self.assertRaises(AssertionError,
155
            self.run_command_check_imports,
156
            ['st'],
157
            ['bzrlib.tree'])
158
159
    def test_simple_local(self):
5698.1.1 by Jelmer Vernooij
Add bzrlib.workingtree_2 to the list of forbidden modules for 'bzr st' in a 2a tree.
160
        # 'st' in a default format working tree shouldn't need many modules
5017.2.2 by Martin Pool
Add import tariff tests
161
        self.make_branch_and_tree('.')
5017.2.4 by Martin Pool
Move or remove some unconditionally loaded code
162
        self.run_command_check_imports(['st'], [
5757.8.2 by Jelmer Vernooij
Avoid annotate import during 'bzr st'.
163
            'bzrlib.annotate',
5745.2.2 by Jelmer Vernooij
Add atomicfile to test import tariff blacklist.
164
            'bzrlib.atomicfile',
5671.2.1 by Jelmer Vernooij
Add some more forbidden imports to the import tariff test.
165
            'bzrlib.bugtracker',
5018.1.11 by Martin Pool
Check bundle commands are not loaded for 'bzr st' invocation
166
            'bzrlib.bundle.commands',
5127.1.1 by Martin Pool
version-info is lazily loaded
167
            'bzrlib.cmd_version_info',
5671.2.2 by Jelmer Vernooij
Remove unused serializer class.
168
            'bzrlib.externalcommand',
5745.3.2 by Jelmer Vernooij
Add filters to import tariff blacklist.
169
            'bzrlib.filters',
6110.4.3 by Jelmer Vernooij
Forbid bzrlib.hashcache in normal usage.
170
            'bzrlib.hashcache',
5749.1.1 by Jelmer Vernooij
Remove bzrlib.foreign from the test_import_tariff blacklist.
171
            # foreign branch plugins import the foreign_vcs_registry from 
172
            # bzrlib.foreign so it can't be blacklisted
5671.2.1 by Jelmer Vernooij
Add some more forbidden imports to the import tariff test.
173
            'bzrlib.gpg',
174
            'bzrlib.info',
5757.8.1 by Jelmer Vernooij
Avoid bzrlib.knit imports when using groupcompress repositories.
175
            'bzrlib.knit',
5279.1.1 by Andrew Bennetts
lazy_import most things in merge.py; add a few representative modules to the import tariff tests; tweak a couple of other modules so that patiencediff is not necessarily imported; remove a bunch of unused imports from test_knit.py.
176
            'bzrlib.merge3',
5671.2.1 by Jelmer Vernooij
Add some more forbidden imports to the import tariff test.
177
            'bzrlib.merge_directive',
178
            'bzrlib.msgeditor',
5279.1.1 by Andrew Bennetts
lazy_import most things in merge.py; add a few representative modules to the import tariff tests; tweak a couple of other modules so that patiencediff is not necessarily imported; remove a bunch of unused imports from test_knit.py.
179
            'bzrlib.patiencediff',
5017.2.4 by Martin Pool
Move or remove some unconditionally loaded code
180
            'bzrlib.remote',
5745.3.3 by Jelmer Vernooij
Add rules to blacklist.
181
            'bzrlib.rules',
5127.1.4 by Martin Pool
Lazy-load sign-my-commits
182
            'bzrlib.sign_my_commits',
5017.2.4 by Martin Pool
Move or remove some unconditionally loaded code
183
            'bzrlib.smart',
5712.3.15 by Jelmer Vernooij
Remove unused register format functions.
184
            'bzrlib.smart.client',
5757.8.5 by Jelmer Vernooij
Add smart medium/server to the blacklist.
185
            'bzrlib.smart.medium',
186
            'bzrlib.smart.server',
5279.1.1 by Andrew Bennetts
lazy_import most things in merge.py; add a few representative modules to the import tariff tests; tweak a couple of other modules so that patiencediff is not necessarily imported; remove a bunch of unused imports from test_knit.py.
187
            'bzrlib.transform',
5671.2.1 by Jelmer Vernooij
Add some more forbidden imports to the import tariff test.
188
            'bzrlib.version_info_formats.format_rio',
6355.1.4 by Jelmer Vernooij
Fix import tariff tests.
189
            'bzrlib.xml_serializer',
190
            'bzrlib.xml8',
5753.2.2 by Jelmer Vernooij
Remove some unnecessary imports, clean up lazy imports.
191
            'getpass',
5271.1.1 by Martin Pool
Test that Kerberos is no longer loaded.
192
            'kerberos',
6379.4.1 by Jelmer Vernooij
add test for importing ssl/socket.
193
            'ssl',
194
            'socket',
5017.2.4 by Martin Pool
Move or remove some unconditionally loaded code
195
            'smtplib',
196
            'tarfile',
5753.2.2 by Jelmer Vernooij
Remove some unnecessary imports, clean up lazy imports.
197
            'tempfile',
6379.1.1 by Jelmer Vernooij
Avoid importing tty and termios if we don't have to.
198
            'termios',
199
            'tty',
6379.4.3 by Jelmer Vernooij
Check for urllib in tariff test.
200
            'urllib',
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
201
            ] + old_format_modules)
5127.1.2 by Martin Pool
Lazy-load conflict commands
202
        # TODO: similar test for repository-only operations, checking we avoid
203
        # loading wt-specific stuff
204
        #
5243.1.2 by Martin
Point launchpad links in comments at production server rather than edge
205
        # See https://bugs.launchpad.net/bzr/+bug/553017
5510.1.1 by Martin von Gagern
Ensure 'bzr help commands' doesn't import testtools.
206
207
    def test_help_commands(self):
208
        # See https://bugs.launchpad.net/bzr/+bug/663773
209
        self.run_command_check_imports(['help', 'commands'], [
210
            'testtools',
211
            ])
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
212
213
    def test_simple_serve(self):
214
        # 'serve' in a default format working tree shouldn't need many modules
215
        tree = self.make_branch_and_tree('.')
5898.2.1 by Andrew Bennetts
Fix deadlock in TestImportTariffs.test_simple_serve.
216
        # Capture the bzr serve process' stderr in a file to avoid deadlocks
217
        # while the smart client interacts with it.
218
        stderr_file = open('bzr-serve.stderr', 'w')
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
219
        process = self.start_bzr_subprocess_with_import_check(['serve',
5898.2.1 by Andrew Bennetts
Fix deadlock in TestImportTariffs.test_simple_serve.
220
            '--inet', '-d', tree.basedir], stderr_file=stderr_file)
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
221
        url = 'bzr://localhost/'
222
        self.permit_url(url)
223
        client_medium = medium.SmartSimplePipesClientMedium(
224
            process.stdout, process.stdin, url)
225
        transport = remote.RemoteTransport(url, medium=client_medium)
6472.2.2 by Jelmer Vernooij
Use controldir rather than bzrdir in a couple more places.
226
        branch = ControlDir.open_from_transport(transport).open_branch()
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
227
        process.stdin.close()
228
        # Hide stdin from the subprocess module, so it won't fail to close it.
229
        process.stdin = None
230
        (out, err) = self.finish_bzr_subprocess(process,
231
            universal_newlines=False)
5898.2.1 by Andrew Bennetts
Fix deadlock in TestImportTariffs.test_simple_serve.
232
        stderr_file.close()
233
        with open('bzr-serve.stderr', 'r') as stderr_file:
234
            err = stderr_file.read()
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
235
        self.check_forbidden_modules(err,
236
            ['bzrlib.annotate',
237
            'bzrlib.atomicfile',
238
            'bzrlib.bugtracker',
239
            'bzrlib.bundle.commands',
240
            'bzrlib.cmd_version_info',
5816.3.2 by Jelmer Vernooij
Add workingtree4 and dirstate to the forbidden list.
241
            'bzrlib.dirstate',
5816.3.3 by Jelmer Vernooij
Add tariff test to make sure working tree isn't opened by 'bzr serve'
242
            'bzrlib._dirstate_helpers_py',
243
            'bzrlib._dirstate_helpers_pyx',
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
244
            'bzrlib.externalcommand',
245
            'bzrlib.filters',
6110.4.3 by Jelmer Vernooij
Forbid bzrlib.hashcache in normal usage.
246
            'bzrlib.hashcache',
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
247
            # foreign branch plugins import the foreign_vcs_registry from 
248
            # bzrlib.foreign so it can't be blacklisted
249
            'bzrlib.gpg',
250
            'bzrlib.info',
251
            'bzrlib.knit',
252
            'bzrlib.merge3',
253
            'bzrlib.merge_directive',
254
            'bzrlib.msgeditor',
255
            'bzrlib.patiencediff',
256
            'bzrlib.remote',
257
            'bzrlib.rules',
258
            'bzrlib.sign_my_commits',
259
            'bzrlib.smart.client',
260
            'bzrlib.transform',
261
            'bzrlib.version_info_formats.format_rio',
5816.3.2 by Jelmer Vernooij
Add workingtree4 and dirstate to the forbidden list.
262
            'bzrlib.workingtree_4',
6355.1.4 by Jelmer Vernooij
Fix import tariff tests.
263
            'bzrlib.xml_serializer',
264
            'bzrlib.xml8',
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
265
            'getpass',
266
            'kerberos',
267
            'smtplib',
268
            'tarfile',
269
            'tempfile',
6379.1.1 by Jelmer Vernooij
Avoid importing tty and termios if we don't have to.
270
            'termios',
271
            'tty',
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
272
            ] + old_format_modules)