Rev 3334: * -Dlock when passed to the selftest (e.g. ``bzr -Dlock selftest``) will in http://people.ubuntu.com/~robertc/baz2.0/physicallock.hooks

Robert Collins robertc at robertcollins.net
Fri Apr 4 04:57:48 BST 2008


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

------------------------------------------------------------
revno: 3334
revision-id: robertc at robertcollins.net-20080404035733-3d7jzhcfa0fiid2v
parent: robertc at robertcollins.net-20080404035337-ldligjwfp2bzqi47
committer: Robert Collins <robertc at robertcollins.net>
branch nick: test-suite.lock_checking
timestamp: Fri 2008-04-04 14:57:33 +1100
message:
   * -Dlock when passed to the selftest (e.g. ``bzr -Dlock selftest``) will
     cause mismatched physical locks to cause test errors rather than just
     reporting to the screen. (Robert Collins)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
  bzrlib/tests/test_selftest.py  test_selftest.py-20051202044319-c110a115d8c0456a
=== modified file 'NEWS'
--- a/NEWS	2008-04-04 02:13:33 +0000
+++ b/NEWS	2008-04-04 03:57:33 +0000
@@ -137,6 +137,10 @@
 
   TESTING:
 
+    * -Dlock when passed to the selftest (e.g. ``bzr -Dlock selftest``) will
+      cause mismatched physical locks to cause test errors rather than just
+      reporting to the screen. (Robert Collins)
+
     * New -Dselftest_debug flag disables clearing of the debug flags during
       tests.  This is useful if you want to use e.g. -Dhpss to help debug a
       failing test.  Be aware that using this feature is likely to cause

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2008-04-03 00:18:39 +0000
+++ b/bzrlib/tests/__init__.py	2008-04-04 03:57:33 +0000
@@ -51,6 +51,7 @@
     bzrdir,
     debug,
     errors,
+    lock as _mod_lock,
     memorytree,
     osutils,
     progress,
@@ -807,6 +808,7 @@
         self._benchcalls = []
         self._benchtime = None
         self._clear_hooks()
+        self._track_locks()
         self._clear_debug_flags()
 
     def _clear_debug_flags(self):
@@ -842,6 +844,47 @@
         ui.ui_factory = ui.SilentUIFactory()
         self.addCleanup(_restore)
 
+    def _check_locks(self):
+        """Check that all lock take/release actions have been paired."""
+        # once we have fixed all the current lock problems, we can change the
+        # following code to always check for mismatched locks, but only do
+        # traceback showing with -Dlock (self._lock_check_thorough is True).
+        # For now, because the test suite will fail, we only assert that lock
+        # matching has occured with -Dlock.
+        # unhook:
+        _mod_lock.hooks = self._original_lock_hooks
+        acquired_locks = [lock for action, lock in self._lock_actions
+            if action == 'acquired']
+        released_locks = [lock for action, lock in self._lock_actions
+            if action == 'released']
+        # trivially, given the tests for lock acquistion and release, if we
+        # have as many in each list, it should be ok.
+        if len(acquired_locks) != len(released_locks):
+            message = \
+                ("Different number of acquired and released locks. (%s, %s)" %
+                (acquired_locks, released_locks))
+            if not self._lock_check_thorough:
+                # Rather than fail, just warn
+                print "Broken test %s: %s" % (self, message)
+                return
+            self.fail(message)
+
+    def _track_locks(self):
+        """Track lock activity during tests."""
+        self._lock_actions = []
+        self._original_lock_hooks = _mod_lock.hooks
+        self._lock_check_thorough = 'lock' in debug.debug_flags
+        self.addCleanup(self._check_locks)
+        _mod_lock.hooks = _mod_lock.PhysicalLockHooks()
+        _mod_lock.hooks.install_hook('acquired', self._lock_acquired)
+        _mod_lock.hooks.install_hook('released', self._lock_released)
+
+    def _lock_acquired(self, result):
+        self._lock_actions.append(('acquired', result))
+
+    def _lock_released(self, result):
+        self._lock_actions.append(('released', result))
+
     def _ndiff_strings(self, a, b):
         """Return ndiff between two strings containing lines.
         

=== modified file 'bzrlib/tests/test_selftest.py'
--- a/bzrlib/tests/test_selftest.py	2008-03-26 21:43:57 +0000
+++ b/bzrlib/tests/test_selftest.py	2008-04-04 03:57:33 +0000
@@ -27,7 +27,9 @@
 import bzrlib
 from bzrlib import (
     bzrdir,
+    debug,
     errors,
+    lockdir,
     memorytree,
     osutils,
     repository,
@@ -641,6 +643,25 @@
         # But we have a safety net in place.
         self.assertRaises(AssertionError, self._check_safety_net)
 
+    def test_dangling_locks_cause_failures(self):
+        # This is currently only enabled during debug runs, so turn debugging
+        # on.
+        debug.debug_flags.add('lock')
+        class InstrumentedTestResult(ExtendedTestResult):
+
+            def report_test_start(self, test): pass
+            def report_error(self, test, error): pass
+        result = InstrumentedTestResult(None, None, None, None)
+        class TestDanglingLock(TestCaseWithMemoryTransport):
+            def test_function(self):
+                t = self.get_transport('.')
+                l = lockdir.LockDir(t, 'lock')
+                l.create()
+                l.attempt_lock()
+        test = TestDanglingLock('test_function')
+        test.run(result)
+        self.assertEqual(1, len(result.errors))
+
 
 class TestTestCaseWithTransport(TestCaseWithTransport):
     """Tests for the convenience functions TestCaseWithTransport introduces."""




More information about the bazaar-commits mailing list