1
# Copyright (C) 2006 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 as published by
 
 
5
# the Free Software Foundation; either version 2 of the License, or
 
 
6
# (at your option) any later version.
 
 
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.
 
 
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 
17
"""Tests for bzr bundle performance."""
 
 
19
from cStringIO import StringIO
 
 
23
from bzrlib import bzrdir
 
 
24
from bzrlib.add import smart_add
 
 
25
from bzrlib.benchmarks import Benchmark
 
 
26
from bzrlib.branch import Branch
 
 
27
from bzrlib.bundle.apply_bundle import install_bundle
 
 
28
from bzrlib.bundle.serializer import read_bundle, write_bundle
 
 
29
from bzrlib.revision import NULL_REVISION
 
 
30
from bzrlib.revisionspec import RevisionSpec
 
 
31
from bzrlib.workingtree import WorkingTree
 
 
34
class BundleBenchmark(Benchmark):
 
 
35
    """Benchmarks for bzr bundle performance and bzr merge with a bundle."""
 
 
37
    def test_create_bundle_known_kernel_like_tree(self):
 
 
38
        """Create a bundle for a kernel sized tree with no ignored, unknowns,
 
 
39
        or added and one commit.
 
 
41
        self.make_kernel_like_committed_tree()
 
 
42
        self.time(self.run_bzr, ['bundle', '--revision', '..-1'])
 
 
44
    def test_create_bundle_many_commit_tree (self):
 
 
45
        """Create a bundle for a tree with many commits but no changes.""" 
 
 
46
        self.make_many_commit_tree()
 
 
47
        self.time(self.run_bzr, ['bundle', '--revision', '..-1'])
 
 
49
    def test_create_bundle_heavily_merged_tree(self):
 
 
50
        """Create a bundle for a heavily merged tree.""" 
 
 
51
        self.make_heavily_merged_tree()
 
 
52
        self.time(self.run_bzr, ['bundle', '--revision', '..-1'])
 
 
54
    def test_apply_bundle_known_kernel_like_tree(self):
 
 
55
        """Create a bundle for a kernel sized tree with no ignored, unknowns,
 
 
56
        or added and one commit.
 
 
58
        tree = self.make_kernel_like_committed_tree('tree')
 
 
60
        f = open('bundle', 'wb')
 
 
62
            write_bundle(tree.branch.repository, tree.last_revision(),
 
 
67
        tree2 = self.make_branch_and_tree('branch_a')
 
 
69
        self.time(self.run_bzr, ['merge', '../bundle'])
 
 
72
class BundleLibraryLevelWriteBenchmark(Benchmark):
 
 
73
    """ Benchmarks for the write_bundle library function. """
 
 
75
    def _time_read_write(self):
 
 
76
        branch, relpath = Branch.open_containing("a")
 
 
77
        revision_history = branch.revision_history()
 
 
78
        bundle_text = StringIO()
 
 
79
        self.time(write_bundle, branch.repository, revision_history[-1],
 
 
80
                  NULL_REVISION, bundle_text)
 
 
82
        target_tree = self.make_branch_and_tree('b')
 
 
83
        bundle = self.time(read_bundle, bundle_text)
 
 
84
        self.time(install_bundle, target_tree.branch.repository, bundle)
 
 
86
    def test_few_files_small_tree_1_revision(self):
 
 
88
        tree, files = self.create_with_commits(5, 1, directory_name="a")
 
 
89
        self.commit_some_revisions(tree, files[:5], 1, 1)
 
 
90
        self._time_read_write()
 
 
92
    def test_few_files_small_tree_100_revision(self):
 
 
94
        tree, files = self.create_with_commits(5, 1, directory_name="a")
 
 
95
        self.commit_some_revisions(tree, files[:5], 100, 1)
 
 
96
        self._time_read_write()
 
 
98
    def test_few_files_moderate_tree_1_revision(self):
 
 
100
        tree, files = self.create_with_commits(100, 1, directory_name="a")
 
 
101
        self.commit_some_revisions(tree, files[:5], 1, 1)
 
 
102
        self._time_read_write()
 
 
104
    def test_few_files_moderate_tree_100_revision(self):
 
 
106
        tree, files = self.create_with_commits(100, 1, directory_name="a")
 
 
107
        self.commit_some_revisions(tree, files[:5], 100, 1)
 
 
108
        self._time_read_write()
 
 
110
    def test_some_files_moderate_tree_1_revision(self):
 
 
112
        tree, files = self.create_with_commits(100, 1, directory_name="a")
 
 
113
        self.commit_some_revisions(tree, files[:100], 1, 1)
 
 
114
        self._time_read_write()
 
 
116
    def test_few_files_big_tree_1_revision(self):
 
 
118
        tree, files = self.create_with_commits(1000, 1, directory_name="a")
 
 
119
        self.commit_some_revisions(tree, files[:5], 1, 1)
 
 
120
        self._time_read_write()
 
 
122
    def test_some_files_big_tree_1_revision(self):
 
 
124
        tree, files = self.create_with_commits(1000, 1, directory_name="a")
 
 
125
        self.commit_some_revisions(tree, files[:100], 1, 1)
 
 
126
        self._time_read_write()
 
 
129
class BundleLibraryLevelInstallBenchmark(Benchmark):
 
 
130
    """ Benchmarks for the install_bundle library function. """
 
 
132
    def _time_read_write(self):
 
 
133
        branch, relpath = Branch.open_containing("a")
 
 
134
        revision_history = branch.revision_history()
 
 
135
        bundle_text = StringIO()
 
 
136
        write_bundle(branch.repository, revision_history[-1],
 
 
137
                     NULL_REVISION, bundle_text)
 
 
139
        target_tree = self.make_branch_and_tree('b')
 
 
140
        bundle = self.time(read_bundle, bundle_text)
 
 
141
        self.time(install_bundle, target_tree.branch.repository, bundle)
 
 
143
    def test_few_files_small_tree_1_revision(self):
 
 
145
        tree, files = self.create_with_commits(5, 1, directory_name="a")
 
 
146
        self.commit_some_revisions(tree, files[:5], 1, 1)
 
 
147
        self._time_read_write()
 
 
149
    def test_few_files_small_tree_100_revision(self):
 
 
151
        tree, files = self.create_with_commits(5, 1, directory_name="a")
 
 
152
        self.commit_some_revisions(tree, files[:5], 100, 1)
 
 
153
        self._time_read_write()
 
 
155
    def test_few_files_moderate_tree_1_revision(self):
 
 
157
        tree, files = self.create_with_commits(100, 1, directory_name="a")
 
 
158
        self.commit_some_revisions(tree, files[:5], 1, 1)
 
 
159
        self._time_read_write()
 
 
161
    def test_few_files_moderate_tree_100_revision(self):
 
 
163
        tree, files = self.create_with_commits(100, 1, directory_name="a")
 
 
164
        self.commit_some_revisions(tree, files[:5], 100, 1)
 
 
165
        self._time_read_write()
 
 
167
    def test_some_files_moderate_tree_1_revision(self):
 
 
169
        tree, files = self.create_with_commits(100, 1, directory_name="a")
 
 
170
        self.commit_some_revisions(tree, files[:100], 1, 1)
 
 
171
        self._time_read_write()
 
 
173
    def test_few_files_big_tree_1_revision(self):
 
 
175
        tree, files = self.create_with_commits(1000, 1, directory_name="a")
 
 
176
        self.commit_some_revisions(tree, files[:5], 1, 1)
 
 
177
        self._time_read_write()
 
 
179
    def test_some_files_big_tree_1_revision(self):
 
 
181
        tree, files = self.create_with_commits(1000, 1, directory_name="a")
 
 
182
        self.commit_some_revisions(tree, files[:100], 1, 1)
 
 
183
        self._time_read_write()
 
 
186
if __name__ == '__main__':
 
 
187
    # USE the following if you want to regenerate the above test functions 
 
 
188
    for treesize, treesize_h in [(5, "small"), (100, "moderate"),
 
 
190
        for bundlefiles, bundlefiles_h in [(5, "few"), (100, "some")]:
 
 
191
            if bundlefiles > treesize:
 
 
193
            for num_revisions in [1, 100]:
 
 
194
                if (num_revisions >= 100 and 
 
 
195
                        (bundlefiles >= 100 or treesize >= 1000)):
 
 
196
                    # Skip the 100x100x? tests.
 
 
200
    def test_%s_files_%s_tree_%s_revision(self):
 
 
202
        tree, files = self.create_with_commits(%s, 1, directory_name="a")
 
 
203
        self.commit_some_revisions(tree, files[:%s], %s, 1)
 
 
204
        self._time_read_write()
 
 
205
""" % (bundlefiles_h, treesize_h, num_revisions,
 
 
206
       treesize, bundlefiles, num_revisions)