~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/benchmarks/__init__.py

Merged bzr.dev and updated NEWS with a better description of changes

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
 
from bzrlib import bzrdir, plugin
 
19
from bzrlib import (
 
20
    bzrdir,
 
21
    plugin,
 
22
    )
 
23
import bzrlib.branch
21
24
from bzrlib.tests.TestUtil import TestLoader
22
25
from bzrlib.tests.blackbox import ExternalBase
23
26
 
24
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 = bzrdir.BzrDir.create_branch_convenience(url)
39
 
            d = 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='.'):
 
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):
56
106
        """Create a tree with many commits.
57
107
        
58
 
        No files change are included.
 
108
        No file changes are included. Not hardlinking the working tree, 
 
109
        because there are no working tree files.
59
110
        """
60
 
        tree = bzrdir.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:
69
 
                try:
70
 
                    tree.branch.repository.unlock()
71
 
                finally:
72
 
                    tree.branch.unlock()
73
 
            finally:
74
 
                tree.unlock()
75
 
        return tree
 
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)
76
116
 
77
 
    def make_heavily_merged_tree(self, directory_name='.'):
 
117
    def make_heavily_merged_tree(self, directory_name='.',
 
118
                                 hardlink=False):
78
119
        """Create a tree in which almost every commit is a merge.
79
120
       
80
 
        No files change are included.  This produces two trees, 
 
121
        No file changes are included.  This produces two trees, 
81
122
        one of which is returned.  Except for the first commit, every
82
123
        commit in its revision-history is a merge another commit in the other
83
 
        tree.
84
 
        """
85
 
        tree = bzrdir.BzrDir.create_standalone_workingtree(directory_name)
86
 
        tree.lock_write()
87
 
        try:
88
 
            tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
89
 
            tree2.lock_write()
90
 
            try:
91
 
                for i in xrange(250):
92
 
                    revision_id = tree.commit('no-changes commit %d-a' % i)
93
 
                    tree2.branch.fetch(tree.branch, revision_id)
94
 
                    tree2.set_pending_merges([revision_id])
95
 
                    revision_id = tree2.commit('no-changes commit %d-b' % i)
96
 
                    tree.branch.fetch(tree2.branch, revision_id)
97
 
                    tree.set_pending_merges([revision_id])
98
 
                tree.set_pending_merges([])
99
 
            finally:
100
 
                tree.unlock()
101
 
        finally:
102
 
            tree2.unlock()
103
 
        return tree
 
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")
 
167
                try:
 
168
                    f.write("\n".join([str(k) for k in content]))
 
169
                finally:
 
170
                    f.close()
 
171
            tree.commit("new revision")
104
172
 
105
173
 
106
174
def test_suite():
108
176
    testmod_names = [ \
109
177
                   'bzrlib.benchmarks.bench_add',
110
178
                   'bzrlib.benchmarks.bench_bench',
 
179
                   'bzrlib.benchmarks.bench_bundle',
 
180
                   'bzrlib.benchmarks.bench_cache_utf8',
111
181
                   'bzrlib.benchmarks.bench_checkout',
112
182
                   'bzrlib.benchmarks.bench_commit',
 
183
                   'bzrlib.benchmarks.bench_dirstate',
 
184
                   'bzrlib.benchmarks.bench_info',
113
185
                   'bzrlib.benchmarks.bench_inventory',
 
186
                   'bzrlib.benchmarks.bench_knit',
114
187
                   'bzrlib.benchmarks.bench_log',
115
188
                   'bzrlib.benchmarks.bench_osutils',
116
189
                   'bzrlib.benchmarks.bench_rocks',
 
190
                   'bzrlib.benchmarks.bench_startup',
117
191
                   'bzrlib.benchmarks.bench_status',
118
192
                   'bzrlib.benchmarks.bench_transform',
119
193
                   'bzrlib.benchmarks.bench_workingtree',
 
194
                   'bzrlib.benchmarks.bench_sftp',
 
195
                   'bzrlib.benchmarks.bench_xml',
120
196
                   ]
121
197
    suite = TestLoader().loadTestsFromModuleNames(testmod_names) 
122
198