745
745
broken_repo = self.make_broken_repository()
746
746
empty_repo = self.make_repository('empty-repo')
747
self.assertRaises(errors.RevisionNotPresent, empty_repo.fetch, broken_repo)
747
self.assertRaises((errors.RevisionNotPresent, errors.BzrCheckError),
748
empty_repo.fetch, broken_repo)
750
751
class TestRepositoryPackCollection(TestCaseWithTransport):
757
758
repo = self.make_repository('.', format=format)
758
759
return repo._pack_collection
761
def make_packs_and_alt_repo(self, write_lock=False):
762
"""Create a pack repo with 3 packs, and access it via a second repo."""
763
tree = self.make_branch_and_tree('.')
765
self.addCleanup(tree.unlock)
766
rev1 = tree.commit('one')
767
rev2 = tree.commit('two')
768
rev3 = tree.commit('three')
769
r = repository.Repository.open('.')
774
self.addCleanup(r.unlock)
775
packs = r._pack_collection
776
packs.ensure_loaded()
777
return tree, r, packs, [rev1, rev2, rev3]
760
779
def test__max_pack_count(self):
761
780
"""The maximum pack count is a function of the number of revisions."""
762
781
# no revisions - one pack, so that we can have a revision free repo
925
944
self.assertTrue(pack_1 is packs.get_pack_by_name(name))
927
946
def test_reload_pack_names_new_entry(self):
928
tree = self.make_branch_and_tree('.')
930
self.addCleanup(tree.unlock)
931
rev1 = tree.commit('one')
932
rev2 = tree.commit('two')
933
r = repository.Repository.open('.')
935
self.addCleanup(r.unlock)
936
packs = r._pack_collection
937
packs.ensure_loaded()
947
tree, r, packs, revs = self.make_packs_and_alt_repo()
938
948
names = packs.names()
939
949
# Add a new pack file into the repository
940
rev3 = tree.commit('three')
950
rev4 = tree.commit('four')
941
951
new_names = tree.branch.repository._pack_collection.names()
942
952
new_name = set(new_names).difference(names)
943
953
self.assertEqual(1, len(new_name))
947
957
self.assertTrue(packs.reload_pack_names())
948
958
self.assertEqual(new_names, packs.names())
949
959
# And the repository can access the new revision
950
self.assertEqual({rev3:(rev2,)}, r.get_parent_map([rev3]))
960
self.assertEqual({rev4:(revs[-1],)}, r.get_parent_map([rev4]))
951
961
self.assertFalse(packs.reload_pack_names())
953
963
def test_reload_pack_names_added_and_removed(self):
954
tree = self.make_branch_and_tree('.')
956
self.addCleanup(tree.unlock)
957
rev1 = tree.commit('one')
958
rev2 = tree.commit('two')
959
r = repository.Repository.open('.')
961
self.addCleanup(r.unlock)
962
packs = r._pack_collection
963
packs.ensure_loaded()
964
tree, r, packs, revs = self.make_packs_and_alt_repo()
964
965
names = packs.names()
965
966
# Now repack the whole thing
966
967
tree.branch.repository.pack()
969
970
self.assertEqual(names, packs.names())
970
971
self.assertTrue(packs.reload_pack_names())
971
972
self.assertEqual(new_names, packs.names())
972
self.assertEqual({rev2:(rev1,)}, r.get_parent_map([rev2]))
973
self.assertEqual({revs[-1]:(revs[-2],)}, r.get_parent_map([revs[-1]]))
973
974
self.assertFalse(packs.reload_pack_names())
976
def test_autopack_reloads_and_stops(self):
977
tree, r, packs, revs = self.make_packs_and_alt_repo(write_lock=True)
978
# After we have determined what needs to be autopacked, trigger a
979
# full-pack via the other repo which will cause us to re-evaluate and
980
# decide we don't need to do anything
981
orig_execute = packs._execute_pack_operations
982
def _munged_execute_pack_ops(*args, **kwargs):
983
tree.branch.repository.pack()
984
return orig_execute(*args, **kwargs)
985
packs._execute_pack_operations = _munged_execute_pack_ops
986
packs._max_pack_count = lambda x: 1
987
packs.pack_distribution = lambda x: [10]
988
self.assertFalse(packs.autopack())
989
self.assertEqual(1, len(packs.names()))
990
self.assertEqual(tree.branch.repository._pack_collection.names(),
976
994
class TestPack(TestCaseWithTransport):
977
995
"""Tests for the Pack object."""
1031
1049
pack_transport = self.get_transport('pack')
1032
1050
index_transport = self.get_transport('index')
1033
1051
upload_transport.mkdir('.')
1034
pack = pack_repo.NewPack(upload_transport, index_transport,
1035
pack_transport, index_builder_class=BTreeBuilder,
1052
collection = pack_repo.RepositoryPackCollection(repo=None,
1053
transport=self.get_transport('.'),
1054
index_transport=index_transport,
1055
upload_transport=upload_transport,
1056
pack_transport=pack_transport,
1057
index_builder_class=BTreeBuilder,
1036
1058
index_class=BTreeGraphIndex)
1059
pack = pack_repo.NewPack(collection)
1037
1060
self.assertIsInstance(pack.revision_index, BTreeBuilder)
1038
1061
self.assertIsInstance(pack.inventory_index, BTreeBuilder)
1039
1062
self.assertIsInstance(pack._hash, type(osutils.md5()))
1049
1072
class TestPacker(TestCaseWithTransport):
1050
1073
"""Tests for the packs repository Packer class."""
1052
# To date, this class has been factored out and nothing new added to it;
1053
# thus there are not yet any tests.
1075
def test_pack_optimizes_pack_order(self):
1076
builder = self.make_branch_builder('.')
1077
builder.start_series()
1078
builder.build_snapshot('A', None, [
1079
('add', ('', 'root-id', 'directory', None)),
1080
('add', ('f', 'f-id', 'file', 'content\n'))])
1081
builder.build_snapshot('B', ['A'],
1082
[('modify', ('f-id', 'new-content\n'))])
1083
builder.build_snapshot('C', ['B'],
1084
[('modify', ('f-id', 'third-content\n'))])
1085
builder.build_snapshot('D', ['C'],
1086
[('modify', ('f-id', 'fourth-content\n'))])
1087
b = builder.get_branch()
1089
builder.finish_series()
1090
self.addCleanup(b.unlock)
1091
# At this point, we should have 4 pack files available
1092
# Because of how they were built, they correspond to
1093
# ['D', 'C', 'B', 'A']
1094
packs = b.repository._pack_collection.packs
1095
packer = pack_repo.Packer(b.repository._pack_collection,
1097
revision_ids=['B', 'C'])
1098
# Now, when we are copying the B & C revisions, their pack files should
1099
# be moved to the front of the stack
1100
# The new ordering moves B & C to the front of the .packs attribute,
1101
# and leaves the others in the original order.
1102
new_packs = [packs[1], packs[2], packs[0], packs[3]]
1103
new_pack = packer.pack()
1104
self.assertEqual(new_packs, packer.packs)
1056
1107
class TestOptimisingPacker(TestCaseWithTransport):