test lock contention

This commit is contained in:
Brad Warren 2017-03-17 12:16:34 -07:00
parent dc85f0c45f
commit 00a0e70fe6

View file

@ -4,6 +4,7 @@ from __future__ import print_function
import itertools
import mock
import multiprocessing
import os
import shutil
import tempfile
@ -1311,12 +1312,51 @@ class TestHandleException(unittest.TestCase):
class TestAcquireFileLock(unittest.TestCase):
"""Test main.acquire_file_lock."""
def setUp(self):
self.tempdir = tempfile.mkdtemp()
self.lock_path = os.path.join(self.tempdir, 'certbot.lock')
def tearDown(self):
shutil.rmtree(self.tempdir)
@mock.patch('certbot.main.logger')
def test_bad_path(self, mock_logger):
lock = main.acquire_file_lock(os.getcwd())
self.assertTrue(mock_logger.warning.called)
self.assertFalse(lock.acquired)
def test_held_lock(self):
# start child and wait for it to grab the lock
cv = multiprocessing.Condition()
cv.acquire()
child_args = (cv, self.lock_path,)
child = multiprocessing.Process(target=_hold_lock, args=child_args)
child.start()
cv.wait()
# assert we can't grab lock and terminate the child
self.assertRaises(errors.Error, main.acquire_file_lock, self.lock_path)
cv.notify()
cv.release()
child.join()
self.assertEqual(child.exitcode, 0)
def _hold_lock(cv, lock_path):
"""Acquire a file lock at lock_path and wait to release it.
:param multiprocessing.Condition cv: condition for syncronization
:param str lock_path: path to the file lock
"""
import fasteners
lock = fasteners.InterProcessLock(lock_path)
lock.acquire()
cv.acquire()
cv.notify()
cv.wait()
lock.release()
if __name__ == '__main__':
unittest.main() # pragma: no cover