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