27
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',
31
51
class TestImportTariffs(TestCaseWithTransport):
33
52
"""Check how many modules are loaded for some representative scenarios.
35
54
See the Testing Guide in the developer documentation for more explanation.
38
def run_command_check_imports(self, args, forbidden_imports):
39
"""Run bzr ARGS in a subprocess and check its imports.
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()
65
def start_bzr_subprocess_with_import_check(self, args):
66
"""Run a bzr process and capture the imports.
41
68
This is fairly expensive because we start a subprocess, so we aim to
42
69
cover representative rather than exhaustive cases.
44
:param forbidden_imports: List of fully-qualified Python module names
45
that should not be loaded while running this command.
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
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',
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)
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()))
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
66
91
self.addDetail('subprocess_stderr',
67
92
content.Content(content.ContentType("text", "plain"),
73
98
bad_modules.append(module_name)
76
self.fail("command %r loaded forbidden modules %r"
77
% (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,
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
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'], [
95
148
'bzrlib.bundle.commands',
96
149
'bzrlib.cmd_version_info',
150
'bzrlib.externalcommand',
152
# foreign branch plugins import the foreign_vcs_registry from
153
# bzrlib.foreign so it can't be blacklisted
158
'bzrlib.merge_directive',
99
160
'bzrlib.patiencediff',
101
163
'bzrlib.sign_my_commits',
165
'bzrlib.smart.client',
166
'bzrlib.smart.medium',
167
'bzrlib.smart.server',
103
168
'bzrlib.transform',
169
'bzrlib.version_info_formats.format_rio',
175
] + old_format_modules)
108
176
# TODO: similar test for repository-only operations, checking we avoid
109
177
# loading wt-specific stuff
111
179
# See https://bugs.launchpad.net/bzr/+bug/553017
181
def test_help_commands(self):
182
# See https://bugs.launchpad.net/bzr/+bug/663773
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',
210
'bzrlib._dirstate_helpers_py',
211
'bzrlib._dirstate_helpers_pyx',
212
'bzrlib.externalcommand',
214
# foreign branch plugins import the foreign_vcs_registry from
215
# bzrlib.foreign so it can't be blacklisted
220
'bzrlib.merge_directive',
222
'bzrlib.patiencediff',
225
'bzrlib.sign_my_commits',
226
'bzrlib.smart.client',
228
'bzrlib.version_info_formats.format_rio',
229
'bzrlib.workingtree_4',
235
] + old_format_modules)