135
138
except LockContention as e:
136
139
self.assertEqual(e.lock, lf2)
137
140
self.assertContainsRe(str(e),
138
r'^Could not acquire.*test_lock.*$')
141
r'^Could not acquire.*test_lock.*$')
141
144
def test_20_lock_peek(self):
148
151
# lock is held, should get some info on it
149
152
info1 = lf1.peek()
150
153
self.assertEqual(set(info1.info_dict.keys()),
151
{'user', 'nonce', 'hostname', 'pid', 'start_time'})
154
{'user', 'nonce', 'hostname', 'pid', 'start_time'})
152
155
# should get the same info if we look at it through a different
154
157
info2 = LockDir(t, 'test_lock').peek()
190
193
# it should only take about 0.4 seconds, but we allow more time in
191
194
# case the machine is heavily loaded
192
195
self.assertTrue(after - before <= 8.0,
193
"took %f seconds to detect lock contention" % (after - before))
196
"took %f seconds to detect lock contention" % (after - before))
196
199
self.assertEqual(1, len(self._logged_reports))
197
200
self.assertContainsRe(self._logged_reports[0][0],
198
r'Unable to obtain lock .* held by jrandom@example\.com on .*'
199
r' \(process #\d+\), acquired .* ago\.\n'
200
r'Will continue to try until \d{2}:\d{2}:\d{2}, unless '
201
r'you press Ctrl-C.\n'
202
r'See "brz help break-lock" for more.')
201
r'Unable to obtain lock .* held by jrandom@example\.com on .*'
202
r' \(process #\d+\), acquired .* ago\.\n'
203
r'Will continue to try until \d{2}:\d{2}:\d{2}, unless '
204
r'you press Ctrl-C.\n'
205
r'See "brz help break-lock" for more.')
204
207
def test_31_lock_wait_easy(self):
205
208
"""Succeed when waiting on a lock with no contention.
666
669
def test_unicode(self):
667
670
info = LockHeldInfo.for_this_process(None)
668
self.assertContainsRe(str(info),
669
r'held by .* on .* \(process #\d+\), acquired .* ago')
671
self.assertContainsRe(text_type(info),
672
r'held by .* on .* \(process #\d+\), acquired .* ago')
671
674
def test_is_locked_by_this_process(self):
672
675
info = LockHeldInfo.for_this_process(None)
685
688
def test_lock_holder_dead_process(self):
686
689
"""Detect that the holder (this process) is still running."""
687
690
self.overrideAttr(lockdir, 'get_host_name',
688
lambda: 'aproperhostname')
691
lambda: 'aproperhostname')
689
692
info = LockHeldInfo.for_this_process(None)
690
693
info.info_dict['pid'] = '123123123'
691
694
self.assertTrue(info.is_lock_holder_known_dead())
715
718
self.overrideAttr(lockdir, 'get_host_name',
717
720
info = LockHeldInfo.for_this_process(None)
718
721
info.info_dict['pid'] = '123123123'
719
722
self.assertFalse(info.is_lock_holder_known_dead())
731
734
This generates a warning but no other user interaction.
733
736
self.overrideAttr(lockdir, 'get_host_name',
734
lambda: 'aproperhostname')
735
# Stealing dead locks is enabled by default.
737
lambda: 'aproperhostname')
738
# This is off by default at present; see the discussion in the bug.
739
# If you change the default, don't forget to update the docs.
740
config.GlobalStack().set('locks.steal_dead', True)
736
741
# Create a lock pretending to come from a different nonexistent
737
742
# process on the same machine.
738
743
l1 = LockDir(self.get_transport(), 'a',
739
extra_holder_info={'pid': '12312313'})
744
extra_holder_info={'pid': '12312313'})
740
745
token_1 = l1.attempt_lock()
741
746
l2 = LockDir(self.get_transport(), 'a')
742
747
token_2 = l2.attempt_lock()
743
748
# l1 will notice its lock was stolen.
744
749
self.assertRaises(errors.LockBroken,
748
753
def test_auto_break_stale_lock_configured_off(self):
749
754
"""Automatic breaking can be turned off"""
750
755
l1 = LockDir(self.get_transport(), 'a',
751
extra_holder_info={'pid': '12312313'})
752
# Stealing dead locks is enabled by default, so disable it.
753
config.GlobalStack().set('locks.steal_dead', False)
756
extra_holder_info={'pid': '12312313'})
754
757
token_1 = l1.attempt_lock()
755
758
self.addCleanup(l1.unlock)
756
759
l2 = LockDir(self.get_transport(), 'a')
757
# This fails now, because dead lock breaking is disabled.
760
# This fails now, because dead lock breaking is off by default.
758
761
self.assertRaises(LockContention,
760
763
# and it's in fact not broken