/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
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
5570.3.7 by Vincent Ladeuil
For test_import_tariff we want to preserve the env vars *before* isolation.
20
import os
5017.2.2 by Martin Pool
Add import tariff tests
21
from testtools import content
22
5935.1.1 by Vincent Ladeuil
Preserve $HOME/.bzr.log from tests
23
from bzrlib import (
24
    osutils,
25
    trace,
26
    )
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
27
from bzrlib.bzrdir import BzrDir
28
from bzrlib.smart import medium
29
from bzrlib.transport import remote
30
5017.2.2 by Martin Pool
Add import tariff tests
31
from bzrlib.plugin import (
32
    are_plugins_disabled,
33
    )
34
35
from bzrlib.tests import (
36
    TestCaseWithTransport,
37
    )
38
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
39
old_format_modules = [
40
    'bzrlib.repofmt.knitrepo',
41
    'bzrlib.repofmt.knitpack_repo',
42
    'bzrlib.plugins.weave_fmt.branch',
43
    'bzrlib.plugins.weave_fmt.bzrdir',
44
    'bzrlib.plugins.weave_fmt.repository',
45
    'bzrlib.plugins.weave_fmt.workingtree',
46
    'bzrlib.weave',
47
    'bzrlib.weavefile',
48
    'bzrlib.xml4',
49
    'bzrlib.xml5',
50
    'bzrlib.xml6',
51
    'bzrlib.xml7',
52
    ]
53
5017.2.2 by Martin Pool
Add import tariff tests
54
55
class TestImportTariffs(TestCaseWithTransport):
56
    """Check how many modules are loaded for some representative scenarios.
57
58
    See the Testing Guide in the developer documentation for more explanation.
5938.1.1 by Vincent Ladeuil
Better explain why tariff tests need to escape the test isolation jail.
59
60
61
    We must respect the setup used by the selftest command regarding
62
    plugins. This allows the user to control which plugins are in effect while
63
    running these tests and respect the import policies defined here.
64
65
    When failures are encountered for a given plugin, they can generally be
66
    addressed by using lazy import or lazy hook registration.
5017.2.2 by Martin Pool
Add import tariff tests
67
    """
68
5570.3.7 by Vincent Ladeuil
For test_import_tariff we want to preserve the env vars *before* isolation.
69
    def setUp(self):
70
        # Preserve some env vars as we want to escape the isolation for them
71
        self.preserved_env_vars = {}
72
        for name in ('BZR_HOME', 'BZR_PLUGIN_PATH', 'BZR_DISABLE_PLUGINS',
73
                     'BZR_PLUGINS_AT', 'HOME'):
74
            self.preserved_env_vars[name] = os.environ.get(name)
75
        super(TestImportTariffs, self).setUp()
5938.1.1 by Vincent Ladeuil
Better explain why tariff tests need to escape the test isolation jail.
76
        # We don't want to pollute the user's .bzr.log so we define our own.
5935.1.1 by Vincent Ladeuil
Preserve $HOME/.bzr.log from tests
77
        self.log_path = osutils.pathjoin(self.test_home_dir, '.bzr.log')
78
        self.overrideEnv('BZR_LOG', self.log_path)
79
80
    def test_log_path_overriden(self):
81
        # ensure we get the log file in the right place
82
        actual_log_path = trace._get_bzr_log_filename()
83
        self.assertStartsWith(actual_log_path, self.test_home_dir)
84
        self.assertEquals(self.log_path, actual_log_path)
85
5570.3.7 by Vincent Ladeuil
For test_import_tariff we want to preserve the env vars *before* isolation.
86
5898.2.1 by Andrew Bennetts
Fix deadlock in TestImportTariffs.test_simple_serve.
87
    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
88
        """Run a bzr process and capture the imports.
5018.1.8 by Martin Pool
doc
89
90
        This is fairly expensive because we start a subprocess, so we aim to
91
        cover representative rather than exhaustive cases.
92
        """
5017.2.2 by Martin Pool
Add import tariff tests
93
        # We use PYTHON_VERBOSE rather than --profile-importts because in
94
        # experimentation the profile-imports output seems to not always show
95
        # the modules you'd expect; this can be debugged but python -v seems
96
        # more likely to always show everything.  And we use the environment
97
        # variable rather than 'python -v' in the hope it will work even if
98
        # bzr is frozen and python is not explicitly specified. -- mbp 20100208
5570.3.7 by Vincent Ladeuil
For test_import_tariff we want to preserve the env vars *before* isolation.
99
5017.2.2 by Martin Pool
Add import tariff tests
100
        # Normally we want test isolation from the real $HOME but here we
101
        # explicitly do want to test against things installed there, therefore
102
        # we pass it through.
5570.3.7 by Vincent Ladeuil
For test_import_tariff we want to preserve the env vars *before* isolation.
103
        env_changes = dict(PYTHONVERBOSE='1', **self.preserved_env_vars)
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.
104
        kwargs = dict(env_changes=env_changes,
105
                      allow_plugins=(not are_plugins_disabled()))
106
        if stderr_file:
107
            # We don't want to update the whole call chain so we insert stderr
108
            # *iff* we need to
109
            kwargs['stderr'] = stderr_file
110
        return self.start_bzr_subprocess(args, **kwargs)
5816.1.2 by Jelmer Vernooij
Factor out start_bzr_subprocess_with_import_check
111
5816.1.3 by Jelmer Vernooij
Split up tariff functions.
112
    def check_forbidden_modules(self, err, forbidden_imports):
113
        """Check for forbidden modules in stderr.
114
115
        :param err: Standard error
116
        :param forbidden_imports: List of forbidden modules
5816.1.2 by Jelmer Vernooij
Factor out start_bzr_subprocess_with_import_check
117
        """
5304.1.1 by Vincent Ladeuil
Pass BZR_PLUGINS_AT and BZR_DISABLE_PLINGS to the subprocess fpr test_import_tariff
118
        self.addDetail('subprocess_stderr',
5017.2.2 by Martin Pool
Add import tariff tests
119
            content.Content(content.ContentType("text", "plain"),
120
                lambda:[err]))
121
122
        bad_modules = []
123
        for module_name in forbidden_imports:
124
            if err.find("\nimport %s " % module_name) != -1:
125
                bad_modules.append(module_name)
126
127
        if bad_modules:
5816.1.3 by Jelmer Vernooij
Split up tariff functions.
128
            self.fail("command loaded forbidden modules %r"
129
                % (bad_modules,))
130
131
    def finish_bzr_subprocess_with_import_check(self, process,
132
            args, forbidden_imports):
133
        """Finish subprocess and check specific modules have not been
134
        imported.
135
136
        :param forbidden_imports: List of fully-qualified Python module names
137
            that should not be loaded while running this command.
138
        """
139
        (out, err) = self.finish_bzr_subprocess(process,
140
            universal_newlines=False, process_args=args)
141
        self.check_forbidden_modules(err, forbidden_imports)
5017.2.2 by Martin Pool
Add import tariff tests
142
        return out, err
143
5816.1.3 by Jelmer Vernooij
Split up tariff functions.
144
    def run_command_check_imports(self, args, forbidden_imports):
145
        """Run bzr ARGS in a subprocess and check its imports.
146
147
        This is fairly expensive because we start a subprocess, so we aim to
148
        cover representative rather than exhaustive cases.
149
150
        :param forbidden_imports: List of fully-qualified Python module names
151
            that should not be loaded while running this command.
152
        """
153
        process = self.start_bzr_subprocess_with_import_check(args)
154
        self.finish_bzr_subprocess_with_import_check(process, args,
155
            forbidden_imports)
156
5017.2.2 by Martin Pool
Add import tariff tests
157
    def test_import_tariffs_working(self):
158
        # check some guaranteed-true and false imports to be sure we're
159
        # measuring correctly
160
        self.make_branch_and_tree('.')
161
        self.run_command_check_imports(['st'],
162
            ['nonexistentmodulename', 'anothernonexistentmodule'])
163
        self.assertRaises(AssertionError,
164
            self.run_command_check_imports,
165
            ['st'],
166
            ['bzrlib.tree'])
167
168
    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.
169
        # 'st' in a default format working tree shouldn't need many modules
5017.2.2 by Martin Pool
Add import tariff tests
170
        self.make_branch_and_tree('.')
5017.2.4 by Martin Pool
Move or remove some unconditionally loaded code
171
        self.run_command_check_imports(['st'], [
5757.8.2 by Jelmer Vernooij
Avoid annotate import during 'bzr st'.
172
            'bzrlib.annotate',
5745.2.2 by Jelmer Vernooij
Add atomicfile to test import tariff blacklist.
173
            'bzrlib.atomicfile',
5671.2.1 by Jelmer Vernooij
Add some more forbidden imports to the import tariff test.
174
            'bzrlib.bugtracker',
5018.1.11 by Martin Pool
Check bundle commands are not loaded for 'bzr st' invocation
175
            'bzrlib.bundle.commands',
5127.1.1 by Martin Pool
version-info is lazily loaded
176
            'bzrlib.cmd_version_info',
5671.2.2 by Jelmer Vernooij
Remove unused serializer class.
177
            'bzrlib.externalcommand',
5745.3.2 by Jelmer Vernooij
Add filters to import tariff blacklist.
178
            'bzrlib.filters',
5749.1.1 by Jelmer Vernooij
Remove bzrlib.foreign from the test_import_tariff blacklist.
179
            # foreign branch plugins import the foreign_vcs_registry from 
180
            # bzrlib.foreign so it can't be blacklisted
5671.2.1 by Jelmer Vernooij
Add some more forbidden imports to the import tariff test.
181
            'bzrlib.gpg',
182
            'bzrlib.info',
5757.8.1 by Jelmer Vernooij
Avoid bzrlib.knit imports when using groupcompress repositories.
183
            '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.
184
            'bzrlib.merge3',
5671.2.1 by Jelmer Vernooij
Add some more forbidden imports to the import tariff test.
185
            'bzrlib.merge_directive',
186
            '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.
187
            'bzrlib.patiencediff',
5017.2.4 by Martin Pool
Move or remove some unconditionally loaded code
188
            'bzrlib.remote',
5745.3.3 by Jelmer Vernooij
Add rules to blacklist.
189
            'bzrlib.rules',
5127.1.4 by Martin Pool
Lazy-load sign-my-commits
190
            'bzrlib.sign_my_commits',
5017.2.4 by Martin Pool
Move or remove some unconditionally loaded code
191
            'bzrlib.smart',
5712.3.15 by Jelmer Vernooij
Remove unused register format functions.
192
            'bzrlib.smart.client',
5757.8.5 by Jelmer Vernooij
Add smart medium/server to the blacklist.
193
            'bzrlib.smart.medium',
194
            '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.
195
            'bzrlib.transform',
5671.2.1 by Jelmer Vernooij
Add some more forbidden imports to the import tariff test.
196
            'bzrlib.version_info_formats.format_rio',
5753.2.2 by Jelmer Vernooij
Remove some unnecessary imports, clean up lazy imports.
197
            'getpass',
5271.1.1 by Martin Pool
Test that Kerberos is no longer loaded.
198
            'kerberos',
5017.2.4 by Martin Pool
Move or remove some unconditionally loaded code
199
            'smtplib',
200
            'tarfile',
5753.2.2 by Jelmer Vernooij
Remove some unnecessary imports, clean up lazy imports.
201
            'tempfile',
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
202
            ] + old_format_modules)
5127.1.2 by Martin Pool
Lazy-load conflict commands
203
        # TODO: similar test for repository-only operations, checking we avoid
204
        # loading wt-specific stuff
205
        #
5243.1.2 by Martin
Point launchpad links in comments at production server rather than edge
206
        # See https://bugs.launchpad.net/bzr/+bug/553017
5510.1.1 by Martin von Gagern
Ensure 'bzr help commands' doesn't import testtools.
207
208
    def test_help_commands(self):
209
        # See https://bugs.launchpad.net/bzr/+bug/663773
210
        self.run_command_check_imports(['help', 'commands'], [
211
            'testtools',
212
            ])
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
213
214
    def test_simple_serve(self):
215
        # 'serve' in a default format working tree shouldn't need many modules
216
        tree = self.make_branch_and_tree('.')
5898.2.1 by Andrew Bennetts
Fix deadlock in TestImportTariffs.test_simple_serve.
217
        # Capture the bzr serve process' stderr in a file to avoid deadlocks
218
        # while the smart client interacts with it.
219
        stderr_file = open('bzr-serve.stderr', 'w')
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
220
        process = self.start_bzr_subprocess_with_import_check(['serve',
5898.2.1 by Andrew Bennetts
Fix deadlock in TestImportTariffs.test_simple_serve.
221
            '--inet', '-d', tree.basedir], stderr_file=stderr_file)
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
222
        url = 'bzr://localhost/'
223
        self.permit_url(url)
224
        client_medium = medium.SmartSimplePipesClientMedium(
225
            process.stdout, process.stdin, url)
226
        transport = remote.RemoteTransport(url, medium=client_medium)
227
        branch = BzrDir.open_from_transport(transport).open_branch()
228
        process.stdin.close()
229
        # Hide stdin from the subprocess module, so it won't fail to close it.
230
        process.stdin = None
231
        (out, err) = self.finish_bzr_subprocess(process,
232
            universal_newlines=False)
5898.2.1 by Andrew Bennetts
Fix deadlock in TestImportTariffs.test_simple_serve.
233
        stderr_file.close()
234
        with open('bzr-serve.stderr', 'r') as stderr_file:
235
            err = stderr_file.read()
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
236
        self.check_forbidden_modules(err,
237
            ['bzrlib.annotate',
238
            'bzrlib.atomicfile',
239
            'bzrlib.bugtracker',
240
            'bzrlib.bundle.commands',
241
            'bzrlib.cmd_version_info',
5816.3.2 by Jelmer Vernooij
Add workingtree4 and dirstate to the forbidden list.
242
            'bzrlib.dirstate',
5816.3.3 by Jelmer Vernooij
Add tariff test to make sure working tree isn't opened by 'bzr serve'
243
            'bzrlib._dirstate_helpers_py',
244
            'bzrlib._dirstate_helpers_pyx',
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
245
            'bzrlib.externalcommand',
246
            'bzrlib.filters',
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',
5816.1.4 by Jelmer Vernooij
Add import tariff test for the smart server.
263
            'getpass',
264
            'kerberos',
265
            'smtplib',
266
            'tarfile',
267
            'tempfile',
268
            ] + old_format_modules)