def test_50_lockdir_representation(self): """Check the on-disk representation of LockDirs is as expected. There should always be a top-level directory named by the lock. When the lock is held, there should be a lockname/held directory containing an info file. """ t = self.get_transport() lf1 = LockDir(t, 'test_lock') lf1.create() self.assertTrue(t.has('test_lock')) lf1.lock_write() self.assertTrue(t.has('test_lock/held/info')) lf1.unlock() self.assertFalse(t.has('test_lock/held/info'))
def test_34_lock_write_waits(self): """LockDir.lock_write() will wait for the lock.""" # the test suite sets the default to 0 to make deadlocks fail fast. # change it for this test, as we want to try a manual deadlock. raise tests.TestSkipped('Timing-sensitive test') bzrlib.lockdir._DEFAULT_TIMEOUT_SECONDS = 300 t = self.get_transport() lf1 = LockDir(t, 'test_lock') lf1.create() lf1.attempt_lock() def wait_and_unlock(): time.sleep(0.1) lf1.unlock() unlocker = Thread(target=wait_and_unlock) unlocker.start() try: lf2 = LockDir(t, 'test_lock') self.setup_log_reporter(lf2) before = time.time() # wait and then lock lf2.lock_write() after = time.time() finally: unlocker.join() # There should be only 1 report, even though it should have to # wait for a while lock_base = lf2.transport.abspath(lf2.path) self.assertEqual(1, len(self._logged_reports)) self.assertEqual( '%s %s\n' '%s\n%s\n' 'Will continue to try until %s\n', self._logged_reports[0][0]) args = self._logged_reports[0][1] self.assertEqual('Unable to obtain', args[0]) self.assertEqual('lock %s' % (lock_base, ), args[1]) self.assertStartsWith(args[2], 'held by ') self.assertStartsWith(args[3], 'locked ') self.assertEndsWith(args[3], ' ago') self.assertContainsRe(args[4], r'\d\d:\d\d:\d\d')
def test_34_lock_write_waits(self): """LockDir.lock_write() will wait for the lock.""" # the test suite sets the default to 0 to make deadlocks fail fast. # change it for this test, as we want to try a manual deadlock. raise tests.TestSkipped('Timing-sensitive test') bzrlib.lockdir._DEFAULT_TIMEOUT_SECONDS = 300 t = self.get_transport() lf1 = LockDir(t, 'test_lock') lf1.create() lf1.attempt_lock() def wait_and_unlock(): time.sleep(0.1) lf1.unlock() unlocker = Thread(target=wait_and_unlock) unlocker.start() try: lf2 = LockDir(t, 'test_lock') self.setup_log_reporter(lf2) before = time.time() # wait and then lock lf2.lock_write() after = time.time() finally: unlocker.join() # There should be only 1 report, even though it should have to # wait for a while lock_base = lf2.transport.abspath(lf2.path) self.assertEqual(1, len(self._logged_reports)) self.assertEqual('%s %s\n' '%s\n%s\n' 'Will continue to try until %s\n', self._logged_reports[0][0]) args = self._logged_reports[0][1] self.assertEqual('Unable to obtain', args[0]) self.assertEqual('lock %s' % (lock_base,), args[1]) self.assertStartsWith(args[2], 'held by ') self.assertStartsWith(args[3], 'locked ') self.assertEndsWith(args[3], ' ago') self.assertContainsRe(args[4], r'\d\d:\d\d:\d\d')
def test_create_missing_base_directory(self): """If LockDir.path doesn't exist, it can be created Some people manually remove the entire lock/ directory trying to unlock a stuck repository/branch/etc. Rather than failing after that, just create the lock directory when needed. """ t = self.get_transport() lf1 = LockDir(t, 'test_lock') lf1.create() self.assertTrue(t.has('test_lock')) t.rmdir('test_lock') self.assertFalse(t.has('test_lock')) # This will create 'test_lock' if it needs to lf1.lock_write() self.assertTrue(t.has('test_lock')) self.assertTrue(t.has('test_lock/held/info')) lf1.unlock() self.assertFalse(t.has('test_lock/held/info'))