Rev 4334: Extract repository access in WorkingTree._check to be data driven, adding a new _get_check_refs method to support this. in http://people.ubuntu.com/~robertc/baz2.0/check

Robert Collins robertc at robertcollins.net
Fri May 8 03:07:06 BST 2009


At http://people.ubuntu.com/~robertc/baz2.0/check

------------------------------------------------------------
revno: 4334
revision-id: robertc at robertcollins.net-20090508020636-f5w6t5ry2g1xluyo
parent: robertc at robertcollins.net-20090506054834-4zzevk11lk0a1b32
committer: Robert Collins <robertc at robertcollins.net>
branch nick: check
timestamp: Fri 2009-05-08 12:06:36 +1000
message:
  Extract repository access in WorkingTree._check to be data driven, adding a new _get_check_refs method to support this.
=== modified file 'NEWS'
--- a/NEWS	2009-05-05 18:48:00 +0000
+++ b/NEWS	2009-05-08 02:06:36 +0000
@@ -80,6 +80,9 @@
   instead of ``InstallFailed`` when they detect a missing revision.
   ``InstallFailed`` itself has been deleted. (Jonathan Lange)
 
+* ``WorkingTree._check`` now requires a references dict with keys matching
+  those returned by ``WorkingTree._get_check_refs``. (Robert Collins)
+
 Internals
 *********
 

=== modified file 'bzrlib/check.py'
--- a/bzrlib/check.py	2009-03-23 14:59:43 +0000
+++ b/bzrlib/check.py	2009-05-08 02:06:36 +0000
@@ -32,6 +32,16 @@
 # raising them.  If there's more than one exception it'd be good to see them
 # all.
 
+"""Checking of bzr objects.
+
+check_refs is a concept used for optimising check. Objects that depend on other
+objects (e.g. tree on repository) can list the objects they would be requesting
+so that when the dependent object is checked, matches can be pulled out and
+evaluated in-line rather than re-reading the same data many times.
+check_refs are tuples (kind, value). Currently defined kinds are:
+* 'trees', where value is a revid.
+"""
+
 from bzrlib import errors, osutils
 from bzrlib import repository as _mod_repository
 from bzrlib import revision
@@ -296,7 +306,20 @@
         if tree is not None:
             note("Checking working tree at '%s'."
                  % (tree.bzrdir.root_transport.base,))
-            tree._check()
+            tree.lock_read()
+            try:
+                needed_refs = tree._get_check_refs()
+                refs = {}
+                for ref in needed_refs:
+                    kind, value = ref
+                    if kind == 'trees':
+                        refs[ref] = tree.branch.repository.revision_tree(value)
+                    else:
+                        raise AssertionError(
+                            'unknown ref kind for ref %s' % ref)
+                tree._check(refs)
+            finally:
+                tree.unlock()
         else:
             log_error("No working tree found at specified location.")
 

=== modified file 'bzrlib/tests/workingtree_implementations/__init__.py'
--- a/bzrlib/tests/workingtree_implementations/__init__.py	2009-04-11 16:06:53 +0000
+++ b/bzrlib/tests/workingtree_implementations/__init__.py	2009-05-08 02:06:36 +0000
@@ -60,46 +60,50 @@
 
 
 def load_tests(standard_tests, module, loader):
+    test_names = [
+        'add_reference',
+        'add',
+        'basis_inventory',
+        'basis_tree',
+        'break_lock',
+        'changes_from',
+        'check',
+        'content_filters',
+        'commit',
+        'eol_conversion',
+        'executable',
+        'flush',
+        'get_file_with_stat',
+        'get_file_mtime',
+        'get_parent_ids',
+        'inv',
+        'is_control_filename',
+        'is_ignored',
+        'locking',
+        'merge_from_branch',
+        'mkdir',
+        'move',
+        'nested_specifics',
+        'parents',
+        'paths2ids',
+        'pull',
+        'put_file',
+        'readonly',
+        'read_working_inventory',
+        'remove',
+        'rename_one',
+        'revision_tree',
+        'set_root_id',
+        'smart_add',
+        'uncommit',
+        'unversion',
+        'views',
+        'walkdirs',
+        'workingtree',
+        ]
     test_workingtree_implementations = [
-        'bzrlib.tests.workingtree_implementations.test_add_reference',
-        'bzrlib.tests.workingtree_implementations.test_add',
-        'bzrlib.tests.workingtree_implementations.test_basis_inventory',
-        'bzrlib.tests.workingtree_implementations.test_basis_tree',
-        'bzrlib.tests.workingtree_implementations.test_break_lock',
-        'bzrlib.tests.workingtree_implementations.test_changes_from',
-        'bzrlib.tests.workingtree_implementations.test_content_filters',
-        'bzrlib.tests.workingtree_implementations.test_commit',
-        'bzrlib.tests.workingtree_implementations.test_eol_conversion',
-        'bzrlib.tests.workingtree_implementations.test_executable',
-        'bzrlib.tests.workingtree_implementations.test_flush',
-        'bzrlib.tests.workingtree_implementations.test_get_file_with_stat',
-        'bzrlib.tests.workingtree_implementations.test_get_file_mtime',
-        'bzrlib.tests.workingtree_implementations.test_get_parent_ids',
-        'bzrlib.tests.workingtree_implementations.test_inv',
-        'bzrlib.tests.workingtree_implementations.test_is_control_filename',
-        'bzrlib.tests.workingtree_implementations.test_is_ignored',
-        'bzrlib.tests.workingtree_implementations.test_locking',
-        'bzrlib.tests.workingtree_implementations.test_merge_from_branch',
-        'bzrlib.tests.workingtree_implementations.test_mkdir',
-        'bzrlib.tests.workingtree_implementations.test_move',
-        'bzrlib.tests.workingtree_implementations.test_nested_specifics',
-        'bzrlib.tests.workingtree_implementations.test_parents',
-        'bzrlib.tests.workingtree_implementations.test_paths2ids',
-        'bzrlib.tests.workingtree_implementations.test_pull',
-        'bzrlib.tests.workingtree_implementations.test_put_file',
-        'bzrlib.tests.workingtree_implementations.test_readonly',
-        'bzrlib.tests.workingtree_implementations.test_read_working_inventory',
-        'bzrlib.tests.workingtree_implementations.test_remove',
-        'bzrlib.tests.workingtree_implementations.test_rename_one',
-        'bzrlib.tests.workingtree_implementations.test_revision_tree',
-        'bzrlib.tests.workingtree_implementations.test_set_root_id',
-        'bzrlib.tests.workingtree_implementations.test_smart_add',
-        'bzrlib.tests.workingtree_implementations.test_uncommit',
-        'bzrlib.tests.workingtree_implementations.test_unversion',
-        'bzrlib.tests.workingtree_implementations.test_views',
-        'bzrlib.tests.workingtree_implementations.test_walkdirs',
-        'bzrlib.tests.workingtree_implementations.test_workingtree',
-        ]
+        'bzrlib.tests.workingtree_implementations.test_' + name for
+        name in test_names]
 
     scenarios = make_scenarios(
         tests.default_transport,

=== added file 'bzrlib/tests/workingtree_implementations/test_check.py'
--- a/bzrlib/tests/workingtree_implementations/test_check.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/workingtree_implementations/test_check.py	2009-05-08 02:06:36 +0000
@@ -0,0 +1,55 @@
+# Copyright (C) 2009 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""Tests for checking of trees."""
+
+from bzrlib import (
+    tests,
+    )
+from bzrlib.tests.workingtree_implementations import TestCaseWithWorkingTree
+
+
+class TestCheck(TestCaseWithWorkingTree):
+
+    def test__get_check_refs_new(self):
+        tree = self.make_branch_and_tree('tree')
+        self.assertEqual(set([('trees', 'null:')]),
+            set(tree._get_check_refs()))
+
+    def test__get_check_refs_basis(self):
+        # with a basis, all current bzr trees cache it and so need the
+        # inventory to cross-check.
+        tree = self.make_branch_and_tree('tree')
+        revid = tree.commit('first post')
+        self.assertEqual(set([('trees', revid)]),
+            set(tree._get_check_refs()))
+
+    def test__check_with_refs(self):
+        # _check can be called with a dict of the things required.
+        tree = self.make_branch_and_tree('tree')
+        tree.lock_write()
+        self.addCleanup(tree.unlock)
+        revid = tree.commit('first post')
+        needed_refs = tree._get_check_refs()
+        repo = tree.branch.repository
+        for ref in needed_refs:
+            kind, revid = ref
+            refs = {}
+            if kind == 'trees':
+                refs[ref] = repo.revision_tree(revid)
+            else:
+                self.fail('unknown ref kind')
+        tree._check(refs)

=== modified file 'bzrlib/workingtree.py'
--- a/bzrlib/workingtree.py	2009-04-17 12:52:36 +0000
+++ b/bzrlib/workingtree.py	2009-05-08 02:06:36 +0000
@@ -290,6 +290,16 @@
         self._control_files.break_lock()
         self.branch.break_lock()
 
+    def _get_check_refs(self):
+        """Return the references needed to perform a check of this tree.
+        
+        The default implementation returns no refs, and is only suitable for
+        trees that have no local caching and can commit on ghosts at any time.
+
+        :seealso: bzrlib.check for details about check_refs.
+        """
+        return []
+
     def requires_rich_root(self):
         return self._format.requires_rich_root
 
@@ -2513,12 +2523,17 @@
         return un_resolved, resolved
 
     @needs_read_lock
-    def _check(self):
+    def _check(self, references):
+        """Check the tree for consistency.
+
+        :param references: A dict with keys matching the items returned by
+            self._get_check_refs(), and values from looking those keys up in
+            the repository.
+        """
         tree_basis = self.basis_tree()
         tree_basis.lock_read()
         try:
-            repo_basis = self.branch.repository.revision_tree(
-                self.last_revision())
+            repo_basis = references[('trees', self.last_revision())]
             if len(list(repo_basis.iter_changes(tree_basis))) > 0:
                 raise errors.BzrCheckError(
                     "Mismatched basis inventory content.")
@@ -2570,6 +2585,10 @@
         if self._inventory is None:
             self.read_working_inventory()
 
+    def _get_check_refs(self):
+        """Return the references needed to perform a check of this tree."""
+        return [('trees', self.last_revision())]
+
     def lock_tree_write(self):
         """See WorkingTree.lock_tree_write().
 
@@ -2632,6 +2651,10 @@
                 mode=self.bzrdir._get_file_mode())
             return True
 
+    def _get_check_refs(self):
+        """Return the references needed to perform a check of this tree."""
+        return [('trees', self.last_revision())]
+
     @needs_tree_write_lock
     def set_conflicts(self, conflicts):
         self._put_rio('conflicts', conflicts.to_stanzas(),




More information about the bazaar-commits mailing list