21
21
from testtools import content
23
from bzrlib.bzrdir import BzrDir
24
from bzrlib.smart import medium
25
from bzrlib.transport import remote
23
27
from bzrlib.plugin import (
24
28
are_plugins_disabled,
28
32
TestCaseWithTransport,
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',
32
51
class TestImportTariffs(TestCaseWithTransport):
33
52
"""Check how many modules are loaded for some representative scenarios.
43
62
self.preserved_env_vars[name] = os.environ.get(name)
44
63
super(TestImportTariffs, self).setUp()
46
def run_command_check_imports(self, args, forbidden_imports):
47
"""Run bzr ARGS in a subprocess and check its imports.
65
def start_bzr_subprocess_with_import_check(self, args):
66
"""Run a bzr process and capture the imports.
49
68
This is fairly expensive because we start a subprocess, so we aim to
50
69
cover representative rather than exhaustive cases.
52
:param forbidden_imports: List of fully-qualified Python module names
53
that should not be loaded while running this command.
55
71
# We use PYTHON_VERBOSE rather than --profile-importts because in
56
72
# experimentation the profile-imports output seems to not always show
63
79
# explicitly do want to test against things installed there, therefore
64
80
# we pass it through.
65
81
env_changes = dict(PYTHONVERBOSE='1', **self.preserved_env_vars)
66
out, err = self.run_bzr_subprocess(args,
67
allow_plugins=(not are_plugins_disabled()),
68
env_changes=env_changes)
82
return self.start_bzr_subprocess(args, env_changes=env_changes,
83
allow_plugins=(not are_plugins_disabled()))
85
def check_forbidden_modules(self, err, forbidden_imports):
86
"""Check for forbidden modules in stderr.
88
:param err: Standard error
89
:param forbidden_imports: List of forbidden modules
70
91
self.addDetail('subprocess_stderr',
71
92
content.Content(content.ContentType("text", "plain"),
77
98
bad_modules.append(module_name)
80
self.fail("command %r loaded forbidden modules %r"
81
% (args, bad_modules))
101
self.fail("command loaded forbidden modules %r"
104
def finish_bzr_subprocess_with_import_check(self, process,
105
args, forbidden_imports):
106
"""Finish subprocess and check specific modules have not been
109
:param forbidden_imports: List of fully-qualified Python module names
110
that should not be loaded while running this command.
112
(out, err) = self.finish_bzr_subprocess(process,
113
universal_newlines=False, process_args=args)
114
self.check_forbidden_modules(err, forbidden_imports)
117
def run_command_check_imports(self, args, forbidden_imports):
118
"""Run bzr ARGS in a subprocess and check its imports.
120
This is fairly expensive because we start a subprocess, so we aim to
121
cover representative rather than exhaustive cases.
123
:param forbidden_imports: List of fully-qualified Python module names
124
that should not be loaded while running this command.
126
process = self.start_bzr_subprocess_with_import_check(args)
127
self.finish_bzr_subprocess_with_import_check(process, args,
84
130
def test_import_tariffs_working(self):
85
131
# check some guaranteed-true and false imports to be sure we're
86
132
# measuring correctly
123
167
'bzrlib.smart.server',
124
168
'bzrlib.transform',
125
169
'bzrlib.version_info_formats.format_rio',
126
'bzrlib.plugins.weave_fmt.branch',
127
'bzrlib.plugins.weave_fmt.bzrdir',
128
'bzrlib.plugins.weave_fmt.repository',
129
'bzrlib.plugins.weave_fmt.workingtree',
175
] + old_format_modules)
142
176
# TODO: similar test for repository-only operations, checking we avoid
143
177
# loading wt-specific stuff
149
183
self.run_command_check_imports(['help', 'commands'], [
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/'
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.
201
(out, err) = self.finish_bzr_subprocess(process,
202
universal_newlines=False)
203
self.check_forbidden_modules(err,
207
'bzrlib.bundle.commands',
208
'bzrlib.cmd_version_info',
209
'bzrlib.externalcommand',
211
# foreign branch plugins import the foreign_vcs_registry from
212
# bzrlib.foreign so it can't be blacklisted
217
'bzrlib.merge_directive',
219
'bzrlib.patiencediff',
222
'bzrlib.sign_my_commits',
223
'bzrlib.smart.client',
225
'bzrlib.version_info_formats.format_rio',
231
] + old_format_modules)