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