~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_repository.py

  • Committer: Vincent Ladeuil
  • Date: 2011-03-11 10:58:18 UTC
  • mfrom: (5609.2.18 2.3.2-dev)
  • mto: This revision was merged to the branch mainline in revision 5714.
  • Revision ID: v.ladeuil+lp@free.fr-20110311105818-ofadsi2uro16m37y
Merge 2.3 into trunk including fix for bug #437003

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2011 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
1696
1696
        self.assertTrue(new_pack.signature_index._optimize_for_size)
1697
1697
 
1698
1698
 
 
1699
class TestGCCHKPacker(TestCaseWithTransport):
 
1700
 
 
1701
    def make_abc_branch(self):
 
1702
        builder = self.make_branch_builder('source')
 
1703
        builder.start_series()
 
1704
        builder.build_snapshot('A', None, [
 
1705
            ('add', ('', 'root-id', 'directory', None)),
 
1706
            ('add', ('file', 'file-id', 'file', 'content\n')),
 
1707
            ])
 
1708
        builder.build_snapshot('B', ['A'], [
 
1709
            ('add', ('dir', 'dir-id', 'directory', None))])
 
1710
        builder.build_snapshot('C', ['B'], [
 
1711
            ('modify', ('file-id', 'new content\n'))])
 
1712
        builder.finish_series()
 
1713
        return builder.get_branch()
 
1714
 
 
1715
    def make_branch_with_disjoint_inventory_and_revision(self):
 
1716
        """a repo with separate packs for a revisions Revision and Inventory.
 
1717
 
 
1718
        There will be one pack file that holds the Revision content, and one
 
1719
        for the Inventory content.
 
1720
 
 
1721
        :return: (repository,
 
1722
                  pack_name_with_rev_A_Revision,
 
1723
                  pack_name_with_rev_A_Inventory,
 
1724
                  pack_name_with_rev_C_content)
 
1725
        """
 
1726
        b_source = self.make_abc_branch()
 
1727
        b_base = b_source.bzrdir.sprout('base', revision_id='A').open_branch()
 
1728
        b_stacked = b_base.bzrdir.sprout('stacked', stacked=True).open_branch()
 
1729
        b_stacked.lock_write()
 
1730
        self.addCleanup(b_stacked.unlock)
 
1731
        b_stacked.fetch(b_source, 'B')
 
1732
        # Now re-open the stacked repo directly (no fallbacks) so that we can
 
1733
        # fill in the A rev.
 
1734
        repo_not_stacked = b_stacked.bzrdir.open_repository()
 
1735
        repo_not_stacked.lock_write()
 
1736
        self.addCleanup(repo_not_stacked.unlock)
 
1737
        # Now we should have a pack file with A's inventory, but not its
 
1738
        # Revision
 
1739
        self.assertEqual([('A',), ('B',)],
 
1740
                         sorted(repo_not_stacked.inventories.keys()))
 
1741
        self.assertEqual([('B',)],
 
1742
                         sorted(repo_not_stacked.revisions.keys()))
 
1743
        stacked_pack_names = repo_not_stacked._pack_collection.names()
 
1744
        # We have a couple names here, figure out which has A's inventory
 
1745
        for name in stacked_pack_names:
 
1746
            pack = repo_not_stacked._pack_collection.get_pack_by_name(name)
 
1747
            keys = [n[1] for n in pack.inventory_index.iter_all_entries()]
 
1748
            if ('A',) in keys:
 
1749
                inv_a_pack_name = name
 
1750
                break
 
1751
        else:
 
1752
            self.fail('Could not find pack containing A\'s inventory')
 
1753
        repo_not_stacked.fetch(b_source.repository, 'A')
 
1754
        self.assertEqual([('A',), ('B',)],
 
1755
                         sorted(repo_not_stacked.revisions.keys()))
 
1756
        new_pack_names = set(repo_not_stacked._pack_collection.names())
 
1757
        rev_a_pack_names = new_pack_names.difference(stacked_pack_names)
 
1758
        self.assertEqual(1, len(rev_a_pack_names))
 
1759
        rev_a_pack_name = list(rev_a_pack_names)[0]
 
1760
        # Now fetch 'C', so we have a couple pack files to join
 
1761
        repo_not_stacked.fetch(b_source.repository, 'C')
 
1762
        rev_c_pack_names = set(repo_not_stacked._pack_collection.names())
 
1763
        rev_c_pack_names = rev_c_pack_names.difference(new_pack_names)
 
1764
        self.assertEqual(1, len(rev_c_pack_names))
 
1765
        rev_c_pack_name = list(rev_c_pack_names)[0]
 
1766
        return (repo_not_stacked, rev_a_pack_name, inv_a_pack_name,
 
1767
                rev_c_pack_name)
 
1768
 
 
1769
    def test_pack_with_distant_inventories(self):
 
1770
        # See https://bugs.launchpad.net/bzr/+bug/437003
 
1771
        # When repacking, it is possible to have an inventory in a different
 
1772
        # pack file than the associated revision. An autopack can then come
 
1773
        # along, and miss that inventory, and complain.
 
1774
        (repo, rev_a_pack_name, inv_a_pack_name, rev_c_pack_name
 
1775
         ) = self.make_branch_with_disjoint_inventory_and_revision()
 
1776
        a_pack = repo._pack_collection.get_pack_by_name(rev_a_pack_name)
 
1777
        c_pack = repo._pack_collection.get_pack_by_name(rev_c_pack_name)
 
1778
        packer = groupcompress_repo.GCCHKPacker(repo._pack_collection,
 
1779
                    [a_pack, c_pack], '.test-pack')
 
1780
        # This would raise ValueError in bug #437003, but should not raise an
 
1781
        # error once fixed.
 
1782
        packer.pack()
 
1783
 
 
1784
    def test_pack_with_missing_inventory(self):
 
1785
        # Similar to test_pack_with_missing_inventory, but this time, we force
 
1786
        # the A inventory to actually be gone from the repository.
 
1787
        (repo, rev_a_pack_name, inv_a_pack_name, rev_c_pack_name
 
1788
         ) = self.make_branch_with_disjoint_inventory_and_revision()
 
1789
        inv_a_pack = repo._pack_collection.get_pack_by_name(inv_a_pack_name)
 
1790
        repo._pack_collection._remove_pack_from_memory(inv_a_pack)
 
1791
        packer = groupcompress_repo.GCCHKPacker(repo._pack_collection,
 
1792
            repo._pack_collection.all_packs(), '.test-pack')
 
1793
        e = self.assertRaises(ValueError, packer.pack)
 
1794
        packer.new_pack.abort()
 
1795
        self.assertContainsRe(str(e),
 
1796
            r"We are missing inventories for revisions: .*'A'")
 
1797
 
 
1798
 
1699
1799
class TestCrossFormatPacks(TestCaseWithTransport):
1700
1800
 
1701
1801
    def log_pack(self, hint=None):