Add external lock fixture
This was requested by consumers of the library so they don't have to enable external locks globally with the OSLO_LOCK_PATH env var, which can mask bugs in unit tests that have interdependencies because it makes every lock in any unit test shared. The new fixture allows a separate lock directory to be created for each test, and allows external locking to only be enabled for tests that need it. Change-Id: Iae7ce302e1a3a5ad90ca5310f5ac7a6164867637
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import fixtures
|
import fixtures
|
||||||
|
from oslo.config import fixture as config
|
||||||
|
|
||||||
from oslo_concurrency import lockutils
|
from oslo_concurrency import lockutils
|
||||||
|
|
||||||
@@ -49,3 +50,27 @@ class LockFixture(fixtures.Fixture):
|
|||||||
super(LockFixture, self).setUp()
|
super(LockFixture, self).setUp()
|
||||||
self.addCleanup(self.mgr.__exit__, None, None, None)
|
self.addCleanup(self.mgr.__exit__, None, None, None)
|
||||||
self.lock = self.mgr.__enter__()
|
self.lock = self.mgr.__enter__()
|
||||||
|
|
||||||
|
|
||||||
|
class ExternalLockFixture(fixtures.Fixture):
|
||||||
|
"""Configure lock_path so external locks can be used in unit tests.
|
||||||
|
|
||||||
|
Creates a temporary directory to hold file locks and sets the oslo.config
|
||||||
|
lock_path opt to use it. This can be used to enable external locking
|
||||||
|
on a per-test basis, rather than globally with the OSLO_LOCK_PATH
|
||||||
|
environment variable.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
def test_method(self):
|
||||||
|
self.useFixture(ExternalLockFixture())
|
||||||
|
something_that_needs_external_locks()
|
||||||
|
|
||||||
|
Alternatively, the useFixture call could be placed in a test class's
|
||||||
|
setUp method to provide this functionality to all tests in the class.
|
||||||
|
"""
|
||||||
|
def setUp(self):
|
||||||
|
super(ExternalLockFixture, self).setUp()
|
||||||
|
temp_dir = self.useFixture(fixtures.TempDir())
|
||||||
|
conf = self.useFixture(config.Config(lockutils.CONF)).config
|
||||||
|
conf(lock_path=temp_dir.path, group='oslo_concurrency')
|
||||||
|
@@ -549,3 +549,27 @@ class TestLockFixture(test_base.BaseTestCase):
|
|||||||
fixture = fixtures.LockFixture('test-lock')
|
fixture = fixtures.LockFixture('test-lock')
|
||||||
self.useFixture(fixture)
|
self.useFixture(fixture)
|
||||||
self.lock = fixture.lock
|
self.lock = fixture.lock
|
||||||
|
|
||||||
|
|
||||||
|
class TestExternalLockFixture(test_base.BaseTestCase):
|
||||||
|
def test_fixture(self):
|
||||||
|
# NOTE(bnemec): This test case is only valid if lockutils-wrapper is
|
||||||
|
# _not_ in use. Otherwise lock_path will be set on lockutils import
|
||||||
|
# and this test will pass regardless of whether the fixture is used.
|
||||||
|
self.useFixture(fixtures.ExternalLockFixture())
|
||||||
|
# This will raise an exception if lock_path is not set
|
||||||
|
with lockutils.external_lock('foo'):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_with_existing_config_fixture(self):
|
||||||
|
# Make sure the config fixture in the ExternalLockFixture doesn't
|
||||||
|
# cause any issues for tests using their own config fixture.
|
||||||
|
conf = self.useFixture(config.Config())
|
||||||
|
self.useFixture(fixtures.ExternalLockFixture())
|
||||||
|
with lockutils.external_lock('bar'):
|
||||||
|
conf.register_opt(cfg.StrOpt('foo'))
|
||||||
|
conf.config(foo='bar')
|
||||||
|
self.assertEqual(cfg.CONF.foo, 'bar')
|
||||||
|
# Due to config filter, lock_path should still not be present in
|
||||||
|
# the global config opt.
|
||||||
|
self.assertFalse(hasattr(cfg.CONF, 'lock_path'))
|
||||||
|
Reference in New Issue
Block a user