diff options
Diffstat (limited to 'nova/tests')
| -rw-r--r-- | nova/tests/test_misc.py | 16 | ||||
| -rw-r--r-- | nova/tests/test_utils.py | 39 |
2 files changed, 55 insertions, 0 deletions
diff --git a/nova/tests/test_misc.py b/nova/tests/test_misc.py index 0baf38236..63c2773bf 100644 --- a/nova/tests/test_misc.py +++ b/nova/tests/test_misc.py @@ -22,6 +22,7 @@ import select from eventlet import greenpool from eventlet import greenthread +import lockfile from nova import exception from nova import test @@ -134,6 +135,21 @@ class LockTestCase(test.TestCase): self.assertEqual(saved_sem_num, len(utils._semaphores), "Semaphore leak detected") + def test_nested_external_fails(self): + """We can not nest external syncs""" + + @utils.synchronized('testlock1', external=True) + def outer_lock(): + + @utils.synchronized('testlock2', external=True) + def inner_lock(): + pass + inner_lock() + try: + self.assertRaises(lockfile.NotMyLock, outer_lock) + finally: + utils.cleanup_file_locks() + def test_synchronized_externally(self): """We can lock across multiple processes""" rpipe1, wpipe1 = os.pipe() diff --git a/nova/tests/test_utils.py b/nova/tests/test_utils.py index f29da5466..501ff91d0 100644 --- a/nova/tests/test_utils.py +++ b/nova/tests/test_utils.py @@ -24,7 +24,10 @@ import shutil import StringIO import tempfile +import eventlet +from eventlet import greenpool import iso8601 +import lockfile import mox import nova @@ -832,6 +835,42 @@ class Iso8601TimeTest(test.TestCase): self._instaneous(normed, 2012, 2, 13, 23, 53, 07, 0) +class TestGreenLocks(test.TestCase): + def test_concurrent_green_lock_succeeds(self): + """Verify spawn_n greenthreads with two locks run concurrently. + + This succeeds with spawn but fails with spawn_n because lockfile + gets the same thread id for both spawn_n threads. Our workaround + of using the GreenLockFile will work even if the issue is fixed. + """ + self.completed = False + with utils.tempdir() as tmpdir: + + def locka(wait): + a = utils.GreenLockFile(os.path.join(tmpdir, 'a')) + a.acquire() + wait.wait() + a.release() + self.completed = True + + def lockb(wait): + b = utils.GreenLockFile(os.path.join(tmpdir, 'b')) + b.acquire() + wait.wait() + b.release() + + wait1 = eventlet.event.Event() + wait2 = eventlet.event.Event() + pool = greenpool.GreenPool() + pool.spawn_n(locka, wait1) + pool.spawn_n(lockb, wait2) + wait2.send() + eventlet.sleep(0) + wait1.send() + pool.waitall() + self.assertTrue(self.completed) + + class TestLockCleanup(test.TestCase): """unit tests for utils.cleanup_file_locks()""" |
