160
162
lf2 = LockDir(self.get_readonly_transport(), 'test_lock')
161
163
self.assertEqual(lf2.peek(), None)
162
164
lf1.attempt_lock()
165
self.addCleanup(lf1.unlock)
163
166
info2 = lf2.peek()
164
167
self.assertTrue(info2)
165
168
self.assertEqual(info2['nonce'], lf1.nonce)
167
170
def test_30_lock_wait_fail(self):
168
171
"""Wait on a lock, then fail
170
173
We ask to wait up to 400ms; this should fail within at most one
171
174
second. (Longer times are more realistic but we don't want the test
172
175
suite to take too long, and this should do for now.)
320
323
def test_35_wait_lock_changing(self):
321
324
"""LockDir.wait_lock() will report if the lock changes underneath.
323
326
This is the stages we want to happen:
325
328
0) Synchronization locks are created and locked.
326
329
1) Lock1 obtains the lockdir, and releases the 'check' lock.
327
330
2) Lock2 grabs the 'check' lock, and checks the lockdir.
328
It sees the lockdir is already acquired, reports the fact,
331
It sees the lockdir is already acquired, reports the fact,
329
332
and unsets the 'checked' lock.
330
333
3) Thread1 blocks on acquiring the 'checked' lock, and then tells
331
334
Lock1 to release and acquire the lockdir. This resets the 'check'
333
336
4) Lock2 acquires the 'check' lock, and checks again. It notices
334
that the holder of the lock has changed, and so reports a new
337
that the holder of the lock has changed, and so reports a new
336
339
5) Thread1 blocks on the 'checked' lock, this time, it completely
337
340
unlocks the lockdir, allowing Lock2 to acquire the lock.
654
663
# when held, that's all we see
655
664
ld1.attempt_lock()
665
self.addCleanup(ld1.unlock)
656
666
check_dir(['held'])
657
667
# second guy should fail
658
668
self.assertRaises(errors.LockContention, ld2.attempt_lock)
660
670
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)