13
13
# You should have received a copy of the GNU General Public License
14
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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
18
"""Benchmark test suite for bzr."""
22
from bzrlib import plugin as _mod_plugin
20
from bzrlib import bzrdir, plugin
24
21
from bzrlib.tests.TestUtil import TestLoader
25
22
from bzrlib.tests.blackbox import ExternalBase
28
25
class Benchmark(ExternalBase):
29
"""A Test class which provides helpers for writing benchmark tests."""
31
def make_kernel_like_tree(self, url=None, root='.',
27
def make_kernel_like_tree(self, url=None):
33
28
"""Setup a temporary tree roughly like a kernel tree.
35
30
:param url: Creat the kernel like tree as a lightweight checkout
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.
43
from bzrlib.benchmarks.tree_creator.kernel_like import (
44
KernelLikeTreeCreator,
46
creator = KernelLikeTreeCreator(self, link_working=link_working,
48
return creator.create(root=root)
50
def make_kernel_like_added_tree(self, root='.',
53
"""Make a kernel like tree, with all files added
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.
63
from bzrlib.benchmarks.tree_creator.kernel_like import (
64
KernelLikeAddedTreeCreator,
66
creator = KernelLikeAddedTreeCreator(self, link_working=link_working,
68
return creator.create(root=root)
70
def make_kernel_like_committed_tree(self, root='.',
74
"""Make a kernel like tree, with all files added and committed
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
83
from bzrlib.benchmarks.tree_creator.kernel_like import (
84
KernelLikeCommittedTreeCreator,
86
creator = KernelLikeCommittedTreeCreator(self,
87
link_working=link_working,
90
return creator.create(root=root)
92
def make_kernel_like_inventory(self):
93
"""Create an inventory with the properties of a kernel-like tree
95
This should be equivalent to a committed kernel like tree, not
98
from bzrlib.benchmarks.tree_creator.kernel_like import (
99
KernelLikeInventoryCreator,
101
creator = KernelLikeInventoryCreator(self)
102
return creator.create()
104
def make_many_commit_tree(self, directory_name='.',
31
of a new branch created at url.
33
# a kernel tree has ~10000 and 500 directory, with most files around
35
# we simulate this by three levels of dirs named 0-7, givin 512 dirs,
38
b = bzrdir.BzrDir.create_branch_convenience(url)
39
d = bzrdir.BzrDir.create('.')
40
bzrlib.branch.BranchReferenceFormat().initialize(d, b)
41
d.create_workingtree()
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)
52
files.extend([prefix + str(foo) for foo in range(20)])
53
self.build_tree(files)
55
def make_many_commit_tree(self, directory_name='.'):
106
56
"""Create a tree with many commits.
108
No file changes are included. Not hardlinking the working tree,
109
because there are no working tree files.
58
No files change are included.
111
from bzrlib.benchmarks.tree_creator.simple_many_commit import (
112
SimpleManyCommitTreeCreator,
114
creator = SimpleManyCommitTreeCreator(self, link_bzr=hardlink)
115
return creator.create(root=directory_name)
60
tree = bzrdir.BzrDir.create_standalone_workingtree(directory_name)
62
tree.branch.lock_write()
63
tree.branch.repository.lock_write()
65
for i in xrange(1000):
66
tree.commit('no-changes commit %d' % i)
70
tree.branch.repository.unlock()
117
def make_heavily_merged_tree(self, directory_name='.',
77
def make_heavily_merged_tree(self, directory_name='.'):
119
78
"""Create a tree in which almost every commit is a merge.
121
No file changes are included. This produces two trees,
80
No files change are included. This produces two trees,
122
81
one of which is returned. Except for the first commit, every
123
82
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
127
from bzrlib.benchmarks.tree_creator.heavily_merged import (
128
HeavilyMergedTreeCreator,
130
creator = HeavilyMergedTreeCreator(self, link_bzr=hardlink)
131
return creator.create(root=directory_name)
133
def create_with_commits(self, num_files, num_commits, directory_name='.',
135
"""Create a tree with many files and many commits. Every commit changes
138
:param num_files: number of files to be created
139
:param num_commits: number of commits in the newly created tree
141
from bzrlib.benchmarks.tree_creator.many_commit import (
142
ManyCommitTreeCreator,
144
creator = ManyCommitTreeCreator(self, link_bzr=hardlink,
146
num_commits=num_commits)
147
tree = creator.create(root=directory_name)
148
files = ["%s/%s" % (directory_name, fn) for fn in creator.files]
151
def commit_some_revisions(self, tree, files, num_commits,
153
"""Commit a specified number of revisions to some files in a tree,
154
makeing a specified number of changes per commit.
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
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, '']
168
f.write("\n".join([str(k) for k in content]))
171
tree.commit("new revision")
85
tree = bzrdir.BzrDir.create_standalone_workingtree(directory_name)
88
tree2 = tree.bzrdir.sprout('tree2').open_workingtree()
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([])
174
106
def test_suite():
176
108
testmod_names = [ \
177
109
'bzrlib.benchmarks.bench_add',
178
110
'bzrlib.benchmarks.bench_bench',
179
'bzrlib.benchmarks.bench_bundle',
180
'bzrlib.benchmarks.bench_cache_utf8',
181
111
'bzrlib.benchmarks.bench_checkout',
182
112
'bzrlib.benchmarks.bench_commit',
183
'bzrlib.benchmarks.bench_dirstate',
184
'bzrlib.benchmarks.bench_info',
185
113
'bzrlib.benchmarks.bench_inventory',
186
'bzrlib.benchmarks.bench_knit',
187
114
'bzrlib.benchmarks.bench_log',
188
'bzrlib.benchmarks.bench_pack',
189
115
'bzrlib.benchmarks.bench_osutils',
190
116
'bzrlib.benchmarks.bench_rocks',
191
'bzrlib.benchmarks.bench_startup',
192
117
'bzrlib.benchmarks.bench_status',
193
'bzrlib.benchmarks.bench_tags',
194
118
'bzrlib.benchmarks.bench_transform',
195
119
'bzrlib.benchmarks.bench_workingtree',
196
'bzrlib.benchmarks.bench_sftp',
197
'bzrlib.benchmarks.bench_xml',
199
suite = TestLoader().loadTestsFromModuleNames(testmod_names)
121
suite = TestLoader().loadTestsFromModuleNames(testmod_names)
201
123
# Load any benchmarks from plugins
202
for name, plugin in _mod_plugin.plugins().items():
203
if getattr(plugin.module, 'bench_suite', None) is not None:
204
suite.addTest(plugin.module.bench_suite())
124
for name, module in plugin.all_plugins().items():
125
if getattr(module, 'bench_suite', None) is not None:
126
suite.addTest(module.bench_suite())