1
# Copyright (C) 2006 by Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License version 2 as published by
5
# the Free Software Foundation.
7
# This program is distributed in the hope that it will be useful,
8
# but WITHOUT ANY WARRANTY; without even the implied warranty of
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
# GNU General Public License for more details.
12
# You should have received a copy of the GNU General Public License
13
# along with this program; if not, write to the Free Software
14
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16
"""Tests for bzr bundle performance."""
20
from cStringIO import StringIO
22
from bzrlib.benchmarks import Benchmark
23
from bzrlib.branch import Branch
24
from bzrlib.bundle import read_bundle
25
from bzrlib.bundle.serializer import write_bundle
26
from bzrlib.revisionspec import RevisionSpec
27
from bzrlib.workingtree import WorkingTree
30
class BundleBenchmark(Benchmark):
31
"""The bundle tests should (also) be done at a lower level with
32
direct call to the bzrlib.
35
def make_kernel_like_tree_committed(self):
36
self.make_kernel_like_tree_added()
37
self.run_bzr('commit', '-m', 'initial import')
39
def test_create_bundle_known_kernel_like_tree(self):
40
"""Create a bundle for a kernel sized tree with no ignored, unknowns,
41
or added and one commit.
43
self.make_kernel_like_tree_committed()
44
self.time(self.run_bzr, 'bundle', '--revision', '..-1')
46
def test_create_bundle_many_commit_tree (self):
47
"""Create a bundle for a tree with many commits but no changes."""
48
self.make_many_commit_tree()
49
self.time(self.run_bzr, 'bundle', '--revision', '..-1')
51
def test_create_bundle_heavily_merged_tree(self):
52
"""Create a bundle for a heavily merged tree."""
53
self.make_heavily_merged_tree()
54
self.time(self.run_bzr, 'bundle', '--revision', '..-1')
56
def test_apply_bundle_known_kernel_like_tree(self):
57
"""Create a bundle for a kernel sized tree with no ignored, unknowns,
58
or added and one commit.
60
self.make_kernel_like_tree_committed()
61
f = file('../bundle', 'wb')
63
f.write(self.run_bzr('bundle', '--revision', '..-1')[0])
66
self.run_bzr("init", "../branch_a")
67
os.chdir('../branch_a')
68
self.time(self.run_bzr, 'merge', '../bundle')
71
class BundleLibraryLevelBenchmark(Benchmark):
73
def make_parametrized_tree(self, num_files, num_revisions,
75
"""Create a tree with given parameters. Always creates 2 levels of
76
directories with the given number of files. Then the given number of
77
revisions are created, changing some lines in one files in each
78
revision. Only num_files_in_bundle files are changed in these
81
:param num_files: number of files in tree
82
:param num_revisions: number of revisions
83
:param num_files_in_bundle: number of files changed in the revisions
88
for outer in range(num_files // 64 + 1):
89
directories.append("%s/" % outer)
90
for middle in range(8):
91
prefix = "%s/%s/" % (outer, middle)
92
directories.append(prefix)
93
for filename in range(min(8, num_files - count)):
95
files.append(prefix + str(filename))
97
self.build_tree(directories + files)
99
self.run_bzr('add', d)
100
self.run_bzr('commit', '-m', 'initial repo layout')
102
affected_files = files[:num_files_in_bundle]
104
for changes_file in range(num_revisions // num_files_in_bundle + 1):
105
for f in affected_files:
107
if count >= num_revisions:
109
content = "\n".join([str(i) for i in range(changes_file)] +
110
[str(changes_file)] * 5) + "\n"
111
self.build_tree_contents([(f, content)])
112
self.run_bzr("commit", '-m', 'some changes')
113
assert count >= num_revisions
115
def _time_read_write(self):
116
branch, relpath = Branch.open_containing(".")
117
revision_history = branch.revision_history()
118
bundle_text = StringIO()
119
self.time(write_bundle, branch.repository, revision_history[-1],
122
self.time(read_bundle, bundle_text)
124
def test_few_files_small_tree_1_revision(self):
125
self.make_parametrized_tree(5, 1, 5)
126
self._time_read_write()
128
def test_few_files_small_tree_500_revision(self):
129
self.make_parametrized_tree(5, 500, 5)
130
self._time_read_write()
132
def test_few_files_small_tree_1000_revision(self):
133
self.make_parametrized_tree(5, 1000, 5)
134
self._time_read_write()
136
def test_few_files_moderate_tree_1_revision(self):
137
self.make_parametrized_tree(100, 1, 5)
138
self._time_read_write()
140
def test_few_files_moderate_tree_500_revision(self):
141
self.make_parametrized_tree(100, 500, 5)
142
self._time_read_write()
144
def test_few_files_moderate_tree_1000_revision(self):
145
self.make_parametrized_tree(100, 1000, 5)
146
self._time_read_write()
148
def test_some_files_moderate_tree_1_revision(self):
149
self.make_parametrized_tree(100, 1, 100)
150
self._time_read_write()
152
def test_some_files_moderate_tree_500_revision(self):
153
self.make_parametrized_tree(100, 500, 100)
154
self._time_read_write()
156
def test_some_files_moderate_tree_1000_revision(self):
157
self.make_parametrized_tree(100, 1000, 100)
158
self._time_read_write()
160
def test_few_files_big_tree_1_revision(self):
161
self.make_parametrized_tree(1000, 1, 5)
162
self._time_read_write()
164
def test_few_files_big_tree_500_revision(self):
165
self.make_parametrized_tree(1000, 500, 5)
166
self._time_read_write()
168
def test_few_files_big_tree_1000_revision(self):
169
self.make_parametrized_tree(1000, 1000, 5)
170
self._time_read_write()
172
def test_some_files_big_tree_1_revision(self):
173
self.make_parametrized_tree(1000, 1, 100)
174
self._time_read_write()
176
def test_some_files_big_tree_500_revision(self):
177
self.make_parametrized_tree(1000, 500, 100)
178
self._time_read_write()
180
def test_some_files_big_tree_1000_revision(self):
181
self.make_parametrized_tree(1000, 1000, 100)
182
self._time_read_write()
184
def test_many_files_big_tree_1_revision(self):
185
self.make_parametrized_tree(1000, 1, 1000)
186
self._time_read_write()
188
def test_many_files_big_tree_500_revision(self):
189
self.make_parametrized_tree(1000, 500, 1000)
190
self._time_read_write()
192
def test_many_files_big_tree_1000_revision(self):
193
self.make_parametrized_tree(1000, 1000, 1000)
194
self._time_read_write()
197
if __name__ == '__main__':
198
# USE the following if you want to regenerate the above test functions
199
for treesize, treesize_h in [(5, "small"), (100, "moderate"),
201
for bundlefiles, bundlefiles_h in [(5, "few"), (100, "some"),
203
if bundlefiles > treesize:
205
for num_revisions in [1, 500, 1000]:
207
def test_%s_files_%s_tree_%s_revision(self):
208
self.make_parametrized_tree(%s, %s, %s)
209
self._time_read_write()
210
""" % (bundlefiles_h, treesize_h, num_revisions,
211
treesize, num_revisions, bundlefiles)