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