summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2014-10-08 20:25:47 +0000
committerGerrit Code Review <review@openstack.org>2014-10-08 20:25:47 +0000
commit1b9c7cfa99d3eb825b5b11ee0f6fa795c589f134 (patch)
tree41d65c676cff91de75dc97472b311525ee6cb473
parent2dae1fd780198719f35d79e3b01db26cfc2ebf28 (diff)
parent489b1052ebca9f1a4306200d945c50360219aad7 (diff)
downloadoslo-concurrency-1b9c7cfa99d3eb825b5b11ee0f6fa795c589f134.tar.gz
Merge "Address race in file locking tests"
-rw-r--r--tests/unit/test_lockutils.py32
1 files changed, 30 insertions, 2 deletions
diff --git a/tests/unit/test_lockutils.py b/tests/unit/test_lockutils.py
index 29488db..188eef1 100644
--- a/tests/unit/test_lockutils.py
+++ b/tests/unit/test_lockutils.py
@@ -17,6 +17,7 @@ import fcntl
import multiprocessing
import os
import shutil
+import signal
import sys
import tempfile
import threading
@@ -393,12 +394,34 @@ class FileBasedLockingTestCase(test_base.BaseTestCase):
time.sleep(0)
lock1 = lockutils.InterProcessLock('foo')
lock1.lockfile = open(lock_file, 'w')
- self.assertRaises(IOError, lock1.trylock)
+ # NOTE(bnemec): There is a brief window between when the lock file
+ # is created and when it actually becomes locked. If we happen to
+ # context switch in that window we may succeed in locking the
+ # file. Keep retrying until we either get the expected exception
+ # or timeout waiting.
+ while time.time() - start < 5:
+ try:
+ lock1.trylock()
+ lock1.unlock()
+ time.sleep(0)
+ except IOError:
+ # This is what we expect to happen
+ break
+ else:
+ self.fail('Never caught expected lock exception')
+ # We don't need to wait for the full sleep in the child here
+ os.kill(pid, signal.SIGKILL)
else:
try:
lock2 = lockutils.InterProcessLock('foo')
lock2.lockfile = open(lock_file, 'w')
- lock2.trylock()
+ have_lock = False
+ while not have_lock:
+ try:
+ lock2.trylock()
+ have_lock = True
+ except IOError:
+ pass
finally:
# NOTE(bnemec): This is racy, but I don't want to add any
# synchronization primitives that might mask a problem
@@ -425,6 +448,11 @@ class FileBasedLockingTestCase(test_base.BaseTestCase):
thread = threading.Thread(target=other, args=('other',))
thread.start()
# Make sure the other thread grabs the lock
+ # NOTE(bnemec): File locks do not actually work between threads, so
+ # this test is verifying that the local semaphore is still enforcing
+ # external locks in that case. This means this test does not have
+ # the same race problem as the process test above because when the
+ # file is created the semaphore has already been grabbed.
start = time.time()
while not os.path.exists(os.path.join(self.lock_dir, 'foo')):
if time.time() - start > 5: