/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
1
# Copyright (C) 2005, 2006, 2008 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
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
16
17
18
import sys
19
20
from bzrlib import (
21
    errors,
3735.2.135 by Robert Collins
Permit fetching bzr.dev [deal with inconsistent inventories.]
22
    inventory,
23
    osutils,
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
24
    repository,
3735.2.135 by Robert Collins
Permit fetching bzr.dev [deal with inconsistent inventories.]
25
    versionedfile,
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
26
    )
27
from bzrlib.errors import (
28
    NoSuchRevision,
29
    )
4476.3.11 by Andrew Bennetts
All fetch and interrepo tests passing.
30
from bzrlib.graph import (
31
    SearchResult,
32
    )
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
33
from bzrlib.revision import (
34
    NULL_REVISION,
35
    Revision,
36
    )
37
from bzrlib.tests import (
38
    TestNotApplicable,
39
    )
4523.1.3 by Martin Pool
Rename to per_interrepository
40
from bzrlib.tests.per_interrepository import (
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
41
    TestCaseWithInterRepository,
42
    )
4523.1.3 by Martin Pool
Rename to per_interrepository
43
from bzrlib.tests.per_interrepository.test_interrepository import (
3616.2.3 by Mark Hammond
Fix test failures due to missing check_repo_format_for_funky_id_on_win32
44
    check_repo_format_for_funky_id_on_win32
45
    )
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
46
47
4634.35.22 by Andrew Bennetts
Use monkey patching to avoid skipping (mostly) tests that try to create damaged repos on 2a.
48
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
49
class TestInterRepository(TestCaseWithInterRepository):
50
4634.35.22 by Andrew Bennetts
Use monkey patching to avoid skipping (mostly) tests that try to create damaged repos on 2a.
51
    def disable_commit_write_group_paranoia(self, repo):
52
        pack_coll = getattr(repo, '_pack_collection', None)
53
        if pack_coll is not None:
54
            # Monkey-patch the pack collection instance to allow storing
55
            # incomplete revisions.
56
            pack_coll._check_new_inventories = lambda: []
57
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
58
    def test_fetch(self):
59
        tree_a = self.make_branch_and_tree('a')
60
        self.build_tree(['a/foo'])
61
        tree_a.add('foo', 'file1')
62
        tree_a.commit('rev1', rev_id='rev1')
63
        def check_push_rev1(repo):
64
            # ensure the revision is missing.
65
            self.assertRaises(NoSuchRevision, repo.get_revision, 'rev1')
4110.2.5 by Martin Pool
Deprecate passing pbs in to fetch()
66
            # fetch with a limit of NULL_REVISION
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
67
            repo.fetch(tree_a.branch.repository,
4110.2.5 by Martin Pool
Deprecate passing pbs in to fetch()
68
                       revision_id=NULL_REVISION)
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
69
            # nothing should have been pushed
70
            self.assertFalse(repo.has_revision('rev1'))
71
            # fetch with a default limit (grab everything)
72
            repo.fetch(tree_a.branch.repository)
73
            # check that b now has all the data from a's first commit.
74
            rev = repo.get_revision('rev1')
75
            tree = repo.revision_tree('rev1')
76
            tree.lock_read()
77
            self.addCleanup(tree.unlock)
78
            tree.get_file_text('file1')
79
            for file_id in tree:
80
                if tree.inventory[file_id].kind == "file":
81
                    tree.get_file(file_id).read()
82
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
83
        # makes a target version repo
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
84
        repo_b = self.make_to_repository('b')
85
        check_push_rev1(repo_b)
86
3735.2.135 by Robert Collins
Permit fetching bzr.dev [deal with inconsistent inventories.]
87
    def test_fetch_inconsistent_last_changed_entries(self):
88
        """If an inventory has odd data we should still get what it references.
3735.31.2 by John Arbash Meinel
Cleanup trailing whitespace, get test_source to pass by removing asserts.
89
3735.2.135 by Robert Collins
Permit fetching bzr.dev [deal with inconsistent inventories.]
90
        This test tests that we do fetch a file text created in a revision not
91
        being fetched, but referenced from the revision we are fetching when the
92
        adjacent revisions to the one being fetched do not reference that text.
93
        """
94
        tree = self.make_branch_and_tree('source')
95
        revid = tree.commit('old')
96
        to_repo = self.make_to_repository('to_repo')
97
        to_repo.fetch(tree.branch.repository, revid)
98
        # Make a broken revision and fetch it.
99
        source = tree.branch.repository
100
        source.lock_write()
101
        self.addCleanup(source.unlock)
102
        source.start_write_group()
103
        try:
104
            # We need two revisions: OLD and NEW. NEW will claim to need a file
105
            # 'FOO' changed in 'OLD'. OLD will not have that file at all.
106
            source.texts.insert_record_stream([
107
                versionedfile.FulltextContentFactory(('foo', revid), (), None,
108
                'contents')])
109
            basis = source.revision_tree(revid)
110
            parent_id = basis.path2id('')
111
            entry = inventory.make_entry('file', 'foo-path', parent_id, 'foo')
112
            entry.revision = revid
113
            entry.text_size = len('contents')
114
            entry.text_sha1 = osutils.sha_string('contents')
115
            inv_sha1, _ = source.add_inventory_by_delta(revid, [
116
                (None, 'foo-path', 'foo', entry)], 'new', [revid])
117
            rev = Revision(timestamp=0,
118
                           timezone=None,
119
                           committer="Foo Bar <foo@example.com>",
120
                           message="Message",
121
                           inventory_sha1=inv_sha1,
122
                           revision_id='new',
123
                           parent_ids=[revid])
124
            source.add_revision(rev.revision_id, rev)
125
        except:
126
            source.abort_write_group()
127
            raise
128
        else:
129
            source.commit_write_group()
130
        to_repo.fetch(source, 'new')
131
        to_repo.lock_read()
132
        self.addCleanup(to_repo.unlock)
133
        self.assertEqual('contents',
134
            to_repo.texts.get_record_stream([('foo', revid)],
135
            'unordered', True).next().get_bytes_as('fulltext'))
136
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
137
    def test_fetch_parent_inventories_at_stacking_boundary_smart(self):
138
        self.setup_smart_server_with_call_log()
139
        self.test_fetch_parent_inventories_at_stacking_boundary()
140
141
    def test_fetch_parent_inventories_at_stacking_boundary_smart_old(self):
142
        self.setup_smart_server_with_call_log()
4476.3.82 by Andrew Bennetts
Mention another bug fix in NEWS, and update verb name, comments, and NEWS additions for landing on 1.19 rather than 1.18.
143
        self.disable_verb('Repository.insert_stream_1.19')
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
144
        self.test_fetch_parent_inventories_at_stacking_boundary()
145
4257.3.1 by Andrew Bennetts
Add failing test.
146
    def test_fetch_parent_inventories_at_stacking_boundary(self):
4257.3.9 by Andrew Bennetts
Add fix to InterDifferingSerializer too, although it's pretty ugly.
147
        """Fetch to a stacked branch copies inventories for parents of
148
        revisions at the stacking boundary.
149
150
        This is necessary so that the server is able to determine the file-ids
151
        altered by all revisions it contains, which means that it needs both
152
        the inventory for any revision it has, and the inventories of all that
153
        revision's parents.
4597.1.2 by John Arbash Meinel
Fix the second half of bug #402778
154
155
        However, we should also skip any revisions which are ghosts in the
156
        parents.
4257.3.9 by Andrew Bennetts
Add fix to InterDifferingSerializer too, although it's pretty ugly.
157
        """
4597.1.5 by John Arbash Meinel
Split the 'ghost' test into a second test.
158
        if not self.repository_format_to.supports_external_lookups:
4257.3.1 by Andrew Bennetts
Add failing test.
159
            raise TestNotApplicable("Need stacking support in the target.")
160
        builder = self.make_branch_builder('branch')
161
        builder.start_series()
162
        builder.build_snapshot('base', None, [
4597.1.1 by John Arbash Meinel
fix a critical bug #402778
163
            ('add', ('', 'root-id', 'directory', '')),
164
            ('add', ('file', 'file-id', 'file', 'content\n'))])
165
        builder.build_snapshot('left', ['base'], [
166
            ('modify', ('file-id', 'left content\n'))])
167
        builder.build_snapshot('right', ['base'], [
168
            ('modify', ('file-id', 'right content\n'))])
4597.1.5 by John Arbash Meinel
Split the 'ghost' test into a second test.
169
        builder.build_snapshot('merge', ['left', 'right'], [
4597.1.1 by John Arbash Meinel
fix a critical bug #402778
170
            ('modify', ('file-id', 'left and right content\n'))])
4257.3.1 by Andrew Bennetts
Add failing test.
171
        builder.finish_series()
172
        branch = builder.get_branch()
173
        repo = self.make_to_repository('trunk')
174
        trunk = repo.bzrdir.create_branch()
175
        trunk.repository.fetch(branch.repository, 'left')
176
        trunk.repository.fetch(branch.repository, 'right')
177
        repo = self.make_to_repository('stacked')
178
        stacked_branch = repo.bzrdir.create_branch()
179
        stacked_branch.set_stacked_on_url(trunk.base)
180
        stacked_branch.repository.fetch(branch.repository, 'merge')
181
        unstacked_repo = stacked_branch.bzrdir.open_repository()
182
        unstacked_repo.lock_read()
183
        self.addCleanup(unstacked_repo.unlock)
4476.3.73 by Andrew Bennetts
Remove smelly if guard from interrepo fetch stacking test, it's not necessary.
184
        self.assertFalse(unstacked_repo.has_revision('left'))
185
        self.assertFalse(unstacked_repo.has_revision('right'))
4257.3.1 by Andrew Bennetts
Add failing test.
186
        self.assertEqual(
4257.3.2 by Andrew Bennetts
Check during fetch if we are going to be missing data necessary to calculate altered fileids for stacked revisions.
187
            set([('left',), ('right',), ('merge',)]),
4257.3.1 by Andrew Bennetts
Add failing test.
188
            unstacked_repo.inventories.keys())
4597.1.1 by John Arbash Meinel
fix a critical bug #402778
189
        # And the basis inventories have been copied correctly
190
        trunk.lock_read()
191
        self.addCleanup(trunk.unlock)
192
        left_tree, right_tree = trunk.repository.revision_trees(
193
            ['left', 'right'])
194
        stacked_branch.lock_read()
195
        self.addCleanup(stacked_branch.unlock)
196
        (stacked_left_tree,
197
         stacked_right_tree) = stacked_branch.repository.revision_trees(
198
            ['left', 'right'])
199
        self.assertEqual(left_tree.inventory, stacked_left_tree.inventory)
200
        self.assertEqual(right_tree.inventory, stacked_right_tree.inventory)
4257.3.1 by Andrew Bennetts
Add failing test.
201
4476.3.81 by Andrew Bennetts
Merge bzr.dev. Fix some minor fallout. per_interrepository/test_fetch.py has some duplicated assertions as a first pass at resolving conflicts.
202
        # Finally, it's not enough to see that the basis inventories are
203
        # present.  The texts introduced in merge (and only those) should be
204
        # present, and also generating a stream should succeed without blowing
205
        # up.
4476.3.11 by Andrew Bennetts
All fetch and interrepo tests passing.
206
        self.assertTrue(unstacked_repo.has_revision('merge'))
4476.3.81 by Andrew Bennetts
Merge bzr.dev. Fix some minor fallout. per_interrepository/test_fetch.py has some duplicated assertions as a first pass at resolving conflicts.
207
        expected_texts = set([('file-id', 'merge')])
208
        if stacked_branch.repository.texts.get_parent_map([('root-id',
209
            'merge')]):
210
            # If a (root-id,merge) text exists, it should be in the stacked
211
            # repo.
212
            expected_texts.add(('root-id', 'merge'))
213
        self.assertEqual(expected_texts, unstacked_repo.texts.keys())
4476.3.11 by Andrew Bennetts
All fetch and interrepo tests passing.
214
        self.assertCanStreamRevision(unstacked_repo, 'merge')
215
216
    def assertCanStreamRevision(self, repo, revision_id):
217
        exclude_keys = set(repo.all_revision_ids()) - set([revision_id])
218
        search = SearchResult([revision_id], exclude_keys, 1, [revision_id])
219
        source = repo._get_source(repo._format)
220
        for substream_kind, substream in source.get_stream(search):
221
            # Consume the substream
222
            list(substream)
4257.3.1 by Andrew Bennetts
Add failing test.
223
4597.1.5 by John Arbash Meinel
Split the 'ghost' test into a second test.
224
    def test_fetch_across_stacking_boundary_ignores_ghost(self):
225
        if not self.repository_format_to.supports_external_lookups:
226
            raise TestNotApplicable("Need stacking support in the target.")
227
        to_repo = self.make_to_repository('to')
228
        builder = self.make_branch_builder('branch')
229
        builder.start_series()
230
        builder.build_snapshot('base', None, [
231
            ('add', ('', 'root-id', 'directory', '')),
232
            ('add', ('file', 'file-id', 'file', 'content\n'))])
233
        builder.build_snapshot('second', ['base'], [
234
            ('modify', ('file-id', 'second content\n'))])
235
        builder.build_snapshot('third', ['second', 'ghost'], [
236
            ('modify', ('file-id', 'third content\n'))])
237
        builder.finish_series()
238
        branch = builder.get_branch()
239
        repo = self.make_to_repository('trunk')
240
        trunk = repo.bzrdir.create_branch()
241
        trunk.repository.fetch(branch.repository, 'second')
242
        repo = self.make_to_repository('stacked')
243
        stacked_branch = repo.bzrdir.create_branch()
244
        stacked_branch.set_stacked_on_url(trunk.base)
245
        stacked_branch.repository.fetch(branch.repository, 'third')
246
        unstacked_repo = stacked_branch.bzrdir.open_repository()
247
        unstacked_repo.lock_read()
248
        self.addCleanup(unstacked_repo.unlock)
249
        self.assertFalse(unstacked_repo.has_revision('second'))
250
        self.assertFalse(unstacked_repo.has_revision('ghost'))
251
        self.assertEqual(
252
            set([('second',), ('third',)]),
253
            unstacked_repo.inventories.keys())
254
        # And the basis inventories have been copied correctly
255
        trunk.lock_read()
256
        self.addCleanup(trunk.unlock)
257
        second_tree = trunk.repository.revision_tree('second')
258
        stacked_branch.lock_read()
259
        self.addCleanup(stacked_branch.unlock)
260
        stacked_second_tree = stacked_branch.repository.revision_tree('second')
261
        self.assertEqual(second_tree.inventory, stacked_second_tree.inventory)
4476.3.81 by Andrew Bennetts
Merge bzr.dev. Fix some minor fallout. per_interrepository/test_fetch.py has some duplicated assertions as a first pass at resolving conflicts.
262
        # Finally, it's not enough to see that the basis inventories are
263
        # present.  The texts introduced in merge (and only those) should be
264
        # present, and also generating a stream should succeed without blowing
265
        # up.
266
        self.assertTrue(unstacked_repo.has_revision('third'))
267
        expected_texts = set([('file-id', 'third')])
268
        if stacked_branch.repository.texts.get_parent_map([('root-id',
269
            'third')]):
270
            # If a (root-id,third) text exists, it should be in the stacked
271
            # repo.
272
            expected_texts.add(('root-id', 'third'))
273
        self.assertEqual(expected_texts, unstacked_repo.texts.keys())
274
        self.assertCanStreamRevision(unstacked_repo, 'third')
4597.1.5 by John Arbash Meinel
Split the 'ghost' test into a second test.
275
4627.3.4 by Andrew Bennetts
Add a (long) test that fails without the fix.
276
    def test_fetch_from_stacked_to_stacked_copies_parent_inventories(self):
277
        """Fetch from a stacked branch copies inventories for parents of
278
        revisions at the stacking boundary.
279
280
        Specifically, fetch will copy the parent inventories from the
281
        source for which the corresponding revisions are not present.  This
282
        will happen even when the source repository has no fallbacks configured
283
        (as is the case during upgrade).
284
        """
285
        if not self.repository_format.supports_external_lookups:
286
            raise TestNotApplicable("Need stacking support in the source.")
287
        if not self.repository_format_to.supports_external_lookups:
288
            raise TestNotApplicable("Need stacking support in the target.")
289
        builder = self.make_branch_builder('branch')
290
        builder.start_series()
291
        builder.build_snapshot('base', None, [
292
            ('add', ('', 'root-id', 'directory', '')),
293
            ('add', ('file', 'file-id', 'file', 'content\n'))])
294
        builder.build_snapshot('left', ['base'], [
295
            ('modify', ('file-id', 'left content\n'))])
296
        builder.build_snapshot('right', ['base'], [
297
            ('modify', ('file-id', 'right content\n'))])
298
        builder.build_snapshot('merge', ['left', 'right'], [
299
            ('modify', ('file-id', 'left and right content\n'))])
300
        builder.finish_series()
301
        branch = builder.get_branch()
302
        repo = self.make_repository('old-trunk')
303
        # Make a pair of equivalent trunk repos in the from and to formats.
304
        old_trunk = repo.bzrdir.create_branch()
305
        old_trunk.repository.fetch(branch.repository, 'left')
306
        old_trunk.repository.fetch(branch.repository, 'right')
307
        repo = self.make_to_repository('new-trunk')
308
        new_trunk = repo.bzrdir.create_branch()
309
        new_trunk.repository.fetch(branch.repository, 'left')
310
        new_trunk.repository.fetch(branch.repository, 'right')
311
        # Make the source; a repo stacked on old_trunk contained just the data
312
        # for 'merge'.
313
        repo = self.make_repository('old-stacked')
314
        old_stacked_branch = repo.bzrdir.create_branch()
315
        old_stacked_branch.set_stacked_on_url(old_trunk.base)
316
        old_stacked_branch.repository.fetch(branch.repository, 'merge')
317
        # Make the target, a repo stacked on new_trunk.
318
        repo = self.make_to_repository('new-stacked')
319
        new_stacked_branch = repo.bzrdir.create_branch()
320
        new_stacked_branch.set_stacked_on_url(new_trunk.base)
321
        old_unstacked_repo = old_stacked_branch.bzrdir.open_repository()
322
        new_unstacked_repo = new_stacked_branch.bzrdir.open_repository()
323
        # Reopen the source and target repos without any fallbacks, and fetch
324
        # 'merge'.
325
        new_unstacked_repo.fetch(old_unstacked_repo, 'merge')
326
        # Now check the results.  new_unstacked_repo should contain all the
327
        # data necessary to stream 'merge' (i.e. the parent inventories).
328
        new_unstacked_repo.lock_read()
329
        self.addCleanup(new_unstacked_repo.unlock)
330
        self.assertFalse(new_unstacked_repo.has_revision('left'))
331
        self.assertFalse(new_unstacked_repo.has_revision('right'))
332
        self.assertEqual(
333
            set([('left',), ('right',), ('merge',)]),
334
            new_unstacked_repo.inventories.keys())
335
        # And the basis inventories have been copied correctly
336
        new_trunk.lock_read()
337
        self.addCleanup(new_trunk.unlock)
338
        left_tree, right_tree = new_trunk.repository.revision_trees(
339
            ['left', 'right'])
340
        new_stacked_branch.lock_read()
341
        self.addCleanup(new_stacked_branch.unlock)
342
        (stacked_left_tree,
343
         stacked_right_tree) = new_stacked_branch.repository.revision_trees(
344
            ['left', 'right'])
345
        self.assertEqual(left_tree.inventory, stacked_left_tree.inventory)
346
        self.assertEqual(right_tree.inventory, stacked_right_tree.inventory)
347
        # Finally, it's not enough to see that the basis inventories are
348
        # present.  The texts introduced in merge (and only those) should be
349
        # present, and also generating a stream should succeed without blowing
350
        # up.
351
        self.assertTrue(new_unstacked_repo.has_revision('merge'))
352
        expected_texts = set([('file-id', 'merge')])
353
        if new_stacked_branch.repository.texts.get_parent_map([('root-id',
354
            'merge')]):
355
            # If a (root-id,merge) text exists, it should be in the stacked
356
            # repo.
357
            expected_texts.add(('root-id', 'merge'))
358
        self.assertEqual(expected_texts, new_unstacked_repo.texts.keys())
359
        self.assertCanStreamRevision(new_unstacked_repo, 'merge')
360
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
361
    def test_fetch_missing_basis_text(self):
362
        """If fetching a delta, we should die if a basis is not present."""
363
        tree = self.make_branch_and_tree('tree')
364
        self.build_tree(['tree/a'])
365
        tree.add(['a'], ['a-id'])
366
        tree.commit('one', rev_id='rev-one')
367
        self.build_tree_contents([('tree/a', 'new contents\n')])
368
        tree.commit('two', rev_id='rev-two')
369
370
        to_repo = self.make_to_repository('to_repo')
371
        # We build a broken revision so that we can test the fetch code dies
372
        # properly. So copy the inventory and revision, but not the text.
373
        to_repo.lock_write()
374
        try:
375
            to_repo.start_write_group()
4634.35.13 by Andrew Bennetts
Fix test_fetch_missing_basis_text to skip if commit_write_group on the target repo prevents making a broken revision.
376
            try:
377
                inv = tree.branch.repository.get_inventory('rev-one')
378
                to_repo.add_inventory('rev-one', inv, [])
379
                rev = tree.branch.repository.get_revision('rev-one')
380
                to_repo.add_revision('rev-one', rev, inv=inv)
4634.35.22 by Andrew Bennetts
Use monkey patching to avoid skipping (mostly) tests that try to create damaged repos on 2a.
381
                self.disable_commit_write_group_paranoia(to_repo)
382
                to_repo.commit_write_group()
4634.35.13 by Andrew Bennetts
Fix test_fetch_missing_basis_text to skip if commit_write_group on the target repo prevents making a broken revision.
383
            except:
384
                to_repo.abort_write_group(suppress_errors=True)
385
                raise
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
386
        finally:
387
            to_repo.unlock()
388
3350.3.21 by Robert Collins
Merge bzr.dev.
389
        # Implementations can either ensure that the target of the delta is
390
        # reconstructable, or raise an exception (which stream based copies
391
        # generally do).
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
392
        try:
393
            to_repo.fetch(tree.branch.repository, 'rev-two')
3830.3.12 by Martin Pool
Review cleanups: unify has_key impls, add missing_keys(), clean up exception blocks
394
        except (errors.BzrCheckError, errors.RevisionNotPresent), e:
395
            # If an exception is raised, the revision should not be in the
396
            # target.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
397
            #
3830.3.9 by Martin Pool
Simplify kvf insert_record_stream; add has_key shorthand methods; update stacking effort tests
398
            # Can also just raise a generic check errors; stream insertion
399
            # does this to include all the missing data
400
            self.assertRaises((errors.NoSuchRevision, errors.RevisionNotPresent),
401
                              to_repo.revision_tree, 'rev-two')
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
402
        else:
3350.3.21 by Robert Collins
Merge bzr.dev.
403
            # If not exception is raised, then the text should be
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
404
            # available.
405
            to_repo.lock_read()
406
            try:
3350.3.21 by Robert Collins
Merge bzr.dev.
407
                rt = to_repo.revision_tree('rev-two')
408
                self.assertEqual('new contents\n',
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
409
                                 rt.get_file_text('a-id'))
410
            finally:
411
                to_repo.unlock()
412
413
    def test_fetch_missing_revision_same_location_fails(self):
414
        repo_a = self.make_repository('.')
415
        repo_b = repository.Repository.open('.')
416
        try:
3350.3.21 by Robert Collins
Merge bzr.dev.
417
            self.assertRaises(errors.NoSuchRevision, repo_b.fetch, repo_a, revision_id='XXX')
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
418
        except errors.LockError, e:
419
            check_old_format_lock_error(self.repository_format)
420
421
    def test_fetch_same_location_trivial_works(self):
422
        repo_a = self.make_repository('.')
423
        repo_b = repository.Repository.open('.')
424
        try:
425
            repo_a.fetch(repo_b)
426
        except errors.LockError, e:
427
            check_old_format_lock_error(self.repository_format)
428
429
    def test_fetch_missing_text_other_location_fails(self):
430
        source_tree = self.make_branch_and_tree('source')
431
        source = source_tree.branch.repository
432
        target = self.make_to_repository('target')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
433
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
434
        # start by adding a file so the data knit for the file exists in
435
        # repositories that have specific files for each fileid.
436
        self.build_tree(['source/id'])
437
        source_tree.add(['id'], ['id'])
438
        source_tree.commit('a', rev_id='a')
439
        # now we manually insert a revision with an inventory referencing
4634.35.14 by Andrew Bennetts
Fix more tests to cope with new commit_write_group strictness.
440
        # file 'id' at revision 'b', but we do not insert revision b.
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
441
        # this should ensure that the new versions of files are being checked
442
        # for during pull operations
443
        inv = source.get_inventory('a')
444
        source.lock_write()
3380.1.5 by Aaron Bentley
Merge with make-it-work
445
        self.addCleanup(source.unlock)
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
446
        source.start_write_group()
447
        inv['id'].revision = 'b'
448
        inv.revision_id = 'b'
449
        sha1 = source.add_inventory('b', inv, ['a'])
450
        rev = Revision(timestamp=0,
451
                       timezone=None,
452
                       committer="Foo Bar <foo@example.com>",
453
                       message="Message",
454
                       inventory_sha1=sha1,
455
                       revision_id='b')
456
        rev.parent_ids = ['a']
457
        source.add_revision('b', rev)
4634.35.22 by Andrew Bennetts
Use monkey patching to avoid skipping (mostly) tests that try to create damaged repos on 2a.
458
        self.disable_commit_write_group_paranoia(source)
459
        source.commit_write_group()
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
460
        self.assertRaises(errors.RevisionNotPresent, target.fetch, source)
461
        self.assertFalse(target.has_revision('b'))
462
463
    def test_fetch_funky_file_id(self):
464
        from_tree = self.make_branch_and_tree('tree')
465
        if sys.platform == 'win32':
466
            from_repo = from_tree.branch.repository
467
            check_repo_format_for_funky_id_on_win32(from_repo)
468
        self.build_tree(['tree/filename'])
469
        from_tree.add('filename', 'funky-chars<>%&;"\'')
470
        from_tree.commit('commit filename')
471
        to_repo = self.make_to_repository('to')
3350.3.21 by Robert Collins
Merge bzr.dev.
472
        to_repo.fetch(from_tree.branch.repository, from_tree.get_parent_ids()[0])
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
473
3380.1.6 by Aaron Bentley
Ensure fetching munges sha1s
474
    def test_fetch_revision_hash(self):
475
        """Ensure that inventory hashes are updated by fetch"""
476
        from_tree = self.make_branch_and_tree('tree')
477
        from_tree.commit('foo', rev_id='foo-id')
478
        to_repo = self.make_to_repository('to')
479
        to_repo.fetch(from_tree.branch.repository)
480
        recorded_inv_sha1 = to_repo.get_inventory_sha1('foo-id')
4597.1.4 by John Arbash Meinel
Fix one test that assumed get_inventory_xml worked.
481
        to_repo.lock_read()
482
        self.addCleanup(to_repo.unlock)
483
        stream = to_repo.inventories.get_record_stream([('foo-id',)],
484
                                                       'unordered', True)
485
        bytes = stream.next().get_bytes_as('fulltext')
486
        computed_inv_sha1 = osutils.sha_string(bytes)
3380.1.6 by Aaron Bentley
Ensure fetching munges sha1s
487
        self.assertEqual(computed_inv_sha1, recorded_inv_sha1)
488
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
489
490
class TestFetchDependentData(TestCaseWithInterRepository):
491
492
    def test_reference(self):
493
        from_tree = self.make_branch_and_tree('tree')
494
        to_repo = self.make_to_repository('to')
495
        if (not from_tree.supports_tree_reference() or
496
            not from_tree.branch.repository._format.supports_tree_reference or
497
            not to_repo._format.supports_tree_reference):
498
            raise TestNotApplicable("Need subtree support.")
499
        subtree = self.make_branch_and_tree('tree/subtree')
500
        subtree.commit('subrev 1')
501
        from_tree.add_reference(subtree)
502
        tree_rev = from_tree.commit('foo')
503
        # now from_tree has a last-modified of subtree of the rev id of the
504
        # commit for foo, and a reference revision of the rev id of the commit
505
        # for subrev 1
506
        to_repo.fetch(from_tree.branch.repository, tree_rev)
507
        # to_repo should have a file_graph for from_tree.path2id('subtree') and
508
        # revid tree_rev.
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.
509
        file_id = from_tree.path2id('subtree')
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
510
        to_repo.lock_read()
511
        try:
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.
512
            self.assertEqual({(file_id, tree_rev):()},
513
                to_repo.texts.get_parent_map([(file_id, tree_rev)]))
3380.1.4 by Aaron Bentley
Split interrepository fetch tests into their own file
514
        finally:
515
            to_repo.unlock()