162
160
lf2 = LockDir(self.get_readonly_transport(), 'test_lock')
163
161
self.assertEqual(lf2.peek(), None)
164
162
lf1.attempt_lock()
165
self.addCleanup(lf1.unlock)
166
163
info2 = lf2.peek()
167
164
self.assertTrue(info2)
168
165
self.assertEqual(info2['nonce'], lf1.nonce)
170
167
def test_30_lock_wait_fail(self):
171
168
"""Wait on a lock, then fail
173
170
We ask to wait up to 400ms; this should fail within at most one
174
171
second. (Longer times are more realistic but we don't want the test
175
172
suite to take too long, and this should do for now.)
323
320
def test_35_wait_lock_changing(self):
324
321
"""LockDir.wait_lock() will report if the lock changes underneath.
326
323
This is the stages we want to happen:
328
325
0) Synchronization locks are created and locked.
329
326
1) Lock1 obtains the lockdir, and releases the 'check' lock.
330
327
2) Lock2 grabs the 'check' lock, and checks the lockdir.
331
It sees the lockdir is already acquired, reports the fact,
328
It sees the lockdir is already acquired, reports the fact,
332
329
and unsets the 'checked' lock.
333
330
3) Thread1 blocks on acquiring the 'checked' lock, and then tells
334
331
Lock1 to release and acquire the lockdir. This resets the 'check'
336
333
4) Lock2 acquires the 'check' lock, and checks again. It notices
337
that the holder of the lock has changed, and so reports a new
334
that the holder of the lock has changed, and so reports a new
339
336
5) Thread1 blocks on the 'checked' lock, this time, it completely
340
337
unlocks the lockdir, allowing Lock2 to acquire the lock.
663
654
# when held, that's all we see
664
655
ld1.attempt_lock()
665
self.addCleanup(ld1.unlock)
666
656
check_dir(['held'])
667
657
# second guy should fail
668
658
self.assertRaises(errors.LockContention, ld2.attempt_lock)
670
660
check_dir(['held'])
673
class TestLockDirHooks(TestCaseWithTransport):
676
super(TestLockDirHooks, self).setUp()
680
return LockDir(self.get_transport(), 'test_lock')
682
def record_hook(self, result):
683
self._calls.append(result)
685
def test_LockDir_acquired_success(self):
686
# the LockDir.lock_acquired hook fires when a lock is acquired.
687
LockDir.hooks.install_named_hook('lock_acquired',
688
self.record_hook, 'record_hook')
691
self.assertEqual([], self._calls)
692
result = ld.attempt_lock()
693
lock_path = ld.transport.abspath(ld.path)
694
self.assertEqual([lock.LockResult(lock_path, result)], self._calls)
696
self.assertEqual([lock.LockResult(lock_path, result)], self._calls)
698
def test_LockDir_acquired_fail(self):
699
# the LockDir.lock_acquired hook does not fire on failure.
702
ld2 = self.get_lock()
704
# install a lock hook now, when the disk lock is locked
705
LockDir.hooks.install_named_hook('lock_acquired',
706
self.record_hook, 'record_hook')
707
self.assertRaises(errors.LockContention, ld.attempt_lock)
708
self.assertEqual([], self._calls)
710
self.assertEqual([], self._calls)
712
def test_LockDir_released_success(self):
713
# the LockDir.lock_released hook fires when a lock is acquired.
714
LockDir.hooks.install_named_hook('lock_released',
715
self.record_hook, 'record_hook')
718
self.assertEqual([], self._calls)
719
result = ld.attempt_lock()
720
self.assertEqual([], self._calls)
722
lock_path = ld.transport.abspath(ld.path)
723
self.assertEqual([lock.LockResult(lock_path, result)], self._calls)
725
def test_LockDir_released_fail(self):
726
# the LockDir.lock_released hook does not fire on failure.
729
ld2 = self.get_lock()
731
ld2.force_break(ld2.peek())
732
LockDir.hooks.install_named_hook('lock_released',
733
self.record_hook, 'record_hook')
734
self.assertRaises(LockBroken, ld.unlock)
735
self.assertEqual([], self._calls)
737
def test_LockDir_broken_success(self):
738
# the LockDir.lock_broken hook fires when a lock is broken.
741
ld2 = self.get_lock()
742
result = ld.attempt_lock()
743
LockDir.hooks.install_named_hook('lock_broken',
744
self.record_hook, 'record_hook')
745
ld2.force_break(ld2.peek())
746
lock_path = ld.transport.abspath(ld.path)
747
self.assertEqual([lock.LockResult(lock_path, result)], self._calls)
749
def test_LockDir_broken_failure(self):
750
# the LockDir.lock_broken hook does not fires when a lock is already
754
ld2 = self.get_lock()
755
result = ld.attempt_lock()
756
holder_info = ld2.peek()
758
LockDir.hooks.install_named_hook('lock_broken',
759
self.record_hook, 'record_hook')
760
ld2.force_break(holder_info)
761
lock_path = ld.transport.abspath(ld.path)
762
self.assertEqual([], self._calls)