Add a DatabasePoisonFixture

This is the beginning of a poison fixture for tests that don't use
the database. If they do, we interrupt them deep in oslo_db, log a
warning, and return a MagicMock. This keeps them from breaking
global database state, but doesn't actually poison them. This should
be followed-up with a patch to raise an exception, and fix the rest
of the tests that depend on the broken behavior.

Since some tests claim to not be DB test, but use the fixture
themselves anyway, this adds a USES_DB_SELF flag to help gate
the application of the poison.

Change-Id: If071a12a33aad86e918a9f441a246a930e921c8d
This commit is contained in:
Dan Smith
2016-03-22 11:52:47 -07:00
parent 1feab84233
commit 1906aa4214
9 changed files with 33 additions and 0 deletions

View File

@@ -170,6 +170,7 @@ class TestCase(testtools.TestCase):
`NoDBTestCase` first.
"""
USES_DB = True
USES_DB_SELF = False
REQUIRES_LOCKING = False
TIMEOUT_SCALING_FACTOR = 1
@@ -213,6 +214,8 @@ class TestCase(testtools.TestCase):
if self.USES_DB:
self.useFixture(nova_fixtures.Database())
self.useFixture(nova_fixtures.Database(database='api'))
elif not self.USES_DB_SELF:
self.useFixture(nova_fixtures.DatabasePoisonFixture())
# NOTE(blk-u): WarningsFixture must be after the Database fixture
# because sqlalchemy-migrate messes with the warnings filters.

View File

@@ -22,6 +22,7 @@ import os
import warnings
import fixtures
import mock
from oslo_config import cfg
from oslo_db.sqlalchemy import enginefacade
from oslo_messaging import conffixture as messaging_conffixture
@@ -196,6 +197,22 @@ class Timeout(fixtures.Fixture):
self.useFixture(fixtures.Timeout(self.test_timeout, gentle=True))
class DatabasePoisonFixture(fixtures.Fixture):
def setUp(self):
super(DatabasePoisonFixture, self).setUp()
self.useFixture(fixtures.MonkeyPatch(
'oslo_db.sqlalchemy.enginefacade._TransactionFactory.'
'_create_session',
self._poison_configure))
def _poison_configure(self, *a, **k):
warnings.warn('This test uses methods that set internal oslo_db '
'state, but it does not claim to use the database. '
'This will conflict with the setup of tests that '
'do use the database and cause failures later.')
return mock.MagicMock()
class Database(fixtures.Fixture):
def __init__(self, database='main', connection=None):
"""Create a database fixture.

View File

@@ -24,6 +24,8 @@ from nova.tests.unit import fake_request_spec
class BuildRequestTestCase(test.NoDBTestCase):
USES_DB_SELF = True
def setUp(self):
super(BuildRequestTestCase, self).setUp()
# NOTE: This means that we're using a database for this test suite

View File

@@ -20,6 +20,8 @@ from nova.tests import fixtures
class CellMappingTestCase(test.NoDBTestCase):
USES_DB_SELF = True
def setUp(self):
super(CellMappingTestCase, self).setUp()
self.useFixture(fixtures.Database(database='api'))

View File

@@ -22,6 +22,7 @@ from nova.tests import fixtures
class ConnectionSwitchTestCase(test.NoDBTestCase):
USES_DB_SELF = True
test_filename = 'foo.db'
def setUp(self):

View File

@@ -57,6 +57,8 @@ def create_mapping_obj(context, **kwargs):
class HostMappingTestCase(test.NoDBTestCase):
USES_DB_SELF = True
def setUp(self):
super(HostMappingTestCase, self).setUp()
self.useFixture(fixtures.Database(database='api'))

View File

@@ -34,6 +34,8 @@ def create_mapping(**kwargs):
class InstanceMappingTestCase(test.NoDBTestCase):
USES_DB_SELF = True
def setUp(self):
super(InstanceMappingTestCase, self).setUp()
self.useFixture(fixtures.Database(database='api'))

View File

@@ -20,6 +20,8 @@ from nova.tests.unit import fake_request_spec
class RequestSpecTestCase(test.NoDBTestCase):
USES_DB_SELF = True
def setUp(self):
super(RequestSpecTestCase, self).setUp()
self.useFixture(fixtures.Database(database='api'))

View File

@@ -31,6 +31,8 @@ DISK_INVENTORY = dict(
class ResourceProviderTestCase(test.NoDBTestCase):
"""Test resource-provider objects' lifecycles."""
USES_DB_SELF = True
def setUp(self):
super(ResourceProviderTestCase, self).setUp()
self.useFixture(fixtures.Database())