232
225
('rc', 'ul', True),
235
def test_lock_write_returns_None_refuses_token(self):
228
def test_lock_write_returns_None_refuses_tokens(self):
236
229
branch = self.make_branch('b')
237
token = branch.lock_write()
230
tokens = branch.lock_write()
239
if token is not None:
232
if tokens is not None:
240
233
# This test does not apply, because this lockable supports
243
236
self.assertRaises(errors.TokenLockingNotSupported,
244
branch.lock_write, token='token')
237
branch.lock_write, tokens=('token','token'))
248
def test_lock_write_raises_on_token_mismatch(self):
241
def test_reentering_lock_write_raises_on_token_mismatch(self):
249
242
branch = self.make_branch('b')
250
token = branch.lock_write()
243
tokens = branch.lock_write()
253
246
# This test does not apply, because this lockable refuses
256
different_token = token + 'xxx'
257
# Re-using the same lockable instance with a different token will
258
# raise TokenMismatch.
259
self.assertRaises(errors.TokenMismatch,
260
branch.lock_write, token=different_token)
261
# A seperate instance for the same lockable will also raise
263
# This detects the case where a caller claims to have a lock (via
264
# the token) for an external resource, but doesn't (the token is
265
# different). Clients need a seperate lock object to make sure the
266
# external resource is probed, whereas the existing lock object
249
branch_token, repo_token = tokens
250
different_branch_token = branch_token + 'xxx'
251
different_repo_token = repo_token + 'xxx'
252
# Re-using the same lockable instance with a different branch token
253
# will raise TokenMismatch.
254
self.assertRaises(errors.TokenMismatch,
256
tokens=(different_branch_token, repo_token))
257
# Similarly for a different repository token.
258
self.assertRaises(errors.TokenMismatch,
260
tokens=(branch_token, different_repo_token))
264
def test_lock_write_with_nonmatching_token(self):
265
branch = self.make_branch('b')
266
tokens = branch.lock_write()
269
# This test does not apply, because this branch refuses
272
branch_token, repo_token = tokens
273
different_branch_token = branch_token + 'xxx'
274
different_repo_token = repo_token + 'xxx'
268
276
new_branch = branch.bzrdir.open_branch()
269
277
# We only want to test the relocking abilities of branch, so use the
270
278
# existing repository object which is already locked.
271
279
new_branch.repository = branch.repository
272
280
self.assertRaises(errors.TokenMismatch,
273
new_branch.lock_write, token=different_token)
281
new_branch.lock_write,
282
tokens=(different_branch_token, repo_token))
283
self.assertRaises(errors.TokenMismatch,
284
new_branch.lock_write,
285
tokens=(branch_token, different_repo_token))
277
290
def test_lock_write_with_matching_token(self):
278
291
"""Test that a branch can be locked with a token, if it is already
279
292
locked by that token."""
280
293
branch = self.make_branch('b')
281
token = branch.lock_write()
294
tokens = branch.lock_write()
284
297
# This test does not apply, because this branch refuses tokens.
286
299
# The same instance will accept a second lock_write if the specified
288
branch.lock_write(token=token)
301
branch.lock_write(tokens=tokens)
290
303
# Calling lock_write on a new instance for the same lockable will
293
306
# We only want to test the relocking abilities of branch, so use the
294
307
# existing repository object which is already locked.
295
308
new_branch.repository = branch.repository
296
new_branch.lock_write(token=token)
309
new_branch.lock_write(tokens=tokens)
297
310
new_branch.unlock()
301
def test_unlock_after_lock_write_with_token(self):
314
def test_unlock_after_lock_write_with_tokens(self):
302
315
# If lock_write did not physically acquire the lock (because it was
303
# passed a token), then unlock should not physically release it.
316
# passed some tokens), then unlock should not physically release it.
304
317
branch = self.make_branch('b')
305
token = branch.lock_write()
318
tokens = branch.lock_write()
308
321
# This test does not apply, because this lockable refuses
312
325
# We only want to test the relocking abilities of branch, so use the
313
326
# existing repository object which is already locked.
314
327
new_branch.repository = branch.repository
315
new_branch.lock_write(token=token)
328
new_branch.lock_write(tokens=tokens)
316
329
new_branch.unlock()
317
330
self.assertTrue(branch.get_physical_lock_status()) #XXX
321
def test_lock_write_with_token_fails_when_unlocked(self):
322
# Lock and unlock to get a superficially valid token. This mimics a
334
def test_lock_write_with_tokens_fails_when_unlocked(self):
335
# Lock and unlock to get superficially valid tokens. This mimics a
323
336
# likely programming error, where a caller accidentally tries to lock
324
# with a token that is no longer valid (because the original lock was
337
# with tokens that are no longer valid (because the original lock was
326
339
branch = self.make_branch('b')
327
token = branch.lock_write()
340
tokens = branch.lock_write()
330
343
# This test does not apply, because this lockable refuses
334
347
self.assertRaises(errors.TokenMismatch,
335
branch.lock_write, token=token)
348
branch.lock_write, tokens=tokens)
337
def test_lock_write_reenter_with_token(self):
350
def test_lock_write_reenter_with_tokens(self):
338
351
branch = self.make_branch('b')
339
token = branch.lock_write()
352
tokens = branch.lock_write()
342
355
# This test does not apply, because this lockable refuses
345
358
# Relock with a token.
346
branch.lock_write(token=token)
359
branch.lock_write(tokens=tokens)
354
367
new_branch.lock_write()
355
368
new_branch.unlock()
370
def test_leave_lock_in_place(self):
371
branch = self.make_branch('b')
372
# Lock the branch, then use leave_lock_in_place so that when we
373
# unlock the branch the lock is still held on disk.
374
tokens = branch.lock_write()
377
# This test does not apply, because this repository refuses lock
379
self.assertRaises(NotImplementedError, branch.leave_lock_in_place)
381
branch.leave_lock_in_place()
384
# We should be unable to relock the repo.
385
self.assertRaises(errors.LockContention, branch.lock_write)
387
def test_dont_leave_lock_in_place(self):
388
branch = self.make_branch('b')
389
# Create a lock on disk.
390
tokens = branch.lock_write()
393
# This test does not apply, because this branch refuses lock
395
self.assertRaises(NotImplementedError,
396
branch.dont_leave_lock_in_place)
399
branch.leave_lock_in_place()
400
except NotImplementedError:
401
# This branch doesn't support this API.
403
branch.repository.leave_lock_in_place()
406
# Reacquire the lock (with a different branch object) by using the
408
new_branch = branch.bzrdir.open_branch()
409
new_branch.lock_write(tokens=tokens)
410
# Call dont_leave_lock_in_place, so that the lock will be released by
411
# this instance, even though the lock wasn't originally acquired by it.
412
new_branch.dont_leave_lock_in_place()
413
new_branch.repository.dont_leave_lock_in_place()
415
# Now the branch is unlocked. Test this by locking it (without tokens).