/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_pack_repository.py

  • Committer: Jelmer Vernooij
  • Date: 2019-05-29 03:22:34 UTC
  • mfrom: (7303 work)
  • mto: This revision was merged to the branch mainline in revision 7306.
  • Revision ID: jelmer@jelmer.uk-20190529032234-mt3fuws8gq03tapi
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
from .. import (
27
27
    controldir,
28
28
    errors,
 
29
    gpg,
29
30
    osutils,
30
31
    repository,
31
32
    revision as _mod_revision,
96
97
 
97
98
    def check_format(self, t):
98
99
        self.assertEqualDiff(
99
 
            self.format_string.encode('ascii'), # from scenario
 
100
            self.format_string.encode('ascii'),  # from scenario
100
101
            t.get('format').read())
101
102
 
102
103
    def assertHasNoKndx(self, t, knit_name):
120
121
        self.assertFalse(t.has('knits'))
121
122
        # revision-indexes file-container directory
122
123
        self.assertEqual([],
123
 
            list(self.index_class(t, 'pack-names', None).iter_all_entries()))
 
124
                         list(self.index_class(t, 'pack-names', None).iter_all_entries()))
124
125
        self.assertTrue(S_ISDIR(t.stat('packs').st_mode))
125
126
        self.assertTrue(S_ISDIR(t.stat('upload').st_mode))
126
127
        self.assertTrue(S_ISDIR(t.stat('indices').st_mode))
162
163
    def test_adding_revision_creates_pack_indices(self):
163
164
        format = self.get_format()
164
165
        tree = self.make_branch_and_tree('.', format=format)
165
 
        trans = tree.branch.repository.controldir.get_repository_transport(None)
 
166
        trans = tree.branch.repository.controldir.get_repository_transport(
 
167
            None)
166
168
        self.assertEqual([],
167
 
            list(self.index_class(trans, 'pack-names', None).iter_all_entries()))
 
169
                         list(self.index_class(trans, 'pack-names', None).iter_all_entries()))
168
170
        tree.commit('foobarbaz')
169
171
        index = self.index_class(trans, 'pack-names', None)
170
172
        index_nodes = list(index.iter_all_entries())
183
185
        tree1 = self.make_branch_and_tree('1', format=format)
184
186
        tree2 = self.make_branch_and_tree('2', format=format)
185
187
        tree1.branch.repository.fetch(tree2.branch.repository)
186
 
        trans = tree1.branch.repository.controldir.get_repository_transport(None)
 
188
        trans = tree1.branch.repository.controldir.get_repository_transport(
 
189
            None)
187
190
        self.assertEqual([],
188
 
            list(self.index_class(trans, 'pack-names', None).iter_all_entries()))
 
191
                         list(self.index_class(trans, 'pack-names', None).iter_all_entries()))
189
192
 
190
193
    def test_commit_across_pack_shape_boundary_autopacks(self):
191
194
        format = self.get_format()
192
195
        tree = self.make_branch_and_tree('.', format=format)
193
 
        trans = tree.branch.repository.controldir.get_repository_transport(None)
 
196
        trans = tree.branch.repository.controldir.get_repository_transport(
 
197
            None)
194
198
        # This test could be a little cheaper by replacing the packs
195
199
        # attribute on the repository to allow a different pack distribution
196
200
        # and max packs policy - so we are checking the policy is honoured
212
216
        tree = tree.controldir.open_workingtree()
213
217
        check_result = tree.branch.repository.check(
214
218
            [tree.branch.last_revision()])
215
 
        nb_files = 5 # .pack, .rix, .iix, .tix, .six
 
219
        nb_files = 5  # .pack, .rix, .iix, .tix, .six
216
220
        if tree.branch.repository._format.supports_chks:
217
 
            nb_files += 1 # .cix
 
221
            nb_files += 1  # .cix
218
222
        # We should have 10 x nb_files files in the obsolete_packs directory.
219
223
        obsolete_files = list(trans.list_dir('obsolete_packs'))
220
224
        self.assertFalse('foo' in obsolete_files)
249
253
                    inv.root.revision = revid
250
254
                    repo.texts.add_lines((inv.root.file_id, revid), [], [])
251
255
                    rev = _mod_revision.Revision(timestamp=0, timezone=None,
252
 
                        committer="Foo Bar <foo@example.com>", message="Message",
253
 
                        revision_id=revid)
 
256
                                                 committer="Foo Bar <foo@example.com>", message="Message",
 
257
                                                 revision_id=revid)
254
258
                    rev.parent_ids = ()
255
259
                    repo.add_revision(revid, rev, inv=inv)
256
260
                except:
287
291
        repo = self.make_repository('repo')
288
292
        pack_coll = repo._pack_collection
289
293
        indices = {pack_coll.revision_index, pack_coll.inventory_index,
290
 
                pack_coll.text_index, pack_coll.signature_index}
 
294
                   pack_coll.text_index, pack_coll.signature_index}
291
295
        if pack_coll.chk_index is not None:
292
296
            indices.add(pack_coll.chk_index)
293
297
        combined_indices = set(idx.combined_index for idx in indices)
296
300
                combined_indices.difference([combined_index]),
297
301
                combined_index._sibling_indices)
298
302
 
 
303
    def test_pack_with_signatures(self):
 
304
        format = self.get_format()
 
305
        tree = self.make_branch_and_tree('.', format=format)
 
306
        trans = tree.branch.repository.controldir.get_repository_transport(
 
307
            None)
 
308
        revid1 = tree.commit('start')
 
309
        revid2 = tree.commit('more work')
 
310
        strategy = gpg.LoopbackGPGStrategy(None)
 
311
        repo = tree.branch.repository
 
312
        self.addCleanup(repo.lock_write().unlock)
 
313
        repo.start_write_group()
 
314
        repo.sign_revision(revid1, strategy)
 
315
        repo.commit_write_group()
 
316
        repo.start_write_group()
 
317
        repo.sign_revision(revid2, strategy)
 
318
        repo.commit_write_group()
 
319
        tree.branch.repository.pack()
 
320
        # there should be 1 pack:
 
321
        index = self.index_class(trans, 'pack-names', None)
 
322
        self.assertEqual(1, len(list(index.iter_all_entries())))
 
323
        self.assertEqual(2, len(tree.branch.repository.all_revision_ids()))
 
324
 
299
325
    def test_pack_after_two_commits_packs_everything(self):
300
326
        format = self.get_format()
301
327
        tree = self.make_branch_and_tree('.', format=format)
302
 
        trans = tree.branch.repository.controldir.get_repository_transport(None)
 
328
        trans = tree.branch.repository.controldir.get_repository_transport(
 
329
            None)
303
330
        tree.commit('start')
304
331
        tree.commit('more work')
305
332
        tree.branch.repository.pack()
351
378
        # tip->ancestor
352
379
        format = self.get_format()
353
380
        tree = self.make_branch_and_tree('.', format=format)
354
 
        trans = tree.branch.repository.controldir.get_repository_transport(None)
 
381
        trans = tree.branch.repository.controldir.get_repository_transport(
 
382
            None)
355
383
        tree.commit('start', rev_id=b'1')
356
384
        tree.commit('more work', rev_id=b'2')
357
385
        tree.branch.repository.pack()
388
416
 
389
417
    def _add_text(self, repo, fileid):
390
418
        """Add a text to the repository within a write group."""
391
 
        repo.texts.add_lines((fileid, b'samplerev+'+fileid), [],
392
 
            [b'smaplerev+'+fileid])
 
419
        repo.texts.add_lines((fileid, b'samplerev+' + fileid), [],
 
420
                             [b'smaplerev+' + fileid])
393
421
 
394
422
    def test_concurrent_writers_merge_new_packs(self):
395
423
        format = self.get_format()
431
459
                # Now both repositories should know about both names
432
460
                r1._pack_collection.ensure_loaded()
433
461
                r2._pack_collection.ensure_loaded()
434
 
                self.assertEqual(r1._pack_collection.names(), r2._pack_collection.names())
 
462
                self.assertEqual(r1._pack_collection.names(),
 
463
                                 r2._pack_collection.names())
435
464
                self.assertEqual(2, len(r1._pack_collection.names()))
436
465
            finally:
437
466
                r2.unlock()
489
518
                # Now both repositories should now about just one name.
490
519
                r1._pack_collection.ensure_loaded()
491
520
                r2._pack_collection.ensure_loaded()
492
 
                self.assertEqual(r1._pack_collection.names(), r2._pack_collection.names())
 
521
                self.assertEqual(r1._pack_collection.names(),
 
522
                                 r2._pack_collection.names())
493
523
                self.assertEqual(1, len(r1._pack_collection.names()))
494
524
                self.assertFalse(name_to_drop in r1._pack_collection.names())
495
525
 
506
536
                # Now r2 has read the pack-names file, but will need to reload
507
537
                # it after r1 has repacked
508
538
                tree.branch.repository.pack()
509
 
                self.assertEqual({rev2:(rev1,)}, r2.get_parent_map([rev2]))
 
539
                self.assertEqual({rev2: (rev1,)}, r2.get_parent_map([rev2]))
510
540
            finally:
511
541
                r2.unlock()
512
542
        finally:
527
557
                packed = False
528
558
                result = {}
529
559
                record_stream = r2.revisions.get_record_stream(keys,
530
 
                                    'unordered', False)
 
560
                                                               'unordered', False)
531
561
                for record in record_stream:
532
562
                    result[record.key] = record
533
563
                    if not packed:
558
588
                autopack_count = [0]
559
589
                r1 = tree.branch.repository
560
590
                orig = r1._pack_collection.pack_distribution
 
591
 
561
592
                def trigger_during_auto(*args, **kwargs):
562
593
                    ret = orig(*args, **kwargs)
563
594
                    if not autopack_count[0]:
606
637
        repo2 = repository.Repository.open('.')
607
638
        self.prepare_for_break_lock()
608
639
        repo2.break_lock()
609
 
        self.assertRaises(errors.LockBroken, repo._pack_collection._unlock_names)
 
640
        self.assertRaises(errors.LockBroken,
 
641
                          repo._pack_collection._unlock_names)
610
642
 
611
643
    def test_fetch_without_find_ghosts_ignores_ghosts(self):
612
644
        # we want two repositories at this point:
616
648
        # 'references' is present in both repositories, and 'tip' is present
617
649
        # just in has_ghost.
618
650
        # has_ghost       missing_ghost
619
 
        #------------------------------
 
651
        # ------------------------------
620
652
        # 'ghost'             -
621
653
        # 'references'    'references'
622
654
        # 'tip'               -
623
655
        # In this test we fetch 'tip' which should not fetch 'ghost'
624
656
        has_ghost = self.make_repository('has_ghost', format=self.get_format())
625
657
        missing_ghost = self.make_repository('missing_ghost',
626
 
            format=self.get_format())
 
658
                                             format=self.get_format())
627
659
 
628
660
        def add_commit(repo, revision_id, parent_ids):
629
661
            repo.lock_write()
652
684
        rev = missing_ghost.get_revision(b'tip')
653
685
        inv = missing_ghost.get_inventory(b'tip')
654
686
        self.assertRaises(errors.NoSuchRevision,
655
 
            missing_ghost.get_revision, b'ghost')
 
687
                          missing_ghost.get_revision, b'ghost')
656
688
        self.assertRaises(errors.NoSuchRevision,
657
 
            missing_ghost.get_inventory, b'ghost')
 
689
                          missing_ghost.get_inventory, b'ghost')
658
690
 
659
691
    def make_write_ready_repo(self):
660
692
        format = self.get_format()
698
730
    def test_supports_external_lookups(self):
699
731
        repo = self.make_repository('.', format=self.get_format())
700
732
        self.assertEqual(self.format_supports_external_lookups,
701
 
            repo._format.supports_external_lookups)
 
733
                         repo._format.supports_external_lookups)
702
734
 
703
735
    def _lock_write(self, write_lockable):
704
736
        """Lock write_lockable, add a cleanup and return the result.
705
 
        
 
737
 
706
738
        :param write_lockable: An object with a lock_write method.
707
739
        :return: The result of write_lockable.lock_write().
708
740
        """
751
783
        wg_tokens = repo.suspend_write_group()
752
784
        expected_pack_name = wg_tokens[0] + '.pack'
753
785
        expected_names = [wg_tokens[0] + ext for ext in
754
 
                            ('.rix', '.iix', '.tix', '.six')]
 
786
                          ('.rix', '.iix', '.tix', '.six')]
755
787
        if repo.chk_bytes is not None:
756
788
            expected_names.append(wg_tokens[0] + '.cix')
757
789
        expected_names.append(expected_pack_name)
779
811
        self.assertEqual([key], list(same_repo.chk_bytes.keys()))
780
812
        self.assertEqual(
781
813
            text, next(same_repo.chk_bytes.get_record_stream([key],
782
 
                'unordered', True)).get_bytes_as('fulltext'))
 
814
                                                             'unordered', True)).get_bytes_as('fulltext'))
783
815
        same_repo.abort_write_group()
784
816
        self.assertEqual([], list(same_repo.chk_bytes.keys()))
785
817
 
821
853
        same_repo.commit_write_group()
822
854
        expected_pack_name = wg_tokens[0] + '.pack'
823
855
        expected_names = [wg_tokens[0] + ext for ext in
824
 
                            ('.rix', '.iix', '.tix', '.six')]
 
856
                          ('.rix', '.iix', '.tix', '.six')]
825
857
        if repo.chk_bytes is not None:
826
858
            expected_names.append(wg_tokens[0] + '.cix')
827
859
        self.assertEqual(
857
889
    def setUp(self):
858
890
        if not self.format_supports_external_lookups:
859
891
            raise TestNotApplicable("%r doesn't support stacking"
860
 
                % (self.format_name,))
 
892
                                    % (self.format_name,))
861
893
        super(TestPackRepositoryStacking, self).setUp()
862
894
 
863
895
    def get_format(self):
894
926
        repo.add_fallback_repository(base)
895
927
        # you can't stack on something with incompatible data
896
928
        bad_repo = self.make_repository('mismatch',
897
 
            format=mismatching_format_name)
 
929
                                        format=mismatching_format_name)
898
930
        e = self.assertRaises(errors.IncompatibleRepositories,
899
 
            repo.add_fallback_repository, bad_repo)
 
931
                              repo.add_fallback_repository, bad_repo)
900
932
        self.assertContainsRe(str(e),
901
 
            r'(?m)KnitPackRepository.*/mismatch/.*\nis not compatible with\n'
902
 
            r'.*Repository.*/repo/.*\n'
903
 
            r'different rich-root support')
 
933
                              r'(?m)KnitPackRepository.*/mismatch/.*\nis not compatible with\n'
 
934
                              r'.*Repository.*/repo/.*\n'
 
935
                              r'different rich-root support')
904
936
 
905
937
    def test_stack_checks_serializers_compatibility(self):
906
938
        repo = self.make_repository('repo', format=self.get_format())
918
950
                mismatching_format_name = 'pack-0.92-subtree'
919
951
            else:
920
952
                raise TestNotApplicable('No formats use non-v5 serializer'
921
 
                    ' without having rich-root also set')
 
953
                                        ' without having rich-root also set')
922
954
        base = self.make_repository('base', format=matching_format_name)
923
955
        repo.add_fallback_repository(base)
924
956
        # you can't stack on something with incompatible data
925
957
        bad_repo = self.make_repository('mismatch',
926
 
            format=mismatching_format_name)
 
958
                                        format=mismatching_format_name)
927
959
        e = self.assertRaises(errors.IncompatibleRepositories,
928
 
            repo.add_fallback_repository, bad_repo)
 
960
                              repo.add_fallback_repository, bad_repo)
929
961
        self.assertContainsRe(str(e),
930
 
            r'(?m)KnitPackRepository.*/mismatch/.*\nis not compatible with\n'
931
 
            r'.*Repository.*/repo/.*\n'
932
 
            r'different serializers')
 
962
                              r'(?m)KnitPackRepository.*/mismatch/.*\nis not compatible with\n'
 
963
                              r'.*Repository.*/repo/.*\n'
 
964
                              r'different serializers')
933
965
 
934
966
    def test_adding_pack_does_not_record_pack_names_from_other_repositories(self):
935
967
        base = self.make_branch_and_tree('base', format=self.get_format())
936
968
        base.commit('foo')
937
 
        referencing = self.make_branch_and_tree('repo', format=self.get_format())
938
 
        referencing.branch.repository.add_fallback_repository(base.branch.repository)
 
969
        referencing = self.make_branch_and_tree(
 
970
            'repo', format=self.get_format())
 
971
        referencing.branch.repository.add_fallback_repository(
 
972
            base.branch.repository)
939
973
        local_tree = referencing.branch.create_checkout('local')
940
974
        local_tree.commit('bar')
941
975
        new_instance = referencing.controldir.open_repository()
950
984
        base.commit('foo')
951
985
        tree = self.make_branch_and_tree('repo', format=format)
952
986
        tree.branch.repository.add_fallback_repository(base.branch.repository)
953
 
        trans = tree.branch.repository.controldir.get_repository_transport(None)
 
987
        trans = tree.branch.repository.controldir.get_repository_transport(
 
988
            None)
954
989
        # This test could be a little cheaper by replacing the packs
955
990
        # attribute on the repository to allow a different pack distribution
956
991
        # and max packs policy - so we are checking the policy is honoured
970
1005
        tree = tree.controldir.open_workingtree()
971
1006
        check_result = tree.branch.repository.check(
972
1007
            [tree.branch.last_revision()])
973
 
        nb_files = 5 # .pack, .rix, .iix, .tix, .six
 
1008
        nb_files = 5  # .pack, .rix, .iix, .tix, .six
974
1009
        if tree.branch.repository._format.supports_chks:
975
 
            nb_files += 1 # .cix
 
1010
            nb_files += 1  # .cix
976
1011
        # We should have 10 x nb_files files in the obsolete_packs directory.
977
1012
        obsolete_files = list(trans.list_dir('obsolete_packs'))
978
1013
        self.assertFalse('foo' in obsolete_files)
1001
1036
            ('add', ('', b'root-id', 'directory', None))],
1002
1037
            revision_id=b'A-id')
1003
1038
        builder.build_snapshot(
1004
 
                [b'A-id', b'ghost-id'], [],
1005
 
                revision_id=b'B-id', )
 
1039
            [b'A-id', b'ghost-id'], [],
 
1040
            revision_id=b'B-id', )
1006
1041
        builder.finish_series()
1007
1042
        repo = self.make_repository('target', format=self.get_format())
1008
1043
        b = builder.get_branch()
1088
1123
        tree = self.make_branch_and_tree('local', format=format)
1089
1124
        self.make_branch_and_tree('remote', format=format)
1090
1125
        remote_branch_url = self.smart_server.get_url() + 'remote'
1091
 
        remote_branch = controldir.ControlDir.open(remote_branch_url).open_branch()
 
1126
        remote_branch = controldir.ControlDir.open(
 
1127
            remote_branch_url).open_branch()
1092
1128
        # Make 9 local revisions, and push them one at a time to the remote
1093
1129
        # repo to produce 9 pack files.
1094
1130
        for x in range(9):
1098
1134
        self.hpss_calls = []
1099
1135
        tree.commit('commit triggering pack')
1100
1136
        tree.branch.push(remote_branch)
1101
 
        autopack_calls = len([call for call in self.hpss_calls if call ==
1102
 
            b'PackRepository.autopack'])
 
1137
        autopack_calls = len([call for call in self.hpss_calls if call
 
1138
                              == b'PackRepository.autopack'])
1103
1139
        streaming_calls = len([call for call in self.hpss_calls if call in
1104
 
            (b'Repository.insert_stream', b'Repository.insert_stream_1.19')])
 
1140
                               (b'Repository.insert_stream', b'Repository.insert_stream_1.19')])
1105
1141
        if autopack_calls:
1106
1142
            # Non streaming server
1107
1143
            self.assertEqual(1, autopack_calls)
1119
1155
    # these give the bzrdir canned format name, and the repository on-disk
1120
1156
    # format string
1121
1157
    scenarios_params = [
1122
 
         dict(format_name='pack-0.92',
1123
 
              format_string="Bazaar pack repository format 1 (needs bzr 0.92)\n",
1124
 
              format_supports_external_lookups=False,
1125
 
              index_class=GraphIndex),
1126
 
         dict(format_name='pack-0.92-subtree',
1127
 
              format_string="Bazaar pack repository format 1 "
1128
 
              "with subtree support (needs bzr 0.92)\n",
1129
 
              format_supports_external_lookups=False,
1130
 
              index_class=GraphIndex),
1131
 
         dict(format_name='1.6',
1132
 
              format_string="Bazaar RepositoryFormatKnitPack5 (bzr 1.6)\n",
1133
 
              format_supports_external_lookups=True,
1134
 
              index_class=GraphIndex),
1135
 
         dict(format_name='1.6.1-rich-root',
1136
 
              format_string="Bazaar RepositoryFormatKnitPack5RichRoot "
1137
 
                  "(bzr 1.6.1)\n",
1138
 
              format_supports_external_lookups=True,
1139
 
              index_class=GraphIndex),
1140
 
         dict(format_name='1.9',
1141
 
              format_string="Bazaar RepositoryFormatKnitPack6 (bzr 1.9)\n",
1142
 
              format_supports_external_lookups=True,
1143
 
              index_class=BTreeGraphIndex),
1144
 
         dict(format_name='1.9-rich-root',
1145
 
              format_string="Bazaar RepositoryFormatKnitPack6RichRoot "
1146
 
                  "(bzr 1.9)\n",
1147
 
              format_supports_external_lookups=True,
1148
 
              index_class=BTreeGraphIndex),
1149
 
         dict(format_name='2a',
1150
 
              format_string="Bazaar repository format 2a "
1151
 
                "(needs bzr 1.16 or later)\n",
1152
 
              format_supports_external_lookups=True,
1153
 
              index_class=BTreeGraphIndex),
1154
 
         ]
 
1158
        dict(format_name='pack-0.92',
 
1159
             format_string="Bazaar pack repository format 1 (needs bzr 0.92)\n",
 
1160
             format_supports_external_lookups=False,
 
1161
             index_class=GraphIndex),
 
1162
        dict(format_name='pack-0.92-subtree',
 
1163
             format_string="Bazaar pack repository format 1 "
 
1164
             "with subtree support (needs bzr 0.92)\n",
 
1165
             format_supports_external_lookups=False,
 
1166
             index_class=GraphIndex),
 
1167
        dict(format_name='1.6',
 
1168
             format_string="Bazaar RepositoryFormatKnitPack5 (bzr 1.6)\n",
 
1169
             format_supports_external_lookups=True,
 
1170
             index_class=GraphIndex),
 
1171
        dict(format_name='1.6.1-rich-root',
 
1172
             format_string="Bazaar RepositoryFormatKnitPack5RichRoot "
 
1173
             "(bzr 1.6.1)\n",
 
1174
             format_supports_external_lookups=True,
 
1175
             index_class=GraphIndex),
 
1176
        dict(format_name='1.9',
 
1177
             format_string="Bazaar RepositoryFormatKnitPack6 (bzr 1.9)\n",
 
1178
             format_supports_external_lookups=True,
 
1179
             index_class=BTreeGraphIndex),
 
1180
        dict(format_name='1.9-rich-root',
 
1181
             format_string="Bazaar RepositoryFormatKnitPack6RichRoot "
 
1182
             "(bzr 1.9)\n",
 
1183
             format_supports_external_lookups=True,
 
1184
             index_class=BTreeGraphIndex),
 
1185
        dict(format_name='2a',
 
1186
             format_string="Bazaar repository format 2a "
 
1187
             "(needs bzr 1.16 or later)\n",
 
1188
             format_supports_external_lookups=True,
 
1189
             index_class=BTreeGraphIndex),
 
1190
        ]
1155
1191
    # name of the scenario is the format name
1156
1192
    scenarios = [(s['format_name'], s) for s in scenarios_params]
1157
1193
    return tests.multiply_tests(basic_tests, scenarios, loader.suiteClass())