565
565
bzrlib.ui.ui_factory = orig_factory
567
def test_break_lock_corrupt_info(self):
568
"""break_lock works even if the info file is corrupt (and tells the UI
572
ld2 = self.get_lock()
575
ld.transport.put_bytes_non_atomic('test_lock/held/info', '\0')
576
class LoggingUIFactory(bzrlib.ui.SilentUIFactory):
579
def get_boolean(self, prompt):
580
self.prompts.append(('boolean', prompt))
582
ui = LoggingUIFactory()
583
orig_factory = bzrlib.ui.ui_factory
584
bzrlib.ui.ui_factory = ui
587
self.assertLength(1, ui.prompts)
588
self.assertEqual('boolean', ui.prompts[0][0])
589
self.assertStartsWith(ui.prompts[0][1], 'Break (corrupt LockDir')
590
self.assertRaises(LockBroken, ld.unlock)
592
bzrlib.ui.ui_factory = orig_factory
594
def test_break_lock_missing_info(self):
595
"""break_lock works even if the info file is missing (and tells the UI
599
ld2 = self.get_lock()
602
ld.transport.delete('test_lock/held/info')
603
class LoggingUIFactory(bzrlib.ui.SilentUIFactory):
606
def get_boolean(self, prompt):
607
self.prompts.append(('boolean', prompt))
609
ui = LoggingUIFactory()
610
orig_factory = bzrlib.ui.ui_factory
611
bzrlib.ui.ui_factory = ui
614
self.assertRaises(LockBroken, ld.unlock)
615
self.assertLength(0, ui.prompts)
617
bzrlib.ui.ui_factory = orig_factory
618
# Suppress warnings due to ld not being unlocked
619
# XXX: if lock_broken hook was invoked in this case, this hack would
620
# not be necessary. - Andrew Bennetts, 2010-09-06.
621
del self._lock_actions[:]
567
623
def test_create_missing_base_directory(self):
568
624
"""If LockDir.path doesn't exist, it can be created
681
737
['<unknown>', '<unknown>', '<unknown>', '(unknown)'],
740
def test_corrupt_lockdir_info(self):
741
"""We can cope with corrupt (and thus unparseable) info files."""
742
# This seems like a fairly common failure case too - see
743
# <https://bugs.edge.launchpad.net/bzr/+bug/619872> for instance.
744
# In particular some systems tend to fill recently created files with
745
# nul bytes after recovering from a system crash.
746
t = self.get_transport()
748
t.mkdir('test_lock/held')
749
t.put_bytes('test_lock/held/info', '\0')
750
lf = LockDir(t, 'test_lock')
751
self.assertRaises(errors.LockCorrupt, lf.peek)
752
# Currently attempt_lock gives LockContention, but LockCorrupt would be
753
# a reasonable result too.
755
(errors.LockCorrupt, errors.LockContention), lf.attempt_lock)
756
self.assertRaises(errors.LockCorrupt, lf.validate_token, 'fake token')
758
def test_missing_lockdir_info(self):
759
"""We can cope with absent info files."""
760
t = self.get_transport()
762
t.mkdir('test_lock/held')
763
lf = LockDir(t, 'test_lock')
764
# In this case we expect the 'not held' result from peek, because peek
765
# cannot be expected to notice that there is a 'held' directory with no
767
self.assertEqual(None, lf.peek())
768
# And lock/unlock may work or give LockContention (but not any other
772
except LockContention:
773
# LockContention is ok, and expected on Windows
776
# no error is ok, and expected on POSIX (because POSIX allows
777
# os.rename over an empty directory).
779
# Currently raises TokenMismatch, but LockCorrupt would be reasonable
782
(errors.TokenMismatch, errors.LockCorrupt),
783
lf.validate_token, 'fake token')
685
786
class TestLockDirHooks(TestCaseWithTransport):