Rev 4021: (robertc) Add the ability for KnitVersionedFiles backed by packs to in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Fri Feb 20 01:26:12 GMT 2009


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 4021
revision-id: pqm at pqm.ubuntu.com-20090220012608-hh2rwz1cqd43mjrm
parent: pqm at pqm.ubuntu.com-20090219084345-0wx5gbw9v6hdmjmz
parent: robertc at robertcollins.net-20090220004516-wif8t618qhm3alwv
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Fri 2009-02-20 01:26:08 +0000
message:
  (robertc) Add the ability for KnitVersionedFiles backed by packs to
  	scan a low level index for missing compression parent
  	references. (Andrew Bennetts, Robert Collins)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/btree_index.py          index.py-20080624222253-p0x5f92uyh5hw734-7
  bzrlib/index.py                index.py-20070712131115-lolkarso50vjr64s-1
  bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
  bzrlib/repofmt/pack_repo.py    pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
  bzrlib/tests/test_btree_index.py test_index.py-20080624222253-p0x5f92uyh5hw734-13
  bzrlib/tests/test_index.py     test_index.py-20070712131115-lolkarso50vjr64s-2
  bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
  bzrlib/tests/test_pack_repository.py test_pack_repository-20080801043947-eaw0e6h2gu75kwmy-1
    ------------------------------------------------------------
    revno: 4011.5.12
    revision-id: robertc at robertcollins.net-20090220004516-wif8t618qhm3alwv
    parent: robertc at robertcollins.net-20090220004338-ctqo5e5hhbbkk25v
    parent: pqm at pqm.ubuntu.com-20090219084345-0wx5gbw9v6hdmjmz
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: integration
    timestamp: Fri 2009-02-20 11:45:16 +1100
    message:
      Resolve NEWS conflicts.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
      bzrlib/progress.py             progress.py-20050610070202-df9faaab791964c0
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/shelf_ui.py             shelver.py-20081005210102-33worgzwrtdw0yrm-1
      bzrlib/smart/branch.py         branch.py-20061124031907-mzh3pla28r83r97f-1
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/blackbox/test_push.py test_push.py-20060329002750-929af230d5d22663
      bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
      bzrlib/tests/branch_implementations/test_hooks.py test_hooks.py-20070129154855-blhpwxmvjs07waei-1
      bzrlib/tests/branch_implementations/test_sprout.py test_sprout.py-20070521151739-b8t8p7axw1h966ws-1
      bzrlib/tests/bzrdir_implementations/test_bzrdir.py test_bzrdir.py-20060131065642-0ebeca5e30e30866
      bzrlib/tests/per_repository/test_add_fallback_repository.py test_add_fallback_re-20080215040003-8w9n4ck9uqdxj18m-1
      bzrlib/tests/per_repository/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
      bzrlib/tests/test_bzrdir.py    test_bzrdir.py-20060131065654-deba40eef51cf220
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
      bzrlib/tests/test_shelf_ui.py  test_shelf_ui.py-20081027155203-wtcuazg85wp9u4fv-1
      bzrlib/tests/test_transport.py testtransport.py-20050718175618-e5cdb99f4555ddce
      bzrlib/tests/test_ui.py        test_ui.py-20051130162854-458e667a7414af09
      bzrlib/trace.py                trace.py-20050309040759-c8ed824bdcd4748a
      bzrlib/transport/__init__.py   transport.py-20050711165921-4978aa7ce1285ad5
      bzrlib/transport/http/_urllib2_wrappers.py _urllib2_wrappers.py-20060913231729-ha9ugi48ktx481ao-1
      bzrlib/transport/remote.py     ssh.py-20060608202016-c25gvf1ob7ypbus6-1
      bzrlib/ui/text.py              text.py-20051130153916-2e438cffc8afc478
      bzrlib/win32utils.py           win32console.py-20051021033308-123c6c929d04973d
    ------------------------------------------------------------
    revno: 4011.5.11
    revision-id: robertc at robertcollins.net-20090220004338-ctqo5e5hhbbkk25v
    parent: andrew.bennetts at canonical.com-20090219035237-o147dwr881zgd71d
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: scan-index
    timestamp: Fri 2009-02-20 11:43:38 +1100
    message:
      Polish the KnitVersionedFiles.scan_unvalidated_index api.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/index.py                index.py-20070712131115-lolkarso50vjr64s-1
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/repofmt/pack_repo.py    pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
      bzrlib/tests/test_index.py     test_index.py-20070712131115-lolkarso50vjr64s-2
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
    ------------------------------------------------------------
    revno: 4011.5.10
    revision-id: andrew.bennetts at canonical.com-20090219035237-o147dwr881zgd71d
    parent: andrew.bennetts at canonical.com-20090219035040-d51zs798oyckz7ft
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: missing-parents-in-pack-index
    timestamp: Thu 2009-02-19 14:52:37 +1100
    message:
      Replace XXX with better comment.
    modified:
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
    ------------------------------------------------------------
    revno: 4011.5.9
    revision-id: andrew.bennetts at canonical.com-20090219035040-d51zs798oyckz7ft
    parent: andrew.bennetts at canonical.com-20090219035023-avie6ynjdkg19izc
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: missing-parents-in-pack-index
    timestamp: Thu 2009-02-19 14:50:40 +1100
    message:
      Remove obsolete XXX.
    modified:
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
    ------------------------------------------------------------
    revno: 4011.5.8
    revision-id: andrew.bennetts at canonical.com-20090219035023-avie6ynjdkg19izc
    parent: andrew.bennetts at canonical.com-20090219034950-lhcuwvokgs0gc05g
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: missing-parents-in-pack-index
    timestamp: Thu 2009-02-19 14:50:23 +1100
    message:
      Remove obsolete XXX.
    modified:
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
    ------------------------------------------------------------
    revno: 4011.5.7
    revision-id: andrew.bennetts at canonical.com-20090219034950-lhcuwvokgs0gc05g
    parent: andrew.bennetts at canonical.com-20090219033740-143irsufekboyfma
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: missing-parents-in-pack-index
    timestamp: Thu 2009-02-19 14:49:50 +1100
    message:
      Remove leading underscore from _scan_unvalidate_index, explicitly NotImplementedError it for _KndxIndex.
    modified:
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
    ------------------------------------------------------------
    revno: 4011.5.6
    revision-id: andrew.bennetts at canonical.com-20090219033740-143irsufekboyfma
    parent: andrew.bennetts at canonical.com-20090218221156-mkh8bhbfqn42rs8o
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: missing-parents-in-pack-index
    timestamp: Thu 2009-02-19 14:37:40 +1100
    message:
      Make sure it's not possible to commit a pack write group when any versioned file has missing compression parents.
    modified:
      bzrlib/repofmt/pack_repo.py    pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
      bzrlib/tests/test_pack_repository.py test_pack_repository-20080801043947-eaw0e6h2gu75kwmy-1
    ------------------------------------------------------------
    revno: 4011.5.5
    revision-id: andrew.bennetts at canonical.com-20090218221156-mkh8bhbfqn42rs8o
    parent: andrew.bennetts at canonical.com-20090218054235-944h8gplfyjwzepw
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: missing-parents-in-pack-index
    timestamp: Thu 2009-02-19 09:11:56 +1100
    message:
      Fix typo in comment.
    modified:
      bzrlib/tests/test_btree_index.py test_index.py-20080624222253-p0x5f92uyh5hw734-13
    ------------------------------------------------------------
    revno: 4011.5.4
    revision-id: andrew.bennetts at canonical.com-20090218054235-944h8gplfyjwzepw
    parent: andrew.bennetts at canonical.com-20090218054039-zzb6g266wttjhk4d
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: missing-parents-in-pack-index
    timestamp: Wed 2009-02-18 16:42:35 +1100
    message:
      Remove obsolete test double.
    modified:
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
    ------------------------------------------------------------
    revno: 4011.5.3
    revision-id: andrew.bennetts at canonical.com-20090218054039-zzb6g266wttjhk4d
    parent: andrew.bennetts at canonical.com-20090218030140-ae0h6i2z52qy7w4t
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: missing-parents-in-pack-index
    timestamp: Wed 2009-02-18 16:40:39 +1100
    message:
      Implement and test external_references on GraphIndex and BTreeGraphIndex.
    modified:
      bzrlib/btree_index.py          index.py-20080624222253-p0x5f92uyh5hw734-7
      bzrlib/index.py                index.py-20070712131115-lolkarso50vjr64s-1
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/tests/test_btree_index.py test_index.py-20080624222253-p0x5f92uyh5hw734-13
      bzrlib/tests/test_index.py     test_index.py-20070712131115-lolkarso50vjr64s-2
    ------------------------------------------------------------
    revno: 4011.5.2
    revision-id: andrew.bennetts at canonical.com-20090218030140-ae0h6i2z52qy7w4t
    parent: andrew.bennetts at canonical.com-20090217054444-xhb5m6x05tjf5b26
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: missing-parents-in-pack-index
    timestamp: Wed 2009-02-18 14:01:40 +1100
    message:
      Add more tests, improve existing tests, add GraphIndex._external_references()
    modified:
      bzrlib/index.py                index.py-20070712131115-lolkarso50vjr64s-1
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
    ------------------------------------------------------------
    revno: 4011.5.1
    revision-id: andrew.bennetts at canonical.com-20090217054444-xhb5m6x05tjf5b26
    parent: pqm at pqm.ubuntu.com-20090216172448-vj35mjoe463c3bk2
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: missing-parents-in-pack-index
    timestamp: Tue 2009-02-17 16:44:44 +1100
    message:
      Start to add _add_unvalidated_index/get_missing_compression_parents methods to _KnitGraphIndex.
    modified:
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
=== modified file 'NEWS'
--- a/NEWS	2009-02-18 23:52:03 +0000
+++ b/NEWS	2009-02-20 00:45:16 +0000
@@ -73,6 +73,12 @@
       to aid branch types that are not bzr branch objects (like
       RemoteBranch). (Robert Collins, Andrew Bennetts)
 
+    * The ``_index`` of ``KnitVersionedFiles`` now supports the ability
+      to scan an underlying index that is going to be incorporated into
+      the ``KnitVersionedFiles`` object, to determine if it has missing
+      delta references. The method is ``scan_unvalidated_index``.
+      (Andrew Bennetts, Robert Collins)
+
 
 bzr 1.12 "1234567890" 2009-02-13
 --------------------------------

=== modified file 'bzrlib/btree_index.py'
--- a/bzrlib/btree_index.py	2008-11-28 02:32:40 +0000
+++ b/bzrlib/btree_index.py	2009-02-18 05:40:39 +0000
@@ -801,6 +801,19 @@
             new_tips = next_tips
         return final_offsets
 
+    def external_references(self, ref_list_num):
+        if self._root_node is None:
+            self._get_root_node()
+        if ref_list_num + 1 > self.node_ref_lists:
+            raise ValueError('No ref list %d, index has %d ref lists'
+                % (ref_list_num, self.node_ref_lists))
+        keys = set()
+        refs = set()
+        for node in self.iter_all_entries():
+            keys.add(node[1])
+            refs.update(node[3][ref_list_num])
+        return refs - keys
+
     def _find_layer_first_and_end(self, offset):
         """Find the start/stop nodes for the layer corresponding to offset.
 

=== modified file 'bzrlib/index.py'
--- a/bzrlib/index.py	2008-12-16 14:58:29 +0000
+++ b/bzrlib/index.py	2009-02-20 00:43:38 +0000
@@ -435,6 +435,19 @@
             # there must be one line - the empty trailer line.
             raise errors.BadIndexData(self)
 
+    def external_references(self, ref_list_num):
+        """Return references that are not present in this index.
+        """
+        self._buffer_all()
+        if ref_list_num + 1 > self.node_ref_lists:
+            raise ValueError('No ref list %d, index has %d ref lists'
+                % (ref_list_num, self.node_ref_lists))
+        refs = set()
+        for key, (value, ref_lists) in self._nodes.iteritems():
+            ref_list = ref_lists[ref_list_num]
+            refs.update(ref_list)
+        return refs - self._keys
+
     def _get_nodes_by_key(self):
         if self._nodes_by_key is None:
             nodes_by_key = {}

=== modified file 'bzrlib/knit.py'
--- a/bzrlib/knit.py	2009-02-02 05:56:34 +0000
+++ b/bzrlib/knit.py	2009-02-20 00:43:38 +0000
@@ -1881,6 +1881,18 @@
                 self._kndx_cache[prefix] = (orig_cache, orig_history)
                 raise
 
+    def scan_unvalidated_index(self, graph_index):
+        """See _KnitGraphIndex.scan_unvalidated_index."""
+        # Because kndx files do not support atomic insertion via separate index
+        # files, they do not support this method.
+        raise NotImplementedError(self.scan_unvalidated_index)
+
+    def get_missing_compression_parents(self):
+        """See _KnitGraphIndex.get_missing_compression_parents."""
+        # Because kndx files do not support atomic insertion via separate index
+        # files, they do not support this method.
+        raise NotImplementedError(self.get_missing_compression_parents)
+    
     def _cache_key(self, key, options, pos, size, parent_keys):
         """Cache a version record in the history array and index cache.
 
@@ -2196,6 +2208,7 @@
                 "parent tracking.")
         self.has_graph = parents
         self._is_locked = is_locked
+        self._missing_compression_parents = set()
 
     def __repr__(self):
         return "%s(%r)" % (self.__class__.__name__, self._graph_index)
@@ -2263,6 +2276,26 @@
                 result.append((key, value))
         self._add_callback(result)
         
+    def scan_unvalidated_index(self, graph_index):
+        """Inform this _KnitGraphIndex that there is an unvalidated index.
+
+        This allows this _KnitGraphIndex to keep track of any missing
+        compression parents we may want to have filled in to make those
+        indices valid.
+
+        :param graph_index: A GraphIndex
+        """
+        if self._deltas:
+            new_missing = graph_index.external_references(ref_list_num=1)
+            new_missing.difference_update(self.get_parent_map(new_missing))
+            self._missing_compression_parents.update(new_missing)
+
+    def get_missing_compression_parents(self):
+        """Return the keys of compression parents missing from unvalidated
+        indices.
+        """
+        return frozenset(self._missing_compression_parents)
+
     def _check_read(self):
         """raise if reads are not permitted."""
         if not self._is_locked():

=== modified file 'bzrlib/repofmt/pack_repo.py'
--- a/bzrlib/repofmt/pack_repo.py	2009-01-08 16:57:10 +0000
+++ b/bzrlib/repofmt/pack_repo.py	2009-02-20 00:43:38 +0000
@@ -1805,6 +1805,20 @@
         self.repo._text_knit = None
 
     def _commit_write_group(self):
+        all_missing = set()
+        for prefix, versioned_file in (
+                ('revisions', self.repo.revisions),
+                ('inventories', self.repo.inventories),
+                ('texts', self.repo.texts),
+                ('signatures', self.repo.signatures),
+                ):
+            # We use KnitVersionedFiles exclusively so can rely on _index.
+            missing = versioned_file._index.get_missing_compression_parents()
+            all_missing.update([(prefix,) + key for key in missing])
+        if all_missing:
+            raise errors.BzrCheckError(
+                "Repository %s has missing compression parent(s) %r "
+                 % (self.repo, sorted(all_missing)))
         self._remove_pack_indices(self._new_pack)
         if self._new_pack.data_inserted():
             # get all the data to disk and read to use

=== modified file 'bzrlib/tests/test_btree_index.py'
--- a/bzrlib/tests/test_btree_index.py	2008-11-09 18:40:17 +0000
+++ b/bzrlib/tests/test_btree_index.py	2009-02-18 22:11:56 +0000
@@ -869,6 +869,37 @@
             (index, ('name', 'fin2'), 'beta', ((), ))]),
             set(index.iter_entries_prefix([('name', None)])))
 
+    # XXX: external_references tests are duplicated in test_index.  We
+    # probably should have per_graph_index tests...
+    def test_external_references_no_refs(self):
+        index = self.make_index(ref_lists=0, nodes=[])
+        self.assertRaises(ValueError, index.external_references, 0)
+
+    def test_external_references_no_results(self):
+        index = self.make_index(ref_lists=1, nodes=[
+            (('key',), 'value', ([],))])
+        self.assertEqual(set(), index.external_references(0))
+
+    def test_external_references_missing_ref(self):
+        missing_key = ('missing',)
+        index = self.make_index(ref_lists=1, nodes=[
+            (('key',), 'value', ([missing_key],))])
+        self.assertEqual(set([missing_key]), index.external_references(0))
+
+    def test_external_references_multiple_ref_lists(self):
+        missing_key = ('missing',)
+        index = self.make_index(ref_lists=2, nodes=[
+            (('key',), 'value', ([], [missing_key]))])
+        self.assertEqual(set([]), index.external_references(0))
+        self.assertEqual(set([missing_key]), index.external_references(1))
+
+    def test_external_references_two_records(self):
+        index = self.make_index(ref_lists=1, nodes=[
+            (('key-1',), 'value', ([('key-2',)],)),
+            (('key-2',), 'value', ([],)),
+            ])
+        self.assertEqual(set([]), index.external_references(0))
+
 
 class TestBTreeNodes(BTreeTestCase):
 

=== modified file 'bzrlib/tests/test_index.py'
--- a/bzrlib/tests/test_index.py	2008-12-16 14:58:29 +0000
+++ b/bzrlib/tests/test_index.py	2009-02-20 00:43:38 +0000
@@ -922,6 +922,37 @@
         index = self.make_index(nodes=[(('key', ), 'value', ())])
         index.validate()
 
+    # XXX: external_references tests are duplicated in test_btree_index.  We
+    # probably should have per_graph_index tests...
+    def test_external_references_no_refs(self):
+        index = self.make_index(ref_lists=0, nodes=[])
+        self.assertRaises(ValueError, index.external_references, 0)
+
+    def test_external_references_no_results(self):
+        index = self.make_index(ref_lists=1, nodes=[
+            (('key',), 'value', ([],))])
+        self.assertEqual(set(), index.external_references(0))
+
+    def test_external_references_missing_ref(self):
+        missing_key = ('missing',)
+        index = self.make_index(ref_lists=1, nodes=[
+            (('key',), 'value', ([missing_key],))])
+        self.assertEqual(set([missing_key]), index.external_references(0))
+
+    def test_external_references_multiple_ref_lists(self):
+        missing_key = ('missing',)
+        index = self.make_index(ref_lists=2, nodes=[
+            (('key',), 'value', ([], [missing_key]))])
+        self.assertEqual(set([]), index.external_references(0))
+        self.assertEqual(set([missing_key]), index.external_references(1))
+
+    def test_external_references_two_records(self):
+        index = self.make_index(ref_lists=1, nodes=[
+            (('key-1',), 'value', ([('key-2',)],)),
+            (('key-2',), 'value', ([],)),
+            ])
+        self.assertEqual(set([]), index.external_references(0))
+
 
 class TestCombinedGraphIndex(TestCaseWithMemoryTransport):
 

=== modified file 'bzrlib/tests/test_knit.py'
--- a/bzrlib/tests/test_knit.py	2009-01-22 21:32:15 +0000
+++ b/bzrlib/tests/test_knit.py	2009-02-20 00:43:38 +0000
@@ -1237,6 +1237,15 @@
             else:
                 raise
 
+    def test_scan_unvalidated_index_not_implemented(self):
+        transport = MockTransport()
+        index = self.get_knit_index(transport, 'filename', 'r')
+        self.assertRaises(
+            NotImplementedError, index.scan_unvalidated_index,
+            'dummy graph_index')
+        self.assertRaises(
+            NotImplementedError, index.get_missing_compression_parents)
+
     def test_short_line(self):
         transport = MockTransport([
             _KndxIndex.HEADER,
@@ -1601,6 +1610,81 @@
              (('tip',), 'line-delta', (None, 0, 100), [('parent',)])])
         self.assertEqual([], self.caught_entries)
 
+    def make_g_index_missing_compression_parent(self):
+        graph_index = self.make_g_index('missing_comp', 2,
+            [(('tip', ), ' 100 78',
+              ([('missing-parent', ), ('ghost', )], [('missing-parent', )]))])
+        return graph_index
+    
+    def make_g_index_no_external_refs(self):
+        graph_index = self.make_g_index('no_external_refs', 2,
+            [(('rev', ), ' 100 78',
+              ([('parent', ), ('ghost', )], []))])
+        return graph_index
+
+    def test_add_good_unvalidated_index(self):
+        unvalidated = self.make_g_index_no_external_refs()
+        combined = CombinedGraphIndex([unvalidated])
+        index = _KnitGraphIndex(combined, lambda: True, deltas=True)
+        index.scan_unvalidated_index(unvalidated)
+        self.assertEqual(frozenset(), index.get_missing_compression_parents())
+
+    def test_add_incomplete_unvalidated_index(self):
+        unvalidated = self.make_g_index_missing_compression_parent()
+        combined = CombinedGraphIndex([unvalidated])
+        index = _KnitGraphIndex(combined, lambda: True, deltas=True)
+        index.scan_unvalidated_index(unvalidated)
+        # This also checks that its only the compression parent that is
+        # examined, otherwise 'ghost' would also be reported as a missing
+        # parent.
+        self.assertEqual(
+            frozenset([('missing-parent',)]),
+            index.get_missing_compression_parents())
+
+    def test_add_unvalidated_index_with_present_external_references(self):
+        index = self.two_graph_index(deltas=True)
+        # Ugly hack to get at one of the underlying GraphIndex objects that
+        # two_graph_index built.
+        unvalidated = index._graph_index._indices[1]
+        # 'parent' is an external ref of _indices[1] (unvalidated), but is
+        # present in _indices[0].
+        index.scan_unvalidated_index(unvalidated)
+        self.assertEqual(frozenset(), index.get_missing_compression_parents())
+
+    def make_new_missing_parent_g_index(self, name):
+        missing_parent = name + '-missing-parent'
+        graph_index = self.make_g_index(name, 2,
+            [((name + 'tip', ), ' 100 78',
+              ([(missing_parent, ), ('ghost', )], [(missing_parent, )]))])
+        return graph_index
+
+    def test_add_mulitiple_unvalidated_indices_with_missing_parents(self):
+        g_index_1 = self.make_new_missing_parent_g_index('one')
+        g_index_2 = self.make_new_missing_parent_g_index('two')
+        combined = CombinedGraphIndex([g_index_1, g_index_2])
+        index = _KnitGraphIndex(combined, lambda: True, deltas=True)
+        index.scan_unvalidated_index(g_index_1)
+        index.scan_unvalidated_index(g_index_2)
+        self.assertEqual(
+            frozenset([('one-missing-parent',), ('two-missing-parent',)]),
+            index.get_missing_compression_parents())
+
+    def test_add_mulitiple_unvalidated_indices_with_mutual_dependencies(self):
+        graph_index_a = self.make_g_index('one', 2,
+            [(('parent-one', ), ' 100 78', ([('non-compression-parent',)], [])),
+             (('child-of-two', ), ' 100 78',
+              ([('parent-two',)], [('parent-two',)]))])
+        graph_index_b = self.make_g_index('two', 2,
+            [(('parent-two', ), ' 100 78', ([('non-compression-parent',)], [])),
+             (('child-of-one', ), ' 100 78',
+              ([('parent-one',)], [('parent-one',)]))])
+        combined = CombinedGraphIndex([graph_index_a, graph_index_b])
+        index = _KnitGraphIndex(combined, lambda: True, deltas=True)
+        index.scan_unvalidated_index(graph_index_a)
+        index.scan_unvalidated_index(graph_index_b)
+        self.assertEqual(
+            frozenset([]), index.get_missing_compression_parents())
+        
 
 class TestNoParentsGraphIndexKnit(KnitTests):
     """Tests for knits using _KnitGraphIndex with no parents."""
@@ -1614,6 +1698,14 @@
         size = trans.put_file(name, stream)
         return GraphIndex(trans, name, size)
 
+    def test_add_good_unvalidated_index(self):
+        unvalidated = self.make_g_index('unvalidated')
+        combined = CombinedGraphIndex([unvalidated])
+        index = _KnitGraphIndex(combined, lambda: True, parents=False)
+        index.scan_unvalidated_index(unvalidated)
+        self.assertEqual(frozenset(),
+            index.get_missing_compression_parents())
+
     def test_parents_deltas_incompatible(self):
         index = CombinedGraphIndex([])
         self.assertRaises(errors.KnitError, _KnitGraphIndex, lambda:True,

=== modified file 'bzrlib/tests/test_pack_repository.py'
--- a/bzrlib/tests/test_pack_repository.py	2008-11-27 07:25:52 +0000
+++ b/bzrlib/tests/test_pack_repository.py	2009-02-19 03:37:40 +0000
@@ -533,6 +533,48 @@
         self.assertRaises(errors.NoSuchRevision,
             missing_ghost.get_inventory, 'ghost')
 
+    def make_write_ready_repo(self):
+        repo = self.make_repository('.', format=self.get_format())
+        repo.lock_write()
+        repo.start_write_group()
+        return repo
+
+    def test_missing_inventories_compression_parent_prevents_commit(self):
+        repo = self.make_write_ready_repo()
+        key = ('junk',)
+        repo.inventories._index._missing_compression_parents.add(key)
+        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
+        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
+        repo.abort_write_group()
+        repo.unlock()
+
+    def test_missing_revisions_compression_parent_prevents_commit(self):
+        repo = self.make_write_ready_repo()
+        key = ('junk',)
+        repo.revisions._index._missing_compression_parents.add(key)
+        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
+        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
+        repo.abort_write_group()
+        repo.unlock()
+
+    def test_missing_signatures_compression_parent_prevents_commit(self):
+        repo = self.make_write_ready_repo()
+        key = ('junk',)
+        repo.signatures._index._missing_compression_parents.add(key)
+        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
+        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
+        repo.abort_write_group()
+        repo.unlock()
+
+    def test_missing_text_compression_parent_prevents_commit(self):
+        repo = self.make_write_ready_repo()
+        key = ('some', 'junk')
+        repo.texts._index._missing_compression_parents.add(key)
+        self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
+        e = self.assertRaises(errors.BzrCheckError, repo.commit_write_group)
+        repo.abort_write_group()
+        repo.unlock()
+
     def test_supports_external_lookups(self):
         repo = self.make_repository('.', format=self.get_format())
         self.assertEqual(self.format_supports_external_lookups,




More information about the bazaar-commits mailing list