~bzr-pqm/bzr/bzr.dev

5017.2.2 by Martin Pool
Add import tariff tests
1
# Copyright (C) 2010 Canonical Ltd
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
20
from testtools import content
21
22
from bzrlib.plugin import (
23
    are_plugins_disabled,
24
    )
25
26
from bzrlib.tests import (
27
    TestCaseWithTransport,
28
    )
29
30
31
class TestImportTariffs(TestCaseWithTransport):
32
33
    """Check how many modules are loaded for some representative scenarios.
34
35
    See the Testing Guide in the developer documentation for more explanation.
36
    """
37
38
    def run_command_check_imports(self, args, forbidden_imports):
5018.1.8 by Martin Pool
doc
39
        """Run bzr ARGS in a subprocess and check its imports.
40
41
        This is fairly expensive because we start a subprocess, so we aim to
42
        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
        """
5017.2.2 by Martin Pool
Add import tariff tests
47
        # We use PYTHON_VERBOSE rather than --profile-importts because in
48
        # experimentation the profile-imports output seems to not always show
49
        # the modules you'd expect; this can be debugged but python -v seems
50
        # more likely to always show everything.  And we use the environment
51
        # variable rather than 'python -v' in the hope it will work even if
52
        # bzr is frozen and python is not explicitly specified. -- mbp 20100208
53
        #
54
        # Normally we want test isolation from the real $HOME but here we
55
        # explicitly do want to test against things installed there, therefore
56
        # we pass it through.
57
        env_changes = dict(PYTHONVERBOSE='1')
58
        for name in ['BZR_HOME', 'BZR_PLUGIN_PATH', 'HOME',]:
59
            env_changes[name] = self._old_env.get(name)
60
        out, err = self.run_bzr_subprocess(args,
61
            allow_plugins=(not are_plugins_disabled()),
62
            env_changes=env_changes)
63
64
        self.addDetail('subprocess_stderr', 
65
            content.Content(content.ContentType("text", "plain"),
66
                lambda:[err]))
67
68
        bad_modules = []
69
        for module_name in forbidden_imports:
70
            if err.find("\nimport %s " % module_name) != -1:
71
                bad_modules.append(module_name)
72
73
        if bad_modules:
74
            self.fail("command %r loaded forbidden modules %r" 
75
                % (args, bad_modules))
76
        return out, err
77
78
    def test_import_tariffs_working(self):
79
        # check some guaranteed-true and false imports to be sure we're
80
        # measuring correctly
81
        self.make_branch_and_tree('.')
82
        self.run_command_check_imports(['st'],
83
            ['nonexistentmodulename', 'anothernonexistentmodule'])
84
        self.assertRaises(AssertionError,
85
            self.run_command_check_imports,
86
            ['st'],
87
            ['bzrlib.tree'])
88
89
    def test_simple_local(self):
90
        # 'st' in a working tree shouldn't need many modules
91
        self.make_branch_and_tree('.')
5017.2.4 by Martin Pool
Move or remove some unconditionally loaded code
92
        self.run_command_check_imports(['st'], [
5018.1.11 by Martin Pool
Check bundle commands are not loaded for 'bzr st' invocation
93
            'bzrlib.bundle.commands',
5127.1.1 by Martin Pool
version-info is lazily loaded
94
            'bzrlib.cmd_version_info',
5127.1.3 by Martin Pool
lazy-load dpush
95
            'bzrlib.foreign',
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.
96
            'bzrlib.merge3',
97
            'bzrlib.patiencediff',
5017.2.4 by Martin Pool
Move or remove some unconditionally loaded code
98
            'bzrlib.remote',
5127.1.4 by Martin Pool
Lazy-load sign-my-commits
99
            'bzrlib.sign_my_commits',
5017.2.4 by Martin Pool
Move or remove some unconditionally loaded code
100
            'bzrlib.smart',
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.
101
            'bzrlib.transform',
5271.1.1 by Martin Pool
Test that Kerberos is no longer loaded.
102
            'kerberos',
5017.2.4 by Martin Pool
Move or remove some unconditionally loaded code
103
            'smtplib',
104
            'tarfile',
105
            ])
5127.1.2 by Martin Pool
Lazy-load conflict commands
106
        # TODO: similar test for repository-only operations, checking we avoid
107
        # loading wt-specific stuff
108
        #
5243.1.2 by Martin
Point launchpad links in comments at production server rather than edge
109
        # See https://bugs.launchpad.net/bzr/+bug/553017