Rev 3029: (robertc) Many fixes to support packs on the smart server and as the in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Mon Nov 26 21:33:24 GMT 2007


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

------------------------------------------------------------
revno: 3029
revision-id:pqm at pqm.ubuntu.com-20071126213320-adxxra3gsie5inhw
parent: pqm at pqm.ubuntu.com-20071126205533-5vehpxjf6uk2n8fy
parent: robertc at robertcollins.net-20071126203008-hst9k6pxrbzoci6w
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Mon 2007-11-26 21:33:20 +0000
message:
  (robertc) Many fixes to support packs on the smart server and as the
  	default format. (Robert Collins)
modified:
  bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
  bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
  bzrlib/smart/branch.py         branch.py-20061124031907-mzh3pla28r83r97f-1
  bzrlib/smart/repository.py     repository.py-20061128022038-vr5wy5bubyb8xttk-1
  bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
  bzrlib/tests/branch_implementations/test_break_lock.py test_break_lock.py-20060504111902-9aae411dbe9aadd2
  bzrlib/tests/branch_implementations/test_locking.py test_locking.py-20060707151933-tav3o2hpibwi53u4-4
  bzrlib/tests/bzrdir_implementations/test_bzrdir.py test_bzrdir.py-20060131065642-0ebeca5e30e30866
  bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
  bzrlib/tests/test_smart.py     test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
  bzrlib/tests/workingtree_implementations/test_break_lock.py test_break_lock.py-20060504115740-233e245df546fd42
    ------------------------------------------------------------
    revno: 3015.2.15
    revision-id:robertc at robertcollins.net-20071126203008-hst9k6pxrbzoci6w
    parent: robertc at robertcollins.net-20071126041028-n1roq2ofjdvtct63
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: pack.read-locks
    timestamp: Tue 2007-11-27 07:30:08 +1100
    message:
      Review feedback.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/tests/branch_implementations/test_locking.py test_locking.py-20060707151933-tav3o2hpibwi53u4-4
      bzrlib/tests/bzrdir_implementations/test_bzrdir.py test_bzrdir.py-20060131065642-0ebeca5e30e30866
    ------------------------------------------------------------
    revno: 3015.2.14
    revision-id:robertc at robertcollins.net-20071126041028-n1roq2ofjdvtct63
    parent: robertc at robertcollins.net-20071126034718-uj6tz7ob18h4cw9i
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: pack.read-locks
    timestamp: Mon 2007-11-26 15:10:28 +1100
    message:
      Make branch_implementations.test_locking honour the repository API more.
    modified:
      bzrlib/tests/branch_implementations/test_locking.py test_locking.py-20060707151933-tav3o2hpibwi53u4-4
    ------------------------------------------------------------
    revno: 3015.2.13
    revision-id:robertc at robertcollins.net-20071126034718-uj6tz7ob18h4cw9i
    parent: robertc at robertcollins.net-20071126033630-nvz32vtouqcksjdy
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: pack.read-locks
    timestamp: Mon 2007-11-26 14:47:18 +1100
    message:
      More lock correctness for the use of get_file_text in repository_implementations.
    modified:
      bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
    ------------------------------------------------------------
    revno: 3015.2.12
    revision-id:robertc at robertcollins.net-20071126033630-nvz32vtouqcksjdy
    parent: robertc at robertcollins.net-20071126031158-0jhxvgtik27maw29
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: pack.read-locks
    timestamp: Mon 2007-11-26 14:36:30 +1100
    message:
      Make test_smart use specific formats as needed to exercise locked and unlocked repositories.
    modified:
      bzrlib/tests/test_smart.py     test_smart.py-20061122024551-ol0l0o0oofsu9b3t-2
    ------------------------------------------------------------
    revno: 3015.2.11
    revision-id:robertc at robertcollins.net-20071126031158-0jhxvgtik27maw29
    parent: robertc at robertcollins.net-20071126023626-g5by92lh6cakhkpq
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: pack.read-locks
    timestamp: Mon 2007-11-26 14:11:58 +1100
    message:
      Handle repositories that do not physically lock in workingtree_implementation tests.
    modified:
      bzrlib/tests/workingtree_implementations/test_break_lock.py test_break_lock.py-20060504115740-233e245df546fd42
    ------------------------------------------------------------
    revno: 3015.2.10
    revision-id:robertc at robertcollins.net-20071126023626-g5by92lh6cakhkpq
    parent: robertc at robertcollins.net-20071126021110-bnc8ls8pjlbojj92
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: pack.read-locks
    timestamp: Mon 2007-11-26 13:36:26 +1100
    message:
      Fix regression due to other pack related fixes in tests with packs not-default.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
    ------------------------------------------------------------
    revno: 3015.2.9
    revision-id:robertc at robertcollins.net-20071126021110-bnc8ls8pjlbojj92
    parent: robertc at robertcollins.net-20071126021007-sf06t361rmv8renw
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: pack.read-locks
    timestamp: Mon 2007-11-26 13:11:10 +1100
    message:
      Handle repositories that do not allow remote locking, like pack repositories, in the client side remote server proxy objects.
    modified:
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
    ------------------------------------------------------------
    revno: 3015.2.8
    revision-id:robertc at robertcollins.net-20071126021007-sf06t361rmv8renw
    parent: robertc at robertcollins.net-20071126020813-7sqwqvr0rucxv0oc
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: pack.read-locks
    timestamp: Mon 2007-11-26 13:10:07 +1100
    message:
      Typo in __set_repository_format's docstring.
    modified:
      bzrlib/bzrdir.py               bzrdir.py-20060131065624-156dfea39c4387cb
    ------------------------------------------------------------
    revno: 3015.2.7
    revision-id:robertc at robertcollins.net-20071126020813-7sqwqvr0rucxv0oc
    parent: robertc at robertcollins.net-20071126020652-u7lp6gpb86ppvl1r
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: pack.read-locks
    timestamp: Mon 2007-11-26 13:08:13 +1100
    message:
      In the RemoteServer repository methods handle repositories that cannot be remotely locked like pack repositories, and add a read lock in SmartServerRepositoryStreamKnitDataForRevisions.
    modified:
      bzrlib/smart/repository.py     repository.py-20061128022038-vr5wy5bubyb8xttk-1
    ------------------------------------------------------------
    revno: 3015.2.6
    revision-id:robertc at robertcollins.net-20071126020652-u7lp6gpb86ppvl1r
    parent: robertc at robertcollins.net-20071126020511-udqau8afmvtulcxg
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: pack.read-locks
    timestamp: Mon 2007-11-26 13:06:52 +1100
    message:
      In the RemoteServer branch methods handle repositories that cannot be remotely locked like pack repositories.
    modified:
      bzrlib/smart/branch.py         branch.py-20061124031907-mzh3pla28r83r97f-1
    ------------------------------------------------------------
    revno: 3015.2.5
    revision-id:robertc at robertcollins.net-20071126020511-udqau8afmvtulcxg
    parent: robertc at robertcollins.net-20071126020303-7l85pl5tw4qznb5l
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: pack.read-locks
    timestamp: Mon 2007-11-26 13:05:11 +1100
    message:
      Handle repositories that cannot be remotely locked in branch_implementations.test_locking.
    modified:
      bzrlib/tests/branch_implementations/test_locking.py test_locking.py-20060707151933-tav3o2hpibwi53u4-4
    ------------------------------------------------------------
    revno: 3015.2.4
    revision-id:robertc at robertcollins.net-20071126020303-7l85pl5tw4qznb5l
    parent: robertc at robertcollins.net-20071126013122-p6mtvopbu4u7w59y
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: pack.read-locks
    timestamp: Mon 2007-11-26 13:03:03 +1100
    message:
      Handle repositories that cannot be remotely locked in branch_implementations.test_break_lock.
    modified:
      bzrlib/tests/branch_implementations/test_break_lock.py test_break_lock.py-20060504111902-9aae411dbe9aadd2
    ------------------------------------------------------------
    revno: 3015.2.3
    revision-id:robertc at robertcollins.net-20071126013122-p6mtvopbu4u7w59y
    parent: robertc at robertcollins.net-20071126011805-y12x1dtg7kc4k2vq
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: pack.read-locks
    timestamp: Mon 2007-11-26 12:31:22 +1100
    message:
      Use write groups around revision signature tests for branch.
    modified:
      bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
    ------------------------------------------------------------
    revno: 3015.2.2
    revision-id:robertc at robertcollins.net-20071126011805-y12x1dtg7kc4k2vq
    parent: robertc at robertcollins.net-20071125221339-u715g0yylii6g7ue
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: pack.read-locks
    timestamp: Mon 2007-11-26 12:18:05 +1100
    message:
      Make test_bzrdir work with packs - which always change the pack value during clone.
    modified:
      bzrlib/tests/bzrdir_implementations/test_bzrdir.py test_bzrdir.py-20060131065642-0ebeca5e30e30866
    ------------------------------------------------------------
    revno: 3015.2.1
    revision-id:robertc at robertcollins.net-20071125221339-u715g0yylii6g7ue
    parent: pqm at pqm.ubuntu.com-20071122234103-fn117zncqrqv39me
    committer: Robert Collins <robertc at robertcollins.net>
    branch nick: pack.read-locks
    timestamp: Mon 2007-11-26 09:13:39 +1100
    message:
      Lock correctness in branch implementation tests.
    modified:
      bzrlib/tests/branch_implementations/test_branch.py testbranch.py-20050711070244-121d632bc37d7253
=== modified file 'bzrlib/bzrdir.py'
--- a/bzrlib/bzrdir.py	2007-11-26 13:55:51 +0000
+++ b/bzrlib/bzrdir.py	2007-11-26 21:33:20 +0000
@@ -1717,7 +1717,7 @@
         return RepositoryFormat.get_default_format()
 
     def __set_repository_format(self, value):
-        """Allow changint the repository format for metadir formats."""
+        """Allow changing the repository format for metadir formats."""
         self._repository_format = value
 
     repository_format = property(__return_repository_format, __set_repository_format)

=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py	2007-11-22 22:33:27 +0000
+++ b/bzrlib/remote.py	2007-11-26 20:30:08 +0000
@@ -412,7 +412,9 @@
 
     def get_physical_lock_status(self):
         """See Repository.get_physical_lock_status()."""
-        return False
+        # should be an API call to the server.
+        self._ensure_real()
+        return self._real_repository.get_physical_lock_status()
 
     def is_in_write_group(self):
         """Return True if there is an open write group.
@@ -465,7 +467,10 @@
     def lock_write(self, token=None):
         if not self._lock_mode:
             self._lock_token = self._remote_lock_write(token)
-            assert self._lock_token, 'Remote server did not return a token!'
+            # if self._lock_token is None, then this is something like packs or
+            # svn where we don't get to lock the repo, or a weave style repository
+            # where we cannot lock it over the wire and attempts to do so will
+            # fail.
             if self._real_repository is not None:
                 self._real_repository.lock_write(token=self._lock_token)
             if token is not None:
@@ -478,12 +483,16 @@
             raise errors.ReadOnlyError(self)
         else:
             self._lock_count += 1
-        return self._lock_token
+        return self._lock_token or None
 
     def leave_lock_in_place(self):
+        if not self._lock_token:
+            raise NotImplementedError(self.leave_lock_in_place)
         self._leave_lock = True
 
     def dont_leave_lock_in_place(self):
+        if not self._lock_token:
+            raise NotImplementedError(self.dont_leave_lock_in_place)
         self._leave_lock = False
 
     def _set_real_repository(self, repository):
@@ -514,6 +523,9 @@
 
     def _unlock(self, token):
         path = self.bzrdir._path_for_remote_call(self._client)
+        if not token:
+            # with no token the remote repository is not persistently locked.
+            return
         response = self._client.call('Repository.unlock', path, token)
         if response == ('ok',):
             return
@@ -542,9 +554,6 @@
             if old_mode == 'w':
                 # Only write-locked repositories need to make a remote method
                 # call to perfom the unlock.
-                assert self._lock_token, \
-                    '%s is locked, but has no token' \
-                    % self
                 old_token = self._lock_token
                 self._lock_token = None
                 if not self._leave_lock:
@@ -604,8 +613,6 @@
         builder = self._real_repository.get_commit_builder(branch, parents,
                 config, timestamp=timestamp, timezone=timezone,
                 committer=committer, revprops=revprops, revision_id=revision_id)
-        # Make the builder use this RemoteRepository rather than the real one.
-        builder.repository = self
         return builder
 
     @needs_write_lock
@@ -1055,7 +1062,7 @@
             self.repository.unlock()
         path = self.bzrdir._path_for_remote_call(self._client)
         response = self._client.call('Branch.lock_write', path, branch_token,
-                                     repo_token)
+                                     repo_token or '')
         if response[0] == 'ok':
             ok, branch_token, repo_token = response
             return branch_token, repo_token
@@ -1108,12 +1115,12 @@
                 if token != self._lock_token:
                     raise errors.TokenMismatch(token, self._lock_token)
             self._lock_count += 1
-        return self._lock_token
+        return self._lock_token or None
 
     def _unlock(self, branch_token, repo_token):
         path = self.bzrdir._path_for_remote_call(self._client)
         response = self._client.call('Branch.unlock', path, branch_token,
-                                     repo_token)
+                                     repo_token or '')
         if response == ('ok',):
             return
         elif response[0] == 'TokenMismatch':
@@ -1129,7 +1136,8 @@
             mode = self._lock_mode
             self._lock_mode = None
             if self._real_branch is not None:
-                if not self._leave_lock:
+                if (not self._leave_lock and mode == 'w' and
+                    self._repo_lock_token):
                     # If this RemoteBranch will remove the physical lock for the
                     # repository, make sure the _real_branch doesn't do it
                     # first.  (Because the _real_branch's repository is set to
@@ -1153,9 +1161,13 @@
         return self._real_branch.break_lock()
 
     def leave_lock_in_place(self):
+        if not self._lock_token:
+            raise NotImplementedError(self.leave_lock_in_place)
         self._leave_lock = True
 
     def dont_leave_lock_in_place(self):
+        if not self._lock_token:
+            raise NotImplementedError(self.dont_leave_lock_in_place)
         self._leave_lock = False
 
     def last_revision_info(self):

=== modified file 'bzrlib/smart/branch.py'
--- a/bzrlib/smart/branch.py	2007-10-05 04:43:17 +0000
+++ b/bzrlib/smart/branch.py	2007-11-26 02:06:52 +0000
@@ -128,6 +128,7 @@
             try:
                 branch_token = branch.lock_write(token=branch_token)
             finally:
+                # this leaves the repository with 1 lock
                 branch.repository.unlock()
         except errors.LockContention:
             return FailedSmartServerResponse(('LockContention',))
@@ -137,7 +138,10 @@
             return FailedSmartServerResponse(('UnlockableTransport',))
         except errors.LockFailed, e:
             return FailedSmartServerResponse(('LockFailed', str(e.lock), str(e.why)))
-        branch.repository.leave_lock_in_place()
+        if repo_token is None:
+            repo_token = ''
+        else:
+            branch.repository.leave_lock_in_place()
         branch.leave_lock_in_place()
         branch.unlock()
         return SuccessfulSmartServerResponse(('ok', branch_token, repo_token))
@@ -154,7 +158,8 @@
                 branch.repository.unlock()
         except errors.TokenMismatch:
             return FailedSmartServerResponse(('TokenMismatch',))
-        branch.repository.dont_leave_lock_in_place()
+        if repo_token:
+            branch.repository.dont_leave_lock_in_place()
         branch.dont_leave_lock_in_place()
         branch.unlock()
         return SuccessfulSmartServerResponse(('ok',))

=== modified file 'bzrlib/smart/repository.py'
--- a/bzrlib/smart/repository.py	2007-10-17 09:39:41 +0000
+++ b/bzrlib/smart/repository.py	2007-11-26 02:08:13 +0000
@@ -168,7 +168,8 @@
         except errors.LockFailed, e:
             return FailedSmartServerResponse(('LockFailed',
                 str(e.lock), str(e.why)))
-        repository.leave_lock_in_place()
+        if token is not None:
+            repository.leave_lock_in_place()
         repository.unlock()
         if token is None:
             token = ''
@@ -249,6 +250,13 @@
 class SmartServerRepositoryStreamKnitDataForRevisions(SmartServerRepositoryRequest):
 
     def do_repository_request(self, repository, *revision_ids):
+        repository.lock_read()
+        try:
+            return self._do_repository_request(repository, revision_ids)
+        finally:
+            repository.unlock()
+
+    def _do_repository_request(self, repository, revision_ids):
         stream = repository.get_data_stream(revision_ids)
         filelike = StringIO()
         pack = ContainerWriter(filelike.write)

=== modified file 'bzrlib/tests/branch_implementations/test_branch.py'
--- a/bzrlib/tests/branch_implementations/test_branch.py	2007-11-01 09:52:45 +0000
+++ b/bzrlib/tests/branch_implementations/test_branch.py	2007-11-26 01:31:22 +0000
@@ -97,6 +97,8 @@
 
         rev = b2.repository.get_revision('revision-1')
         tree = b2.repository.revision_tree('revision-1')
+        tree.lock_read()
+        self.addCleanup(tree.unlock)
         self.assertEqual(tree.get_file_text('foo-id'), 'hello')
 
     def test_get_revision_delta(self):
@@ -262,8 +264,19 @@
     def test_store_signature(self):
         wt = self.make_branch_and_tree('.')
         branch = wt.branch
-        branch.repository.store_revision_signature(
-            gpg.LoopbackGPGStrategy(None), 'FOO', 'A')
+        branch.lock_write()
+        try:
+            branch.repository.start_write_group()
+            try:
+                branch.repository.store_revision_signature(
+                    gpg.LoopbackGPGStrategy(None), 'FOO', 'A')
+            except:
+                branch.repository.abort_write_group()
+                raise
+            else:
+                branch.repository.commit_write_group()
+        finally:
+            branch.unlock()
         self.assertRaises(errors.NoSuchRevision,
                           branch.repository.has_signature_for_revision_id,
                           'A')

=== modified file 'bzrlib/tests/branch_implementations/test_break_lock.py'
--- a/bzrlib/tests/branch_implementations/test_break_lock.py	2007-11-01 09:52:45 +0000
+++ b/bzrlib/tests/branch_implementations/test_break_lock.py	2007-11-26 02:03:03 +0000
@@ -20,7 +20,7 @@
 
 import bzrlib
 import bzrlib.errors as errors
-from bzrlib.tests import TestCase, TestCaseWithTransport
+from bzrlib.tests import TestCase, TestCaseWithTransport, TestNotApplicable
 from bzrlib.tests.branch_implementations.test_branch import TestCaseWithBranch
 
 
@@ -51,6 +51,9 @@
         # break lock on the branch should try on the repository even
         # if the branch isn't locked
         self.branch.repository.lock_write()
+        other_instance = self.branch.repository.bzrdir.open_repository()
+        if not other_instance.get_physical_lock_status():
+            raise TestNotApplicable("Repository does not lock persistently.")
         bzrlib.ui.ui_factory.stdin = StringIO("y\n")
         try:
             self.unused_branch.break_lock()

=== modified file 'bzrlib/tests/branch_implementations/test_locking.py'
--- a/bzrlib/tests/branch_implementations/test_locking.py	2007-04-18 05:10:19 +0000
+++ b/bzrlib/tests/branch_implementations/test_locking.py	2007-11-26 20:30:08 +0000
@@ -42,17 +42,21 @@
         bcf = b.control_files
         rcf = getattr(b.repository, 'control_files', None)
         if rcf is None:
-            raise TestSkipped(
-                "This tests depends on being able to instrument "
-                "repository.control_files, but %r doesn't have control_files."
-                % (b.repository,))
-
-        # Look out for branch types that reuse their control files
-        self.combined_control = bcf is rcf
-
-        b.control_files = LockWrapper(self.locks, b.control_files, 'bc')
-        b.repository.control_files = \
-            LockWrapper(self.locks, b.repository.control_files, 'rc')
+            self.combined_branch = False
+        else:
+            # Look out for branch types that reuse their control files
+            self.combined_control = bcf is rcf
+        try:
+            b.control_files = LockWrapper(self.locks, b.control_files, 'bc')
+        except AttributeError:
+            # RemoteBranch seems to trigger this.
+            raise TestSkipped("Could not instrument branch control files.")
+        if self.combined_control:
+            # instrument the repository control files too to ensure its worked
+            # with correctly. When they are not shared, we trust the repository
+            # API and only instrument the repository itself. 
+            b.repository.control_files = \
+                LockWrapper(self.locks, b.repository.control_files, 'rc')
         return b
 
     def test_01_lock_read(self):
@@ -70,15 +74,24 @@
         self.assertFalse(b.is_locked())
         self.assertFalse(b.repository.is_locked())
 
-        self.assertEqual([('b', 'lr', True),
-                          ('r', 'lr', True),
-                          ('rc', 'lr', True),
-                          ('bc', 'lr', True),
-                          ('b', 'ul', True),
-                          ('bc', 'ul', True),
-                          ('r', 'ul', True),
-                          ('rc', 'ul', True),
-                         ], self.locks)
+        if self.combined_control:
+            self.assertEqual([('b', 'lr', True),
+                              ('r', 'lr', True),
+                              ('rc', 'lr', True),
+                              ('bc', 'lr', True),
+                              ('b', 'ul', True),
+                              ('bc', 'ul', True),
+                              ('r', 'ul', True),
+                              ('rc', 'ul', True),
+                             ], self.locks)
+        else:
+            self.assertEqual([('b', 'lr', True),
+                              ('r', 'lr', True),
+                              ('bc', 'lr', True),
+                              ('b', 'ul', True),
+                              ('bc', 'ul', True),
+                              ('r', 'ul', True),
+                             ], self.locks)
 
     def test_02_lock_write(self):
         # Test that locking occurs in the correct order
@@ -95,15 +108,24 @@
         self.assertFalse(b.is_locked())
         self.assertFalse(b.repository.is_locked())
 
-        self.assertEqual([('b', 'lw', True),
-                          ('r', 'lw', True),
-                          ('rc', 'lw', True),
-                          ('bc', 'lw', True),
-                          ('b', 'ul', True),
-                          ('bc', 'ul', True),
-                          ('r', 'ul', True),
-                          ('rc', 'ul', True),
-                         ], self.locks)
+        if self.combined_control:
+            self.assertEqual([('b', 'lw', True),
+                              ('r', 'lw', True),
+                              ('rc', 'lw', True),
+                              ('bc', 'lw', True),
+                              ('b', 'ul', True),
+                              ('bc', 'ul', True),
+                              ('r', 'ul', True),
+                              ('rc', 'ul', True),
+                             ], self.locks)
+        else:
+            self.assertEqual([('b', 'lw', True),
+                              ('r', 'lw', True),
+                              ('bc', 'lw', True),
+                              ('b', 'ul', True),
+                              ('bc', 'ul', True),
+                              ('r', 'ul', True),
+                             ], self.locks)
 
     def test_03_lock_fail_unlock_repo(self):
         # Make sure branch.unlock() is called, even if there is a
@@ -126,14 +148,23 @@
 
             # We unlock the branch control files, even if 
             # we fail to unlock the repository
-            self.assertEqual([('b', 'lw', True),
-                              ('r', 'lw', True),
-                              ('rc', 'lw', True),
-                              ('bc', 'lw', True),
-                              ('b', 'ul', True),
-                              ('bc', 'ul', True),
-                              ('r', 'ul', False), 
-                             ], self.locks)
+            if self.combined_control:
+                self.assertEqual([('b', 'lw', True),
+                                  ('r', 'lw', True),
+                                  ('rc', 'lw', True),
+                                  ('bc', 'lw', True),
+                                  ('b', 'ul', True),
+                                  ('bc', 'ul', True),
+                                  ('r', 'ul', False),
+                                 ], self.locks)
+            else:
+                self.assertEqual([('b', 'lw', True),
+                                  ('r', 'lw', True),
+                                  ('bc', 'lw', True),
+                                  ('b', 'ul', True),
+                                  ('bc', 'ul', True),
+                                  ('r', 'ul', False),
+                                 ], self.locks)
 
         finally:
             # For cleanup purposes, make sure we are unlocked
@@ -159,15 +190,24 @@
 
             # We unlock the repository even if 
             # we fail to unlock the control files
-            self.assertEqual([('b', 'lw', True),
-                              ('r', 'lw', True),
-                              ('rc', 'lw', True),
-                              ('bc', 'lw', True),
-                              ('b', 'ul', True),
-                              ('bc', 'ul', False),
-                              ('r', 'ul', True), 
-                              ('rc', 'ul', True), 
-                             ], self.locks)
+            if self.combined_control:
+                self.assertEqual([('b', 'lw', True),
+                                  ('r', 'lw', True),
+                                  ('rc', 'lw', True),
+                                  ('bc', 'lw', True),
+                                  ('b', 'ul', True),
+                                  ('bc', 'ul', False),
+                                  ('r', 'ul', True),
+                                  ('rc', 'ul', True),
+                                 ], self.locks)
+            else:
+                self.assertEqual([('b', 'lw', True),
+                                  ('r', 'lw', True),
+                                  ('bc', 'lw', True),
+                                  ('b', 'ul', True),
+                                  ('bc', 'ul', False),
+                                  ('r', 'ul', True),
+                                 ], self.locks)
 
         finally:
             # For cleanup purposes, make sure we are unlocked
@@ -208,13 +248,20 @@
         self.assertFalse(b.is_locked())
         self.assertFalse(b.repository.is_locked())
 
-        self.assertEqual([('b', 'lr', True),
-                          ('r', 'lr', True),
-                          ('rc', 'lr', True),
-                          ('bc', 'lr', False),
-                          ('r', 'ul', True),
-                          ('rc', 'ul', True),
-                         ], self.locks)
+        if self.combined_control:
+            self.assertEqual([('b', 'lr', True),
+                              ('r', 'lr', True),
+                              ('rc', 'lr', True),
+                              ('bc', 'lr', False),
+                              ('r', 'ul', True),
+                              ('rc', 'ul', True),
+                             ], self.locks)
+        else:
+            self.assertEqual([('b', 'lr', True),
+                              ('r', 'lr', True),
+                              ('bc', 'lr', False),
+                              ('r', 'ul', True),
+                             ], self.locks)
 
     def test_08_lock_write_fail_control(self):
         # Test the repository is unlocked if we can't lock self
@@ -224,14 +271,20 @@
         self.assertRaises(TestPreventLocking, b.lock_write)
         self.assertFalse(b.is_locked())
         self.assertFalse(b.repository.is_locked())
-
-        self.assertEqual([('b', 'lw', True),
-                          ('r', 'lw', True),
-                          ('rc', 'lw', True),
-                          ('bc', 'lw', False),
-                          ('r', 'ul', True),
-                          ('rc', 'ul', True),
-                         ], self.locks)
+        if self.combined_control:
+            self.assertEqual([('b', 'lw', True),
+                              ('r', 'lw', True),
+                              ('rc', 'lw', True),
+                              ('bc', 'lw', False),
+                              ('r', 'ul', True),
+                              ('rc', 'ul', True),
+                             ], self.locks)
+        else:
+            self.assertEqual([('b', 'lw', True),
+                              ('r', 'lw', True),
+                              ('bc', 'lw', False),
+                              ('r', 'ul', True),
+                             ], self.locks)
 
     def test_lock_write_returns_None_refuses_token(self):
         branch = self.make_branch('b')
@@ -398,24 +451,33 @@
             except NotImplementedError:
                 # This branch doesn't support this API.
                 return
-            branch.repository.leave_lock_in_place()
-            repo_token = branch.repository.lock_write()
-            branch.repository.unlock()
+            try:
+                branch.repository.leave_lock_in_place()
+            except NotImplementedError:
+                # This repo doesn't support leaving locks around,
+                # assume it is essentially lock-free.
+                repo_token = None
+            else:
+                repo_token = branch.repository.lock_write()
+                branch.repository.unlock()
         finally:
             branch.unlock()
         # Reacquire the lock (with a different branch object) by using the
         # tokens.
         new_branch = branch.bzrdir.open_branch()
-        # We have to explicitly lock the repository first.
-        new_branch.repository.lock_write(token=repo_token)
+        if repo_token is not None:
+            # We have to explicitly lock the repository first.
+            new_branch.repository.lock_write(token=repo_token)
         new_branch.lock_write(token=token)
-        # Now we don't need our own repository lock anymore (the branch is
-        # holding it for us).
-        new_branch.repository.unlock()
+        if repo_token is not None:
+            # Now we don't need our own repository lock anymore (the branch is
+            # holding it for us).
+            new_branch.repository.unlock()
         # Call dont_leave_lock_in_place, so that the lock will be released by
         # this instance, even though the lock wasn't originally acquired by it.
         new_branch.dont_leave_lock_in_place()
-        new_branch.repository.dont_leave_lock_in_place()
+        if repo_token is not None:
+            new_branch.repository.dont_leave_lock_in_place()
         new_branch.unlock()
         # Now the branch (and repository) is unlocked.  Test this by locking it
         # without tokens.
@@ -437,8 +499,14 @@
         branch = branch.bzrdir.open_branch()
         branch.lock_write()
         try:
-            # Now the branch.repository is locked, so we can't lock it with a new
-            # repository without a token.
+            # The branch should have asked the repository to lock.
+            self.assertTrue(branch.repository.is_write_locked())
+            # Does the repository type actually lock?
+            if not branch.repository.get_physical_lock_status():
+                # The test was successfully applied, so it was applicable.
+                return
+            # Now the branch.repository is physically locked, so we can't lock
+            # it with a new repository instance.
             new_repo = branch.bzrdir.open_repository()
             self.assertRaises(errors.LockContention, new_repo.lock_write)
             # We can call lock_write on the original repository object though,

=== modified file 'bzrlib/tests/bzrdir_implementations/test_bzrdir.py'
--- a/bzrlib/tests/bzrdir_implementations/test_bzrdir.py	2007-11-14 18:18:59 +0000
+++ b/bzrlib/tests/bzrdir_implementations/test_bzrdir.py	2007-11-26 20:30:08 +0000
@@ -18,6 +18,7 @@
 
 from cStringIO import StringIO
 import errno
+from itertools import izip
 import os
 from stat import S_ISDIR
 import sys
@@ -80,6 +81,10 @@
         reading it again, which leads to changed timestamps. This is ok though,
         because the inventory.kndx file is not ignored, and the integrity of
         knit joins is tested by test_knit and test_versionedfile.
+
+        :seealso: Additionally, assertRepositoryHasSameItems provides value
+            rather than representation checking of repositories for
+            equivalence.
         """
         files = []
         directories = ['.']
@@ -101,6 +106,63 @@
                                          target.get(path).read(),
                                          "text for file %r differs:\n" % path)
 
+    def assertRepositoryHasSameItems(self, left_repo, right_repo):
+        """require left_repo and right_repo to contain the same data."""
+        # XXX: TODO: Doesn't work yet, because we need to be able to compare
+        # local repositories to remote ones...  but this is an as-yet unsolved
+        # aspect of format management and the Remote protocols...
+        # self.assertEqual(left_repo._format.__class__,
+        #     right_repo._format.__class__)
+        left_repo.lock_read()
+        try:
+            right_repo.lock_read()
+            try:
+                # revs
+                all_revs = left_repo.all_revision_ids()
+                self.assertEqual(left_repo.all_revision_ids(),
+                    right_repo.all_revision_ids())
+                for rev_id in left_repo.all_revision_ids():
+                    self.assertEqual(left_repo.get_revision(rev_id),
+                        right_repo.get_revision(rev_id))
+                # inventories
+                left_inv_weave = left_repo.get_inventory_weave()
+                right_inv_weave = right_repo.get_inventory_weave()
+                self.assertEqual(set(left_inv_weave.versions()),
+                    set(right_inv_weave.versions()))
+                # XXX: currently this does not handle indirectly referenced
+                # inventories (e.g. where the inventory is a delta basis for
+                # one that is fully present but that the revid for that
+                # inventory is not yet present.)
+                self.assertEqual(set(left_inv_weave.versions()), set(all_revs))
+                left_trees = left_repo.revision_trees(all_revs)
+                right_trees = right_repo.revision_trees(all_revs)
+                for left_tree, right_tree in izip(left_trees, right_trees):
+                    self.assertEqual(left_tree.inventory, right_tree.inventory)
+                # texts
+                text_index = left_repo._generate_text_key_index()
+                self.assertEqual(text_index,
+                    right_repo._generate_text_key_index())
+                for file_id, revision_id in text_index.iterkeys():
+                    left_weave = left_repo.weave_store.get_weave(
+                        file_id, left_repo.get_transaction())
+                    right_weave = right_repo.weave_store.get_weave(
+                        file_id, right_repo.get_transaction())
+                    self.assertEqual(
+                        left_weave.get_text(revision_id),
+                        right_weave.get_text(revision_id))
+                # signatures
+                for rev_id in all_revs:
+                    try:
+                        left_text = left_repo.get_signature_text(rev_id)
+                    except NoSuchRevision:
+                        continue
+                    right_text = right_repo.get_signature_text(rev_id)
+                    self.assertEqual(left_text, right_text)
+            finally:
+                right_repo.unlock()
+        finally:
+            left_repo.unlock()
+
     def skipIfNoWorkingTree(self, a_bzrdir):
         """Raises TestSkipped if a_bzrdir doesn't have a working tree.
         
@@ -229,9 +291,9 @@
         self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
                                     [
                                      './.bzr/merge-hashes',
-                                     './.bzr/repository/inventory.knit',
+                                     './.bzr/repository',
                                      ])
-
+        self.assertRepositoryHasSameItems(tree.branch.repository, repo)
 
     def test_clone_bzrdir_repository_under_shared(self):
         tree = self.make_branch_and_tree('commit_tree')
@@ -324,8 +386,9 @@
         target = dir.clone(self.get_url('target/child'), force_new_repo=True)
         self.assertNotEqual(dir.transport.base, target.transport.base)
         self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
-                                    ['./.bzr/repository/inventory.knit',
+                                    ['./.bzr/repository',
                                      ])
+        self.assertRepositoryHasSameItems(tree.branch.repository, repo)
 
     def test_clone_bzrdir_repository_revision(self):
         # test for revision limiting, [smoke test, not corner case checks].
@@ -361,9 +424,11 @@
                                      './.bzr/basis-inventory-cache',
                                      './.bzr/checkout/stat-cache',
                                      './.bzr/merge-hashes',
-                                     './.bzr/repository/inventory.knit',
+                                     './.bzr/repository',
                                      './.bzr/stat-cache',
                                     ])
+        self.assertRepositoryHasSameItems(
+            tree.branch.repository, target.open_repository())
 
     def test_clone_bzrdir_branch_and_repo_into_shared_repo(self):
         # by default cloning into a shared repo uses the shared repo.
@@ -401,10 +466,11 @@
         dir = source.bzrdir
         target = dir.clone(self.get_url('target/child'), force_new_repo=True)
         self.assertNotEqual(dir.transport.base, target.transport.base)
-        target.open_repository()
+        repo = target.open_repository()
         self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
-                                    ['./.bzr/repository/inventory.knit',
+                                    ['./.bzr/repository',
                                      ])
+        self.assertRepositoryHasSameItems(tree.branch.repository, repo)
 
     def test_clone_bzrdir_branch_reference(self):
         # cloning should preserve the reference status of the branch in a bzrdir
@@ -418,9 +484,7 @@
             return
         target = dir.clone(self.get_url('target'))
         self.assertNotEqual(dir.transport.base, target.transport.base)
-        self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
-                                    ['./.bzr/repository/inventory.knit',
-                                     ])
+        self.assertDirectoriesEqual(dir.root_transport, target.root_transport)
 
     def test_clone_bzrdir_branch_revision(self):
         # test for revision limiting, [smoke test, not corner case checks].
@@ -454,9 +518,10 @@
                                      './.bzr/checkout/stat-cache',
                                      './.bzr/checkout/merge-hashes',
                                      './.bzr/merge-hashes',
-                                     './.bzr/repository/inventory.knit',
+                                     './.bzr/repository',
                                      ])
-
+        self.assertRepositoryHasSameItems(tree.branch.repository,
+            target.open_repository())
         target.open_workingtree().revert()
 
     def test_revert_inventory(self):
@@ -473,8 +538,10 @@
                                      './.bzr/checkout/stat-cache',
                                      './.bzr/checkout/merge-hashes',
                                      './.bzr/merge-hashes',
-                                     './.bzr/repository/inventory.knit',
+                                     './.bzr/repository',
                                      ])
+        self.assertRepositoryHasSameItems(tree.branch.repository,
+            target.open_repository())
 
         target.open_workingtree().revert()
         self.assertDirectoriesEqual(dir.root_transport, target.root_transport,
@@ -483,8 +550,10 @@
                                      './.bzr/checkout/stat-cache',
                                      './.bzr/checkout/merge-hashes',
                                      './.bzr/merge-hashes',
-                                     './.bzr/repository/inventory.knit',
+                                     './.bzr/repository',
                                      ])
+        self.assertRepositoryHasSameItems(tree.branch.repository,
+            target.open_repository())
 
     def test_clone_bzrdir_tree_branch_reference(self):
         # a tree with a branch reference (aka a checkout) 
@@ -923,9 +992,11 @@
                                      './.bzr/checkout/inventory',
                                      './.bzr/inventory',
                                      './.bzr/parent',
-                                     './.bzr/repository/inventory.knit',
+                                     './.bzr/repository',
                                      './.bzr/stat-cache',
                                      ])
+        self.assertRepositoryHasSameItems(
+            tree.branch.repository, target.open_repository())
 
     def test_sprout_bzrdir_tree_branch_reference(self):
         # sprouting should create a repository if needed and a sprouted branch.
@@ -1427,6 +1498,13 @@
         # break lock with just a repo should unlock the repo.
         repo = self.make_repository('.')
         repo.lock_write()
+        lock_repo = repo.bzrdir.open_repository()
+        if not lock_repo.get_physical_lock_status():
+            # This bzrdir's default repository does not physically lock things
+            # and thus this interaction cannot be tested at the interface
+            # level.
+            repo.unlock()
+            return
         # only one yes needed here: it should only be unlocking
         # the repo
         bzrlib.ui.ui_factory.stdin = StringIO("y\n")
@@ -1436,7 +1514,6 @@
             # this bzrdir does not implement break_lock - so we cant test it.
             repo.unlock()
             return
-        lock_repo = repo.bzrdir.open_repository()
         lock_repo.lock_write()
         lock_repo.unlock()
         self.assertRaises(errors.LockBroken, repo.unlock)
@@ -1462,23 +1539,31 @@
             # dir is inappropriately accessed, 3 will be needed, and
             # we'll see that because the stream will be fully consumed
             bzrlib.ui.ui_factory.stdin = StringIO("y\ny\ny\n")
+            # determine if the repository will have been locked;
+            this_repo_locked = \
+                thisdir.open_repository().get_physical_lock_status()
             master.bzrdir.break_lock()
-            # only two ys should have been read
-            self.assertEqual("y\n", bzrlib.ui.ui_factory.stdin.read())
+            if this_repo_locked:
+                # only two ys should have been read
+                self.assertEqual("y\n", bzrlib.ui.ui_factory.stdin.read())
+            else:
+                # only one y should have been read
+                self.assertEqual("y\ny\n", bzrlib.ui.ui_factory.stdin.read())
             # we should be able to lock a newly opened branch now
             branch = master.bzrdir.open_branch()
             branch.lock_write()
             branch.unlock()
-            # we should not be able to lock the repository in thisdir as its still
-            # held by the explicit lock we took, and the break lock should not have
-            # touched it.
-            repo = thisdir.open_repository()
-            orig_default = lockdir._DEFAULT_TIMEOUT_SECONDS
-            try:
-                lockdir._DEFAULT_TIMEOUT_SECONDS = 1
-                self.assertRaises(errors.LockContention, repo.lock_write)
-            finally:
-                lockdir._DEFAULT_TIMEOUT_SECONDS = orig_default
+            if this_repo_locked:
+                # we should not be able to lock the repository in thisdir as
+                # its still held by the explicit lock we took, and the break
+                # lock should not have touched it.
+                repo = thisdir.open_repository()
+                orig_default = lockdir._DEFAULT_TIMEOUT_SECONDS
+                try:
+                    lockdir._DEFAULT_TIMEOUT_SECONDS = 1
+                    self.assertRaises(errors.LockContention, repo.lock_write)
+                finally:
+                    lockdir._DEFAULT_TIMEOUT_SECONDS = orig_default
         finally:
             unused_repo.unlock()
         self.assertRaises(errors.LockBroken, master.unlock)

=== modified file 'bzrlib/tests/repository_implementations/test_repository.py'
--- a/bzrlib/tests/repository_implementations/test_repository.py	2007-11-17 17:54:25 +0000
+++ b/bzrlib/tests/repository_implementations/test_repository.py	2007-11-26 03:47:18 +0000
@@ -853,6 +853,8 @@
         # now access over vfat; should be safe
         branch = bzrdir.BzrDir.open('vfat+' + self.get_url('repo')).open_branch()
         revtree = branch.repository.revision_tree(REV_ID)
+        revtree.lock_read()
+        self.addCleanup(revtree.unlock)
         contents = revtree.get_file_text(FOO_ID)
         self.assertEqual(contents, 'contents of repo/foo\n')
 

=== modified file 'bzrlib/tests/test_smart.py'
--- a/bzrlib/tests/test_smart.py	2007-10-19 05:38:36 +0000
+++ b/bzrlib/tests/test_smart.py	2007-11-26 03:36:30 +0000
@@ -17,7 +17,9 @@
 """Tests for the smart wire/domain protocol.
 
 This module contains tests for the domain-level smart requests and responses,
-such as the 'Branch.lock_write' request.
+such as the 'Branch.lock_write' request. Many of these use specific disk
+formats to exercise calls that only make sense for formats with specific
+properties.
 
 Tests for low-level protocol encoding are found in test_smart_transport.
 """
@@ -378,7 +380,7 @@
     def test_lock_write_on_unlocked_branch(self):
         backing = self.get_transport()
         request = smart.branch.SmartServerBranchRequestLockWrite(backing)
-        branch = self.make_branch('.')
+        branch = self.make_branch('.', format='knit')
         repository = branch.repository
         response = request.execute(backing.local_abspath(''))
         branch_nonce = branch.control_files._lock.peek().get('nonce')
@@ -405,7 +407,7 @@
     def test_lock_write_with_tokens_on_locked_branch(self):
         backing = self.get_transport()
         request = smart.branch.SmartServerBranchRequestLockWrite(backing)
-        branch = self.make_branch('.')
+        branch = self.make_branch('.', format='knit')
         branch_token = branch.lock_write()
         repo_token = branch.repository.lock_write()
         branch.repository.unlock()
@@ -420,7 +422,7 @@
     def test_lock_write_with_mismatched_tokens_on_locked_branch(self):
         backing = self.get_transport()
         request = smart.branch.SmartServerBranchRequestLockWrite(backing)
-        branch = self.make_branch('.')
+        branch = self.make_branch('.', format='knit')
         branch_token = branch.lock_write()
         repo_token = branch.repository.lock_write()
         branch.repository.unlock()
@@ -435,7 +437,7 @@
     def test_lock_write_on_locked_repo(self):
         backing = self.get_transport()
         request = smart.branch.SmartServerBranchRequestLockWrite(backing)
-        branch = self.make_branch('.')
+        branch = self.make_branch('.', format='knit')
         branch.repository.lock_write()
         branch.repository.leave_lock_in_place()
         branch.repository.unlock()
@@ -462,7 +464,7 @@
     def test_unlock_on_locked_branch_and_repo(self):
         backing = self.get_transport()
         request = smart.branch.SmartServerBranchRequestUnlock(backing)
-        branch = self.make_branch('.')
+        branch = self.make_branch('.', format='knit')
         # Lock the branch
         branch_token = branch.lock_write()
         repo_token = branch.repository.lock_write()
@@ -485,7 +487,7 @@
     def test_unlock_on_unlocked_branch_unlocked_repo(self):
         backing = self.get_transport()
         request = smart.branch.SmartServerBranchRequestUnlock(backing)
-        branch = self.make_branch('.')
+        branch = self.make_branch('.', format='knit')
         response = request.execute(
             backing.local_abspath(''), 'branch token', 'repo token')
         self.assertEqual(
@@ -494,7 +496,7 @@
     def test_unlock_on_unlocked_branch_locked_repo(self):
         backing = self.get_transport()
         request = smart.branch.SmartServerBranchRequestUnlock(backing)
-        branch = self.make_branch('.')
+        branch = self.make_branch('.', format='knit')
         # Lock the repository.
         repo_token = branch.repository.lock_write()
         branch.repository.leave_lock_in_place()
@@ -690,7 +692,7 @@
     def test_lock_write_on_unlocked_repo(self):
         backing = self.get_transport()
         request = smart.repository.SmartServerRepositoryLockWrite(backing)
-        repository = self.make_repository('.')
+        repository = self.make_repository('.', format='knit')
         response = request.execute(backing.local_abspath(''))
         nonce = repository.control_files._lock.peek().get('nonce')
         self.assertEqual(SmartServerResponse(('ok', nonce)), response)
@@ -702,7 +704,7 @@
     def test_lock_write_on_locked_repo(self):
         backing = self.get_transport()
         request = smart.repository.SmartServerRepositoryLockWrite(backing)
-        repository = self.make_repository('.')
+        repository = self.make_repository('.', format='knit')
         repository.lock_write()
         repository.leave_lock_in_place()
         repository.unlock()
@@ -713,7 +715,7 @@
     def test_lock_write_on_readonly_transport(self):
         backing = self.get_readonly_transport()
         request = smart.repository.SmartServerRepositoryLockWrite(backing)
-        repository = self.make_repository('.')
+        repository = self.make_repository('.', format='knit')
         response = request.execute('')
         self.assertFalse(response.is_successful())
         self.assertEqual('LockFailed', response.args[0])
@@ -728,7 +730,7 @@
     def test_unlock_on_locked_repo(self):
         backing = self.get_transport()
         request = smart.repository.SmartServerRepositoryUnlock(backing)
-        repository = self.make_repository('.')
+        repository = self.make_repository('.', format='knit')
         token = repository.lock_write()
         repository.leave_lock_in_place()
         repository.unlock()
@@ -744,7 +746,7 @@
     def test_unlock_on_unlocked_repo(self):
         backing = self.get_transport()
         request = smart.repository.SmartServerRepositoryUnlock(backing)
-        repository = self.make_repository('.')
+        repository = self.make_repository('.', format='knit')
         response = request.execute(backing.local_abspath(''), 'some token')
         self.assertEqual(
             SmartServerResponse(('TokenMismatch',)), response)

=== modified file 'bzrlib/tests/workingtree_implementations/test_break_lock.py'
--- a/bzrlib/tests/workingtree_implementations/test_break_lock.py	2007-02-26 01:06:36 +0000
+++ b/bzrlib/tests/workingtree_implementations/test_break_lock.py	2007-11-26 03:11:58 +0000
@@ -20,6 +20,7 @@
 
 import bzrlib
 import bzrlib.errors as errors
+from bzrlib.tests import TestNotApplicable
 from bzrlib.tests.workingtree_implementations import TestCaseWithWorkingTree
 
 
@@ -51,14 +52,19 @@
         # if the workingtree isn't locked - and the easiest way
         # to see if that happened is to lock the repo.
         self.workingtree.branch.repository.lock_write()
-        bzrlib.ui.ui_factory.stdin = StringIO("y\n")
+        stdin = StringIO("y\n")
+        bzrlib.ui.ui_factory.stdin = stdin
         try:
             self.unused_workingtree.break_lock()
         except NotImplementedError:
             # workingtree does not support break_lock
             self.workingtree.branch.repository.unlock()
             return
-        self.assertRaises(errors.LockBroken, self.workingtree.branch.repository.unlock)
+        remaining = stdin.read()
+        if remaining == 'y\n':
+            raise TestNotApplicable("repository does not physically lock.")
+        self.assertRaises(errors.LockBroken,
+            self.workingtree.branch.repository.unlock)
 
     def test_locked(self):
         # break_lock when locked should




More information about the bazaar-commits mailing list