def test_lock_local_storage(self): # 1. Acquire succeeds lock = LockLocalStorage("/tmp/a") with lock: self.assertTrue(True) # 2. Acquire fails because lock is already acquired lock = LockLocalStorage("/tmp/b", timeout=0.5) with lock: expected_msg = "Failed to acquire thread lock" self.assertRaisesRegex(LibcloudError, expected_msg, lock.__enter__) # 3. Multiprocessing scenario where IPC lock is involved def acquire_lock_in_subprocess(pid, success): # For first process acquire should succeed and for the second it should fail lock = LockLocalStorage("/tmp/c", timeout=0.5) if pid == 1: with lock: # We use longer sleep when running tests in parallel to avoid # failures related to slower process spawn time.sleep(2.5) success.value = 1 elif pid == 2: expected_msg = "Failed to acquire IPC lock" self.assertRaisesRegex(LibcloudError, expected_msg, lock.__enter__) success.value = 1 else: raise ValueError("Invalid pid") success_1 = multiprocessing.Value('i', 0) success_2 = multiprocessing.Value('i', 0) p1 = multiprocessing.Process(target=acquire_lock_in_subprocess, args=( 1, success_1, )) p1.start() time.sleep(0.2) p2 = multiprocessing.Process(target=acquire_lock_in_subprocess, args=( 2, success_2, )) p2.start() p1.join() p2.join() self.assertEqual(bool(success_1.value), True, "Check didn't pass") self.assertEqual(bool(success_2.value), True, "Second check didn't pass")
def __call__(self, pid, success): # For first process acquire should succeed and for the second it should fail lock = LockLocalStorage("/tmp/c", timeout=0.5) if pid == 1: with lock: # We use longer sleep when running tests in parallel to avoid # failures related to slower process spawn time.sleep(2.5) success.value = 1 elif pid == 2: expected_msg = "Failed to acquire IPC lock" try: lock.__enter__() except LibcloudError as e: assert expected_msg in str(e) success.value = 1 else: raise ValueError("Invalid pid")
def test_lock_local_storage(self): # 1. Acquire succeeds lock = LockLocalStorage("/tmp/a") with lock: self.assertTrue(True) # 2. Acquire fails because lock is already acquired lock = LockLocalStorage("/tmp/b", timeout=0.5) with lock: expected_msg = "Failed to acquire thread lock" self.assertRaisesRegex(LibcloudError, expected_msg, lock.__enter__) success_1 = multiprocessing.Value("i", 0) success_2 = multiprocessing.Value("i", 0) p1 = multiprocessing.Process( target=PickleableAcquireLockInSubprocess(), args=( 1, success_1, ), ) p1.start() time.sleep(0.2) p2 = multiprocessing.Process( target=PickleableAcquireLockInSubprocess(), args=( 2, success_2, ), ) p2.start() p1.join() p2.join() self.assertEqual(bool(success_1.value), True, "Check didn't pass") self.assertEqual(bool(success_2.value), True, "Second check didn't pass")
def acquire_lock_in_subprocess(pid, success): # For first process acquire should succeed and for the second it should fail lock = LockLocalStorage("/tmp/c", timeout=0.5) if pid == 1: with lock: time.sleep(1) success.value = 1 elif pid == 2: expected_msg = "Failed to acquire IPC lock" self.assertRaisesRegex(LibcloudError, expected_msg, lock.__enter__) success.value = 1 else: raise ValueError("Invalid pid")
def acquire_lock_in_subprocess(pid, success): # For first process acquire should succeed and for the second it should fail lock = LockLocalStorage("/tmp/c", timeout=0.5) if pid == 1: with lock: # We use longer sleep when running tests in parallel to avoid # failures related to slower process spawn time.sleep(2.5) success.value = 1 elif pid == 2: expected_msg = "Failed to acquire IPC lock" self.assertRaisesRegex(LibcloudError, expected_msg, lock.__enter__) success.value = 1 else: raise ValueError("Invalid pid")
def test_proper_lockfile_imports(self): # LockLocalStorage was previously using an un-imported exception # in its __enter__ method, so the following would raise a NameError. lls = LockLocalStorage("blah") self.assertRaises(LibcloudError, lls.__enter__)