/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/per_interrepository/test_fetch.py

Merge python3-j.

Show diffs side-by-side

added added

removed removed

Lines of Context:
60
60
    def test_fetch(self):
61
61
        tree_a = self.make_branch_and_tree('a')
62
62
        self.build_tree(['a/foo'])
63
 
        tree_a.add('foo', 'file1')
64
 
        tree_a.commit('rev1', rev_id=b'rev1')
 
63
        tree_a.add('foo')
 
64
        rev1 = tree_a.commit('rev1')
65
65
        def check_push_rev1(repo):
66
66
            # ensure the revision is missing.
67
 
            self.assertRaises(NoSuchRevision, repo.get_revision, b'rev1')
 
67
            self.assertRaises(NoSuchRevision, repo.get_revision, rev1)
68
68
            # fetch with a limit of NULL_REVISION
69
69
            repo.fetch(tree_a.branch.repository,
70
70
                       revision_id=NULL_REVISION)
71
71
            # nothing should have been pushed
72
 
            self.assertFalse(repo.has_revision(b'rev1'))
 
72
            self.assertFalse(repo.has_revision(rev1))
73
73
            # fetch with a default limit (grab everything)
74
 
            repo.fetch(tree_a.branch.repository)
 
74
            try:
 
75
                repo.fetch(tree_a.branch.repository)
 
76
            except errors.NoRoundtrippingSupport:
 
77
                raise TestNotApplicable('roundtripping not supported')
75
78
            # check that b now has all the data from a's first commit.
76
 
            rev = repo.get_revision(b'rev1')
77
 
            tree = repo.revision_tree(b'rev1')
 
79
            rev = repo.get_revision(rev1)
 
80
            tree = repo.revision_tree(rev1)
78
81
            tree.lock_read()
79
82
            self.addCleanup(tree.unlock)
80
83
            tree.get_file_text('foo')
81
84
            for path in tree.all_versioned_paths():
82
85
                if tree.kind(path) == "file":
83
 
                    tree.get_file(path).read()
 
86
                    with tree.get_file(path) as f:
 
87
                        f.read()
84
88
 
85
89
        # makes a target version repo
86
90
        repo_b = self.make_to_repository('b')
93
97
        being fetched, but referenced from the revision we are fetching when the
94
98
        adjacent revisions to the one being fetched do not reference that text.
95
99
        """
 
100
        if not self.repository_format.supports_full_versioned_files:
 
101
            raise TestNotApplicable('Need full versioned files')
96
102
        tree = self.make_branch_and_tree('source')
97
103
        revid = tree.commit('old')
98
104
        to_repo = self.make_to_repository('to_repo')
99
 
        to_repo.fetch(tree.branch.repository, revid)
 
105
        try:
 
106
            to_repo.fetch(tree.branch.repository, revid)
 
107
        except errors.NoRoundtrippingSupport:
 
108
            raise TestNotApplicable('roundtripping not supported')
100
109
        # Make a broken revision and fetch it.
101
110
        source = tree.branch.repository
102
111
        source.lock_write()
171
180
        stacked_branch.set_stacked_on_url(trunk.base)
172
181
        stacked_branch.repository.fetch(branch.repository, b'third')
173
182
        target = self.make_to_repository('target')
174
 
        target.fetch(stacked_branch.repository, b'third')
 
183
        try:
 
184
            target.fetch(stacked_branch.repository, b'third')
 
185
        except errors.NoRoundtrippingSupport:
 
186
            raise TestNotApplicable('roundtripping not supported')
175
187
        target.lock_read()
176
188
        self.addCleanup(target.unlock)
177
189
        all_revs = {b'first', b'second', b'third'}
205
217
            raise TestNotApplicable("Need stacking support in the target.")
206
218
        builder = self.make_branch_builder('branch')
207
219
        builder.start_series()
208
 
        builder.build_snapshot(None, [
209
 
            ('add', ('', b'root-id', 'directory', '')),
210
 
            ('add', ('file', b'file-id', 'file', b'content\n'))],
211
 
            revision_id=b'base')
212
 
        builder.build_snapshot([b'base'], [
213
 
            ('modify', ('file', b'left content\n'))],
214
 
            revision_id=b'left')
215
 
        builder.build_snapshot([b'base'], [
216
 
            ('modify', ('file', b'right content\n'))],
217
 
            revision_id=b'right')
218
 
        builder.build_snapshot([b'left', b'right'], [
219
 
            ('modify', ('file', b'left and right content\n'))],
220
 
            revision_id=b'merge')
 
220
        base = builder.build_snapshot(None, [
 
221
            ('add', ('', None, 'directory', '')),
 
222
            ('add', ('file', None, 'file', b'content\n'))])
 
223
        left = builder.build_snapshot([base], [
 
224
            ('modify', ('file', b'left content\n'))])
 
225
        right = builder.build_snapshot([base], [
 
226
            ('modify', ('file', b'right content\n'))])
 
227
        merge = builder.build_snapshot([left, right], [
 
228
            ('modify', ('file', b'left and right content\n'))])
221
229
        builder.finish_series()
222
230
        branch = builder.get_branch()
 
231
        revtree = branch.repository.revision_tree(merge)
 
232
        root_id = revtree.path2id('')
 
233
        file_id = revtree.path2id('file')
 
234
 
223
235
        repo = self.make_to_repository('trunk')
224
236
        trunk = repo.controldir.create_branch()
225
 
        trunk.repository.fetch(branch.repository, b'left')
226
 
        trunk.repository.fetch(branch.repository, b'right')
 
237
        trunk.repository.fetch(branch.repository, left)
 
238
        trunk.repository.fetch(branch.repository, right)
227
239
        repo = self.make_to_repository('stacked')
228
240
        stacked_branch = repo.controldir.create_branch()
229
241
        stacked_branch.set_stacked_on_url(trunk.base)
230
 
        stacked_branch.repository.fetch(branch.repository, b'merge')
 
242
        stacked_branch.repository.fetch(branch.repository, merge)
231
243
        unstacked_repo = stacked_branch.controldir.open_repository()
232
244
        unstacked_repo.lock_read()
233
245
        self.addCleanup(unstacked_repo.unlock)
234
 
        self.assertFalse(unstacked_repo.has_revision(b'left'))
235
 
        self.assertFalse(unstacked_repo.has_revision(b'right'))
 
246
        self.assertFalse(unstacked_repo.has_revision(left))
 
247
        self.assertFalse(unstacked_repo.has_revision(right))
236
248
        self.assertEqual(
237
 
            {(b'left',), (b'right',), (b'merge',)},
 
249
            {(left,), (right,), (merge,)},
238
250
            unstacked_repo.inventories.keys())
239
251
        # And the basis inventories have been copied correctly
240
252
        trunk.lock_read()
241
253
        self.addCleanup(trunk.unlock)
242
254
        left_tree, right_tree = trunk.repository.revision_trees(
243
 
            [b'left', b'right'])
 
255
            [left, right])
244
256
        stacked_branch.lock_read()
245
257
        self.addCleanup(stacked_branch.unlock)
246
258
        (stacked_left_tree,
247
259
         stacked_right_tree) = stacked_branch.repository.revision_trees(
248
 
            [b'left', b'right'])
 
260
            [left, right])
249
261
        self.assertEqual(
250
262
            left_tree.root_inventory, stacked_left_tree.root_inventory)
251
263
        self.assertEqual(
255
267
        # present.  The texts introduced in merge (and only those) should be
256
268
        # present, and also generating a stream should succeed without blowing
257
269
        # up.
258
 
        self.assertTrue(unstacked_repo.has_revision(b'merge'))
259
 
        expected_texts = {(b'file-id', b'merge')}
260
 
        if stacked_branch.repository.texts.get_parent_map([(b'root-id',
261
 
            b'merge')]):
 
270
        self.assertTrue(unstacked_repo.has_revision(merge))
 
271
        expected_texts = {(file_id, merge)}
 
272
        if stacked_branch.repository.texts.get_parent_map([(root_id,
 
273
            merge)]):
262
274
            # If a (root-id,merge) text exists, it should be in the stacked
263
275
            # repo.
264
 
            expected_texts.add((b'root-id', b'merge'))
 
276
            expected_texts.add((root_id, merge))
265
277
        self.assertEqual(expected_texts, unstacked_repo.texts.keys())
266
 
        self.assertCanStreamRevision(unstacked_repo, b'merge')
 
278
        self.assertCanStreamRevision(unstacked_repo, merge)
267
279
 
268
280
    def assertCanStreamRevision(self, repo, revision_id):
269
281
        exclude_keys = set(repo.all_revision_ids()) - {revision_id}
276
288
    def test_fetch_across_stacking_boundary_ignores_ghost(self):
277
289
        if not self.repository_format_to.supports_external_lookups:
278
290
            raise TestNotApplicable("Need stacking support in the target.")
 
291
        if not self.repository_format.supports_ghosts:
 
292
            raise TestNotApplicable("Need ghost support in the source.")
279
293
        to_repo = self.make_to_repository('to')
280
294
        builder = self.make_branch_builder('branch')
281
295
        builder.start_series()
282
 
        builder.build_snapshot(None, [
283
 
            ('add', ('', b'root-id', 'directory', '')),
284
 
            ('add', ('file', b'file-id', 'file', b'content\n'))],
285
 
            revision_id=b'base')
286
 
        builder.build_snapshot([b'base'], [
287
 
            ('modify', ('file', b'second content\n'))],
288
 
            revision_id=b'second')
289
 
        builder.build_snapshot([b'second', b'ghost'], [
290
 
            ('modify', ('file', b'third content\n'))],
291
 
            revision_id=b'third')
 
296
        base = builder.build_snapshot(None, [
 
297
            ('add', ('', None, 'directory', '')),
 
298
            ('add', ('file', None, 'file', b'content\n'))])
 
299
        second = builder.build_snapshot([base], [
 
300
            ('modify', ('file', b'second content\n'))])
 
301
        third = builder.build_snapshot([second, b'ghost'], [
 
302
            ('modify', ('file', b'third content\n'))])
292
303
        builder.finish_series()
293
304
        branch = builder.get_branch()
 
305
        revtree = branch.repository.revision_tree(base)
 
306
        root_id = revtree.path2id('')
 
307
        file_id = revtree.path2id('file')
294
308
        repo = self.make_to_repository('trunk')
295
309
        trunk = repo.controldir.create_branch()
296
 
        trunk.repository.fetch(branch.repository, b'second')
 
310
        trunk.repository.fetch(branch.repository, second)
297
311
        repo = self.make_to_repository('stacked')
298
312
        stacked_branch = repo.controldir.create_branch()
299
313
        stacked_branch.set_stacked_on_url(trunk.base)
300
 
        stacked_branch.repository.fetch(branch.repository, b'third')
 
314
        stacked_branch.repository.fetch(branch.repository, third)
301
315
        unstacked_repo = stacked_branch.controldir.open_repository()
302
316
        unstacked_repo.lock_read()
303
317
        self.addCleanup(unstacked_repo.unlock)
304
 
        self.assertFalse(unstacked_repo.has_revision(b'second'))
 
318
        self.assertFalse(unstacked_repo.has_revision(second))
305
319
        self.assertFalse(unstacked_repo.has_revision(b'ghost'))
306
320
        self.assertEqual(
307
 
            {(b'second',), (b'third',)},
 
321
            {(second,), (third,)},
308
322
            unstacked_repo.inventories.keys())
309
323
        # And the basis inventories have been copied correctly
310
324
        trunk.lock_read()
311
325
        self.addCleanup(trunk.unlock)
312
 
        second_tree = trunk.repository.revision_tree(b'second')
 
326
        second_tree = trunk.repository.revision_tree(second)
313
327
        stacked_branch.lock_read()
314
328
        self.addCleanup(stacked_branch.unlock)
315
 
        stacked_second_tree = stacked_branch.repository.revision_tree(b'second')
 
329
        stacked_second_tree = stacked_branch.repository.revision_tree(second)
316
330
        self.assertEqual(second_tree, stacked_second_tree)
317
331
        # Finally, it's not enough to see that the basis inventories are
318
332
        # present.  The texts introduced in merge (and only those) should be
319
333
        # present, and also generating a stream should succeed without blowing
320
334
        # up.
321
 
        self.assertTrue(unstacked_repo.has_revision(b'third'))
322
 
        expected_texts = {(b'file-id', b'third')}
323
 
        if stacked_branch.repository.texts.get_parent_map([(b'root-id',
324
 
            b'third')]):
 
335
        self.assertTrue(unstacked_repo.has_revision(third))
 
336
        expected_texts = {(file_id, third)}
 
337
        if stacked_branch.repository.texts.get_parent_map([(root_id,
 
338
            third)]):
325
339
            # If a (root-id,third) text exists, it should be in the stacked
326
340
            # repo.
327
 
            expected_texts.add((b'root-id', b'third'))
 
341
            expected_texts.add((root_id, third))
328
342
        self.assertEqual(expected_texts, unstacked_repo.texts.keys())
329
 
        self.assertCanStreamRevision(unstacked_repo, b'third')
 
343
        self.assertCanStreamRevision(unstacked_repo, third)
330
344
 
331
345
    def test_fetch_from_stacked_to_stacked_copies_parent_inventories(self):
332
346
        """Fetch from a stacked branch copies inventories for parents of
419
433
 
420
434
    def test_fetch_missing_basis_text(self):
421
435
        """If fetching a delta, we should die if a basis is not present."""
 
436
        if not self.repository_format.supports_full_versioned_files:
 
437
            raise TestNotApplicable('Need full versioned files support')
 
438
        if not self.repository_format_to.supports_full_versioned_files:
 
439
            raise TestNotApplicable('Need full versioned files support')
422
440
        tree = self.make_branch_and_tree('tree')
423
441
        self.build_tree(['tree/a'])
424
442
        tree.add(['a'])
425
 
        tree.commit('one', rev_id=b'rev-one')
 
443
        rev1 = tree.commit('one')
426
444
        self.build_tree_contents([('tree/a', b'new contents\n')])
427
 
        tree.commit('two', rev_id=b'rev-two')
 
445
        rev2 = tree.commit('two')
428
446
 
429
447
        to_repo = self.make_to_repository('to_repo')
430
448
        # We build a broken revision so that we can test the fetch code dies
432
450
        with to_repo.lock_write():
433
451
            to_repo.start_write_group()
434
452
            try:
435
 
                inv = tree.branch.repository.get_inventory(b'rev-one')
436
 
                to_repo.add_inventory(b'rev-one', inv, [])
437
 
                rev = tree.branch.repository.get_revision(b'rev-one')
438
 
                to_repo.add_revision(b'rev-one', rev, inv=inv)
 
453
                inv = tree.branch.repository.get_inventory(rev1)
 
454
                to_repo.add_inventory(rev1, inv, [])
 
455
                rev = tree.branch.repository.get_revision(rev1)
 
456
                to_repo.add_revision(rev1, rev, inv=inv)
439
457
                self.disable_commit_write_group_paranoia(to_repo)
440
458
                to_repo.commit_write_group()
441
459
            except:
446
464
        # reconstructable, or raise an exception (which stream based copies
447
465
        # generally do).
448
466
        try:
449
 
            to_repo.fetch(tree.branch.repository, b'rev-two')
 
467
            to_repo.fetch(tree.branch.repository, rev2)
450
468
        except (errors.BzrCheckError, errors.RevisionNotPresent) as e:
451
469
            # If an exception is raised, the revision should not be in the
452
470
            # target.
454
472
            # Can also just raise a generic check errors; stream insertion
455
473
            # does this to include all the missing data
456
474
            self.assertRaises((errors.NoSuchRevision, errors.RevisionNotPresent),
457
 
                              to_repo.revision_tree, b'rev-two')
 
475
                              to_repo.revision_tree, rev2)
458
476
        else:
459
477
            # If not exception is raised, then the text should be
460
478
            # available.
461
479
            with to_repo.lock_read():
462
 
                rt = to_repo.revision_tree(b'rev-two')
 
480
                rt = to_repo.revision_tree(rev2)
463
481
                self.assertEqual(b'new contents\n',
464
482
                                 rt.get_file_text('a'))
465
483
 
475
493
        repo_a.fetch(repo_b)
476
494
 
477
495
    def test_fetch_missing_text_other_location_fails(self):
 
496
        if not self.repository_format.supports_full_versioned_files:
 
497
            raise TestNotApplicable('Need full versioned files')
 
498
 
478
499
        source_tree = self.make_branch_and_tree('source')
479
500
        source = source_tree.branch.repository
480
501
        target = self.make_to_repository('target')
505
526
        source.add_revision(b'b', rev)
506
527
        self.disable_commit_write_group_paranoia(source)
507
528
        source.commit_write_group()
508
 
        self.assertRaises(errors.RevisionNotPresent, target.fetch, source)
509
 
        self.assertFalse(target.has_revision(b'b'))
 
529
        try:
 
530
            self.assertRaises(errors.RevisionNotPresent, target.fetch, source)
 
531
        except errors.NoRoundtrippingSupport:
 
532
            raise TestNotApplicable('roundtripping not supported')
 
533
        self.assertFalse(target.has_revision('b'))
510
534
 
511
535
    def test_fetch_funky_file_id(self):
512
536
        from_tree = self.make_branch_and_tree('tree')
514
538
            from_repo = from_tree.branch.repository
515
539
            check_repo_format_for_funky_id_on_win32(from_repo)
516
540
        self.build_tree(['tree/filename'])
 
541
        if not from_tree.supports_setting_file_ids():
 
542
            raise TestNotApplicable('from tree format can not create custom file ids')
517
543
        from_tree.add('filename', 'funky-chars<>%&;"\'')
518
544
        from_tree.commit('commit filename')
519
545
        to_repo = self.make_to_repository('to')
520
 
        to_repo.fetch(from_tree.branch.repository, from_tree.get_parent_ids()[0])
 
546
        try:
 
547
            to_repo.fetch(from_tree.branch.repository, from_tree.get_parent_ids()[0])
 
548
        except errors.NoRoundtrippingSupport:
 
549
            raise TestNotApplicable('roundtripping not supported')
521
550
 
522
551
    def test_fetch_revision_hash(self):
523
552
        """Ensure that inventory hashes are updated by fetch"""
 
553
        if not self.repository_format_to.supports_full_versioned_files:
 
554
            raise TestNotApplicable('Need full versioned files')
524
555
        from_tree = self.make_branch_and_tree('tree')
525
 
        from_tree.commit('foo', rev_id=b'foo-id')
 
556
        revid = from_tree.commit('foo')
526
557
        to_repo = self.make_to_repository('to')
527
 
        to_repo.fetch(from_tree.branch.repository)
528
 
        recorded_inv_sha1 = to_repo.get_revision(b'foo-id').inventory_sha1
 
558
        try:
 
559
            to_repo.fetch(from_tree.branch.repository)
 
560
        except errors.NoRoundtrippingSupport:
 
561
            raise TestNotApplicable('roundtripping not supported')
 
562
        recorded_inv_sha1 = to_repo.get_revision(revid).inventory_sha1
529
563
        to_repo.lock_read()
530
564
        self.addCleanup(to_repo.unlock)
531
 
        stream = to_repo.inventories.get_record_stream([(b'foo-id',)],
 
565
        stream = to_repo.inventories.get_record_stream([(revid,)],
532
566
                                                       'unordered', True)
533
567
        bytes = stream.next().get_bytes_as('fulltext')
534
568
        computed_inv_sha1 = osutils.sha_string(bytes)
544
578
            not from_tree.branch.repository._format.supports_tree_reference or
545
579
            not to_repo._format.supports_tree_reference):
546
580
            raise TestNotApplicable("Need subtree support.")
 
581
        if not to_repo._format.supports_full_versioned_files:
 
582
            raise TestNotApplicable('Need full versioned files support.')
547
583
        subtree = self.make_branch_and_tree('tree/subtree')
548
584
        subtree.commit('subrev 1')
549
585
        from_tree.add_reference(subtree)