~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/benchmarks/__init__.py

  • Committer: Andrew Bennetts
  • Date: 2008-09-05 10:48:03 UTC
  • mto: This revision was merged to the branch mainline in revision 3693.
  • Revision ID: andrew.bennetts@canonical.com-20080905104803-6g72dz6wcldosfs2
Remove monkey-patching of branch._ensure_real from test_remote.py.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006 by Canonical Ltd
 
1
# Copyright (C) 2006 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
 
 
18
17
"""Benchmark test suite for bzr."""
19
18
 
20
 
import bzrlib
21
 
from bzrlib.bzrdir import BzrDir
22
 
from bzrlib.tests import TestLoader
 
19
from bzrlib import (
 
20
    bzrdir,
 
21
    )
 
22
from bzrlib import plugin as _mod_plugin
 
23
import bzrlib.branch
 
24
from bzrlib.tests.TestUtil import TestLoader
23
25
from bzrlib.tests.blackbox import ExternalBase
24
26
 
 
27
 
25
28
class Benchmark(ExternalBase):
 
29
    """A Test class which provides helpers for writing benchmark tests."""
26
30
 
27
 
    def make_kernel_like_tree(self, url=None):
 
31
    def make_kernel_like_tree(self, url=None, root='.',
 
32
                              link_working=False):
28
33
        """Setup a temporary tree roughly like a kernel tree.
29
 
        
 
34
 
30
35
        :param url: Creat the kernel like tree as a lightweight checkout
31
 
        of a new branch created at url.
32
 
        """
33
 
        # a kernel tree has ~10000 and 500 directory, with most files around 
34
 
        # 3-4 levels deep. 
35
 
        # we simulate this by three levels of dirs named 0-7, givin 512 dirs,
36
 
        # and 20 files each.
37
 
        if url is not None:
38
 
            b = bzrlib.bzrdir.BzrDir.create_branch_convenience(url)
39
 
            d = bzrlib.bzrdir.BzrDir.create('.')
40
 
            bzrlib.branch.BranchReferenceFormat().initialize(d, b)
41
 
            d.create_workingtree()
42
 
        else:
43
 
            self.run_bzr('init')
44
 
        files = []
45
 
        for outer in range(8):
46
 
            files.append("%s/" % outer)
47
 
            for middle in range(8):
48
 
                files.append("%s/%s/" % (outer, middle))
49
 
                for inner in range(8):
50
 
                    prefix = "%s/%s/%s/" % (outer, middle, inner)
51
 
                    files.append(prefix)
52
 
                    files.extend([prefix + str(foo) for foo in range(20)])
53
 
        self.build_tree(files)
54
 
 
55
 
    def make_many_commit_tree(self, directory_name='.'):
56
 
        """Create a tree with an egregious number of commits.
 
36
            of a new branch created at url.
 
37
        :param root: Path where the tree will be created.
 
38
        :param link_working: instead of creating a new copy of all files
 
39
            just hardlink the working tree. Tests must request this, because
 
40
            they must break links if they want to change the files
 
41
        :return: A newly created tree.
 
42
        """
 
43
        from bzrlib.benchmarks.tree_creator.kernel_like import (
 
44
            KernelLikeTreeCreator,
 
45
            )
 
46
        creator = KernelLikeTreeCreator(self, link_working=link_working,
 
47
                                        url=url)
 
48
        return creator.create(root=root)
 
49
 
 
50
    def make_kernel_like_added_tree(self, root='.',
 
51
                                    link_working=True,
 
52
                                    hot_cache=True):
 
53
        """Make a kernel like tree, with all files added
 
54
 
 
55
        :param root: Where to create the files
 
56
        :param link_working: Instead of copying all of the working tree
 
57
            files, just hardlink them to the cached files. Tests can unlink
 
58
            files that they will change.
 
59
        :param hot_cache: Run through the newly created tree and make sure
 
60
            the stat-cache is correct. The old way of creating a freshly
 
61
            added tree always had a hot cache.
 
62
        """
 
63
        from bzrlib.benchmarks.tree_creator.kernel_like import (
 
64
            KernelLikeAddedTreeCreator,
 
65
            )
 
66
        creator = KernelLikeAddedTreeCreator(self, link_working=link_working,
 
67
                                             hot_cache=hot_cache)
 
68
        return creator.create(root=root)
 
69
 
 
70
    def make_kernel_like_committed_tree(self, root='.',
 
71
                                    link_working=True,
 
72
                                    link_bzr=False,
 
73
                                    hot_cache=True):
 
74
        """Make a kernel like tree, with all files added and committed
 
75
 
 
76
        :param root: Where to create the files
 
77
        :param link_working: Instead of copying all of the working tree
 
78
            files, just hardlink them to the cached files. Tests can unlink
 
79
            files that they will change.
 
80
        :param link_bzr: Hardlink the .bzr directory. For readonly 
 
81
            operations this is safe, and shaves off a lot of setup time
 
82
        """
 
83
        from bzrlib.benchmarks.tree_creator.kernel_like import (
 
84
            KernelLikeCommittedTreeCreator,
 
85
            )
 
86
        creator = KernelLikeCommittedTreeCreator(self,
 
87
                                                 link_working=link_working,
 
88
                                                 link_bzr=link_bzr,
 
89
                                                 hot_cache=hot_cache)
 
90
        return creator.create(root=root)
 
91
 
 
92
    def make_kernel_like_inventory(self):
 
93
        """Create an inventory with the properties of a kernel-like tree
 
94
 
 
95
        This should be equivalent to a committed kernel like tree, not
 
96
        just a working tree.
 
97
        """
 
98
        from bzrlib.benchmarks.tree_creator.kernel_like import (
 
99
            KernelLikeInventoryCreator,
 
100
            )
 
101
        creator = KernelLikeInventoryCreator(self)
 
102
        return creator.create()
 
103
 
 
104
    def make_many_commit_tree(self, directory_name='.',
 
105
                              hardlink=False):
 
106
        """Create a tree with many commits.
57
107
        
58
 
        No files change are included.
59
 
        """
60
 
        tree = BzrDir.create_standalone_workingtree(directory_name)
61
 
        tree.lock_write()
62
 
        tree.branch.lock_write()
63
 
        tree.branch.repository.lock_write()
64
 
        try:
65
 
            for i in xrange(1000):
66
 
                tree.commit('no-changes commit %d' % i)
67
 
        finally:
68
 
            try:
 
108
        No file changes are included. Not hardlinking the working tree, 
 
109
        because there are no working tree files.
 
110
        """
 
111
        from bzrlib.benchmarks.tree_creator.simple_many_commit import (
 
112
            SimpleManyCommitTreeCreator,
 
113
            )
 
114
        creator = SimpleManyCommitTreeCreator(self, link_bzr=hardlink)
 
115
        return creator.create(root=directory_name)
 
116
 
 
117
    def make_heavily_merged_tree(self, directory_name='.',
 
118
                                 hardlink=False):
 
119
        """Create a tree in which almost every commit is a merge.
 
120
       
 
121
        No file changes are included.  This produces two trees, 
 
122
        one of which is returned.  Except for the first commit, every
 
123
        commit in its revision-history is a merge another commit in the other
 
124
        tree.  Not hardlinking the working tree, because there are no working 
 
125
        tree files.
 
126
        """
 
127
        from bzrlib.benchmarks.tree_creator.heavily_merged import (
 
128
            HeavilyMergedTreeCreator,
 
129
            )
 
130
        creator = HeavilyMergedTreeCreator(self, link_bzr=hardlink)
 
131
        return creator.create(root=directory_name)
 
132
 
 
133
    def create_with_commits(self, num_files, num_commits, directory_name='.',
 
134
                            hardlink=False):
 
135
        """Create a tree with many files and many commits. Every commit changes
 
136
        exactly one file.
 
137
 
 
138
        :param num_files: number of files to be created
 
139
        :param num_commits: number of commits in the newly created tree
 
140
        """
 
141
        from bzrlib.benchmarks.tree_creator.many_commit import (
 
142
            ManyCommitTreeCreator,
 
143
            )
 
144
        creator = ManyCommitTreeCreator(self, link_bzr=hardlink,
 
145
                                        num_files=num_files,
 
146
                                        num_commits=num_commits)
 
147
        tree = creator.create(root=directory_name)
 
148
        files = ["%s/%s" % (directory_name, fn) for fn in creator.files]
 
149
        return tree, files
 
150
 
 
151
    def commit_some_revisions(self, tree, files, num_commits,
 
152
                              changes_per_commit):
 
153
        """Commit a specified number of revisions to some files in a tree,
 
154
        makeing a specified number of changes per commit.
 
155
 
 
156
        :param tree: The tree in which the changes happen.
 
157
        :param files: The list of files where changes should occur.
 
158
        :param num_commits: The number of commits
 
159
        :param changes_per_commit: The number of files that are touched in
 
160
            each commit.
 
161
        """
 
162
        for j in range(num_commits):
 
163
            for i in range(changes_per_commit):
 
164
                fn = files[(i + j) % changes_per_commit]
 
165
                content = range(i) + [i, i, i, '']
 
166
                f = open(fn, "w")
69
167
                try:
70
 
                    tree.branch.repository.unlock()
 
168
                    f.write("\n".join([str(k) for k in content]))
71
169
                finally:
72
 
                    tree.branch.unlock()
73
 
            finally:
74
 
                tree.unlock()
75
 
        return tree
 
170
                    f.close()
 
171
            tree.commit("new revision")
76
172
 
77
173
 
78
174
def test_suite():
80
176
    testmod_names = [ \
81
177
                   'bzrlib.benchmarks.bench_add',
82
178
                   'bzrlib.benchmarks.bench_bench',
 
179
                   'bzrlib.benchmarks.bench_bundle',
 
180
                   'bzrlib.benchmarks.bench_cache_utf8',
83
181
                   'bzrlib.benchmarks.bench_checkout',
84
182
                   'bzrlib.benchmarks.bench_commit',
 
183
                   'bzrlib.benchmarks.bench_dirstate',
 
184
                   'bzrlib.benchmarks.bench_info',
85
185
                   'bzrlib.benchmarks.bench_inventory',
 
186
                   'bzrlib.benchmarks.bench_knit',
86
187
                   'bzrlib.benchmarks.bench_log',
 
188
                   'bzrlib.benchmarks.bench_pack',
87
189
                   'bzrlib.benchmarks.bench_osutils',
88
190
                   'bzrlib.benchmarks.bench_rocks',
 
191
                   'bzrlib.benchmarks.bench_startup',
89
192
                   'bzrlib.benchmarks.bench_status',
90
193
                   'bzrlib.benchmarks.bench_transform',
91
194
                   'bzrlib.benchmarks.bench_workingtree',
 
195
                   'bzrlib.benchmarks.bench_sftp',
 
196
                   'bzrlib.benchmarks.bench_xml',
92
197
                   ]
93
 
    return TestLoader().loadTestsFromModuleNames(testmod_names)
 
198
    suite = TestLoader().loadTestsFromModuleNames(testmod_names) 
 
199
 
 
200
    # Load any benchmarks from plugins
 
201
    for name, plugin in _mod_plugin.plugins().items():
 
202
        if getattr(plugin.module, 'bench_suite', None) is not None:
 
203
            suite.addTest(plugin.module.bench_suite())
 
204
 
 
205
    return suite