/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2696.3.2 by Martin Pool
Move some per-repository tests from big test_repository to test_fetch
1
# Copyright (C) 2007 Canonical Ltd
2
#
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.
7
#
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.
12
#
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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2696.3.2 by Martin Pool
Move some per-repository tests from big test_repository to test_fetch
16
17
"""Tests for fetch between repositories of the same type."""
18
19
from bzrlib import (
20
    bzrdir,
21
    errors,
2696.3.10 by Martin Pool
Add missing import
22
    gpg,
4324.3.1 by Robert Collins
When adding rich root data follow the standard revision graph rules, so it does not create 'inconstent parents'.
23
    remote,
2948.3.1 by John Arbash Meinel
Fix bug #158333, make sure that Repository.fetch(self) is properly a no-op for all Repository implementations.
24
    repository,
2696.3.2 by Martin Pool
Move some per-repository tests from big test_repository to test_fetch
25
    )
4324.3.1 by Robert Collins
When adding rich root data follow the standard revision graph rules, so it does not create 'inconstent parents'.
26
from bzrlib.inventory import ROOT_ID
2696.3.2 by Martin Pool
Move some per-repository tests from big test_repository to test_fetch
27
from bzrlib.tests import TestSkipped
3689.1.1 by John Arbash Meinel
Rename repository_implementations tests into per_repository tests
28
from bzrlib.tests.per_repository import TestCaseWithRepository
2696.3.2 by Martin Pool
Move some per-repository tests from big test_repository to test_fetch
29
from bzrlib.transport import get_transport
30
31
32
class TestFetchSameRepository(TestCaseWithRepository):
33
34
    def test_fetch(self):
35
        # smoke test fetch to ensure that the convenience function works.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
36
        # it is defined as a convenience function with the underlying
2696.3.2 by Martin Pool
Move some per-repository tests from big test_repository to test_fetch
37
        # functionality provided by an InterRepository
38
        tree_a = self.make_branch_and_tree('a')
39
        self.build_tree(['a/foo'])
40
        tree_a.add('foo', 'file1')
41
        tree_a.commit('rev1', rev_id='rev1')
42
        # fetch with a default limit (grab everything)
2711.2.6 by Martin Pool
Fix up conversion of create_repository to make_repository in test_fetch
43
        repo = self.make_repository('b')
2696.3.2 by Martin Pool
Move some per-repository tests from big test_repository to test_fetch
44
        if (tree_a.branch.repository.supports_rich_root() and not
45
            repo.supports_rich_root()):
46
            raise TestSkipped('Cannot fetch from model2 to model1')
47
        repo.fetch(tree_a.branch.repository,
48
                   revision_id=None)
49
4145.1.1 by Robert Collins
Explicitly prevent fetching while the target repository is in a write group.
50
    def test_fetch_fails_in_write_group(self):
51
        # fetch() manages a write group itself, fetching within one isn't safe.
52
        repo = self.make_repository('a')
53
        repo.lock_write()
54
        self.addCleanup(repo.unlock)
55
        repo.start_write_group()
56
        self.addCleanup(repo.abort_write_group)
57
        # Don't need a specific class - not expecting flow control based on
58
        # this.
59
        self.assertRaises(errors.BzrError, repo.fetch, repo)
60
4060.1.4 by Robert Collins
Streaming fetch from remote servers.
61
    def test_fetch_to_knit3(self):
2696.3.2 by Martin Pool
Move some per-repository tests from big test_repository to test_fetch
62
        # create a repository of the sort we are testing.
3242.2.17 by Aaron Bentley
Fix broken tests
63
        tree_a = self.make_branch_and_tree('a')
2696.3.2 by Martin Pool
Move some per-repository tests from big test_repository to test_fetch
64
        self.build_tree(['a/foo'])
65
        tree_a.add('foo', 'file1')
66
        tree_a.commit('rev1', rev_id='rev1')
67
        # create a knit-3 based format to fetch into
68
        f = bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
69
        try:
70
            format = tree_a.branch.repository._format
71
            format.check_conversion_target(f.repository_format)
72
            # if we cannot convert data to knit3, skip the test.
73
        except errors.BadConversionTarget, e:
74
            raise TestSkipped(str(e))
75
        self.get_transport().mkdir('b')
76
        b_bzrdir = f.initialize(self.get_url('b'))
77
        knit3_repo = b_bzrdir.create_repository()
78
        # fetch with a default limit (grab everything)
79
        knit3_repo.fetch(tree_a.branch.repository, revision_id=None)
2592.3.96 by Robert Collins
Merge index improvements (includes bzr.dev).
80
        # Reopen to avoid any in-memory caching - ensure its reading from
81
        # disk.
82
        knit3_repo = b_bzrdir.open_repository()
2696.3.2 by Martin Pool
Move some per-repository tests from big test_repository to test_fetch
83
        rev1_tree = knit3_repo.revision_tree('rev1')
3350.6.4 by Robert Collins
First cut at pluralised VersionedFiles. Some rather massive API incompatabilities, primarily because of the difficulty of coherence among competing stores.
84
        rev1_tree.lock_read()
85
        try:
86
            lines = rev1_tree.get_file_lines(rev1_tree.get_root_id())
87
        finally:
88
            rev1_tree.unlock()
2696.3.2 by Martin Pool
Move some per-repository tests from big test_repository to test_fetch
89
        self.assertEqual([], lines)
90
        b_branch = b_bzrdir.create_branch()
91
        b_branch.pull(tree_a.branch)
92
        try:
93
            tree_b = b_bzrdir.create_workingtree()
94
        except errors.NotLocalUrl:
4060.1.4 by Robert Collins
Streaming fetch from remote servers.
95
            try:
96
                tree_b = b_branch.create_checkout('b', lightweight=True)
97
            except errors.NotLocalUrl:
98
                raise TestSkipped("cannot make working tree with transport %r"
2696.3.2 by Martin Pool
Move some per-repository tests from big test_repository to test_fetch
99
                              % b_bzrdir.transport)
100
        tree_b.commit('no change', rev_id='rev2')
101
        rev2_tree = knit3_repo.revision_tree('rev2')
102
        self.assertEqual('rev1', rev2_tree.inventory.root.revision)
2696.3.9 by Martin Pool
merge trunk
103
4324.3.1 by Robert Collins
When adding rich root data follow the standard revision graph rules, so it does not create 'inconstent parents'.
104
    def do_test_fetch_to_rich_root_sets_parents_correctly(self, result,
105
        snapshots, root_id=ROOT_ID, allow_lefthand_ghost=False):
106
        """Assert that result is the parents of 'tip' after fetching snapshots.
107
108
        This helper constructs a 1.9 format source, and a test-format target
109
        and fetches the result of building snapshots in the source, then
110
        asserts that the parents of tip are result.
111
112
        :param result: A parents list for the inventories.get_parent_map call.
113
        :param snapshots: An iterable of snapshot parameters for
114
            BranchBuilder.build_snapshot.
115
        '"""
116
        # This overlaps slightly with the tests for commit builder about graph
117
        # consistency.
118
        # Cases:
119
        repo = self.make_repository('target')
4324.3.3 by Robert Collins
Fix silly typo.
120
        remote_format = isinstance(repo, remote.RemoteRepository)
4324.3.1 by Robert Collins
When adding rich root data follow the standard revision graph rules, so it does not create 'inconstent parents'.
121
        if not repo._format.rich_root_data and not remote_format:
122
            return # not relevant
123
        builder = self.make_branch_builder('source', format='1.9')
124
        builder.start_series()
125
        for revision_id, parent_ids, actions in snapshots:
126
            builder.build_snapshot(revision_id, parent_ids, actions,
127
            allow_leftmost_as_ghost=allow_lefthand_ghost)
128
        builder.finish_series()
129
        source = builder.get_branch()
130
        if remote_format and not repo._format.rich_root_data:
131
            # use a manual rich root format to ensure the code path is tested.
132
            repo = self.make_repository('remote-target',
133
                format='1.9-rich-root')
134
        repo.lock_write()
135
        self.addCleanup(repo.unlock)
136
        repo.fetch(source.repository)
137
        self.assertEqual(result,
138
            repo.texts.get_parent_map([(root_id, 'tip')])[(root_id, 'tip')])
139
140
    def test_fetch_to_rich_root_set_parent_no_parents(self):
141
        # No parents rev -> No parents
142
        self.do_test_fetch_to_rich_root_sets_parents_correctly((),
143
            [('tip', None, [('add', ('', ROOT_ID, 'directory', ''))]),
144
            ])
145
146
    def test_fetch_to_rich_root_set_parent_1_parent(self):
147
        # 1 parent rev -> 1 parent 
148
        self.do_test_fetch_to_rich_root_sets_parents_correctly(
149
            ((ROOT_ID, 'base'),),
150
            [('base', None, [('add', ('', ROOT_ID, 'directory', ''))]),
151
             ('tip', None, []),
152
            ])
153
154
    def test_fetch_to_rich_root_set_parent_1_ghost_parent(self):
155
        # 1 ghost parent -> No parents
156
        self.do_test_fetch_to_rich_root_sets_parents_correctly((),
157
            [('tip', ['ghost'], [('add', ('', ROOT_ID, 'directory', ''))]),
158
            ], allow_lefthand_ghost=True)
159
160
    def test_fetch_to_rich_root_set_parent_2_head_parents(self):
161
        # 2 parents both heads -> 2 parents
162
        self.do_test_fetch_to_rich_root_sets_parents_correctly(
163
            ((ROOT_ID, 'left'), (ROOT_ID, 'right')),
164
            [('base', None, [('add', ('', ROOT_ID, 'directory', ''))]),
165
             ('left', None, []),
166
             ('right', ['base'], []),
167
             ('tip', ['left', 'right'], []),
168
            ])
169
170
    def test_fetch_to_rich_root_set_parent_2_parents_1_head(self):
171
        # 2 parents one head -> 1 parent
172
        self.do_test_fetch_to_rich_root_sets_parents_correctly(
173
            ((ROOT_ID, 'right'),),
174
            [('left', None, [('add', ('', ROOT_ID, 'directory', ''))]),
175
             ('right', None, []),
176
             ('tip', ['left', 'right'], []),
177
            ])
178
179
    def test_fetch_to_rich_root_set_parent_1_parent_different_id_gone(self):
180
        # 1 parent different fileid, ours missing -> no parents
181
        self.do_test_fetch_to_rich_root_sets_parents_correctly(
182
            (),
183
            [('base', None, [('add', ('', ROOT_ID, 'directory', ''))]),
184
             ('tip', None, [('unversion', ROOT_ID),
185
                            ('add', ('', 'my-root', 'directory', '')),
186
                            ]),
187
            ], root_id='my-root')
188
189
    def test_fetch_to_rich_root_set_parent_1_parent_different_id_moved(self):
190
        # 1 parent different fileid, ours moved -> 1 parent
191
        # (and that parent honours the changing revid of the other location)
192
        self.do_test_fetch_to_rich_root_sets_parents_correctly(
193
            (('my-root', 'origin'),),
194
            [('origin', None, [('add', ('', ROOT_ID, 'directory', '')),
195
                             ('add', ('child', 'my-root', 'directory', ''))]),
196
             ('base', None, []),
197
             ('tip', None, [('unversion', 'my-root'),
198
                            ('unversion', ROOT_ID),
199
                            ('add', ('', 'my-root', 'directory', '')),
200
                            ]),
201
            ], root_id='my-root')
202
203
    def test_fetch_to_rich_root_set_parent_2_parent_1_different_id_gone(self):
204
        # 2 parents, 1 different fileid, our second missing -> 1 parent
205
        self.do_test_fetch_to_rich_root_sets_parents_correctly(
206
            (('my-root', 'right'),),
207
            [('base', None, [('add', ('', ROOT_ID, 'directory', ''))]),
208
             ('right', None, [('unversion', ROOT_ID),
209
                              ('add', ('', 'my-root', 'directory', ''))]),
210
             ('tip', ['base', 'right'], [('unversion', ROOT_ID),
211
                            ('add', ('', 'my-root', 'directory', '')),
212
                            ]),
213
            ], root_id='my-root')
214
215
    def test_fetch_to_rich_root_set_parent_2_parent_2_different_id_moved(self):
216
        # 2 parents, 1 different fileid, our second moved -> 2 parent
217
        # (and that parent honours the changing revid of the other location)
218
        self.do_test_fetch_to_rich_root_sets_parents_correctly(
219
            (('my-root', 'right'),),
220
            # 'my-root' at 'child'.
221
            [('origin', None, [('add', ('', ROOT_ID, 'directory', '')),
222
                             ('add', ('child', 'my-root', 'directory', ''))]),
223
             ('base', None, []),
224
            # 'my-root' at root
225
             ('right', None, [('unversion', 'my-root'),
226
                              ('unversion', ROOT_ID),
227
                              ('add', ('', 'my-root', 'directory', ''))]),
228
             ('tip', ['base', 'right'], [('unversion', 'my-root'),
229
                            ('unversion', ROOT_ID),
230
                            ('add', ('', 'my-root', 'directory', '')),
231
                            ]),
232
            ], root_id='my-root')
233
2948.3.1 by John Arbash Meinel
Fix bug #158333, make sure that Repository.fetch(self) is properly a no-op for all Repository implementations.
234
    def test_fetch_all_from_self(self):
235
        tree = self.make_branch_and_tree('.')
236
        rev_id = tree.commit('one')
237
        # This needs to be a new copy of the repository, if this changes, the
238
        # test needs to be rewritten
239
        repo = tree.branch.repository.bzrdir.open_repository()
240
        # This fetch should be a no-op see bug #158333
241
        tree.branch.repository.fetch(repo, None)
242
243
    def test_fetch_from_self(self):
244
        tree = self.make_branch_and_tree('.')
245
        rev_id = tree.commit('one')
246
        repo = tree.branch.repository.bzrdir.open_repository()
247
        # This fetch should be a no-op see bug #158333
248
        tree.branch.repository.fetch(repo, rev_id)
249
250
    def test_fetch_missing_from_self(self):
251
        tree = self.make_branch_and_tree('.')
252
        rev_id = tree.commit('one')
253
        # Even though the fetch() is a NO-OP it should assert the revision id
254
        # is present
255
        repo = tree.branch.repository.bzrdir.open_repository()
256
        self.assertRaises(errors.NoSuchRevision, tree.branch.repository.fetch,
257
                          repo, 'no-such-revision')
258
2696.3.9 by Martin Pool
merge trunk
259
    def makeARepoWithSignatures(self):
260
        wt = self.make_branch_and_tree('a-repo-with-sigs')
261
        wt.commit('rev1', allow_pointless=True, rev_id='rev1')
262
        repo = wt.branch.repository
2592.3.96 by Robert Collins
Merge index improvements (includes bzr.dev).
263
        repo.lock_write()
264
        repo.start_write_group()
2592.3.103 by Robert Collins
Fix some more pack-related test breakage.
265
        repo.sign_revision('rev1', gpg.LoopbackGPGStrategy(None))
2592.3.96 by Robert Collins
Merge index improvements (includes bzr.dev).
266
        repo.commit_write_group()
267
        repo.unlock()
2696.3.9 by Martin Pool
merge trunk
268
        return repo
269
270
    def test_fetch_copies_signatures(self):
271
        source_repo = self.makeARepoWithSignatures()
272
        target_repo = self.make_repository('target')
273
        target_repo.fetch(source_repo, revision_id=None)
274
        self.assertEqual(
275
            source_repo.get_signature_text('rev1'),
276
            target_repo.get_signature_text('rev1'))
2535.3.48 by Andrew Bennetts
Merge from bzr.dev.
277
278
    def make_repository_with_one_revision(self):
3242.2.17 by Aaron Bentley
Fix broken tests
279
        wt = self.make_branch_and_tree('source')
2535.3.48 by Andrew Bennetts
Merge from bzr.dev.
280
        wt.commit('rev1', allow_pointless=True, rev_id='rev1')
281
        return wt.branch.repository
282
283
    def test_fetch_revision_already_exists(self):
284
        # Make a repository with one revision.
285
        source_repo = self.make_repository_with_one_revision()
286
        # Fetch that revision into a second repository.
287
        target_repo = self.make_repository('target')
288
        target_repo.fetch(source_repo, revision_id='rev1')
289
        # Now fetch again; there will be nothing to do.  This should work
290
        # without causing any errors.
291
        target_repo.fetch(source_repo, revision_id='rev1')
292
1551.19.36 by Aaron Bentley
Prevent fetch all from causing pack collisions
293
    def test_fetch_all_same_revisions_twice(self):
294
        # Blind-fetching all the same revisions twice should succeed and be a
295
        # no-op the second time.
296
        repo = self.make_repository('repo')
297
        tree = self.make_branch_and_tree('tree')
298
        revision_id = tree.commit('test')
299
        repo.fetch(tree.branch.repository)
300
        repo.fetch(tree.branch.repository)