simplify database fixture to the features we use
The Database fixture has existed for a long time, and has a large amount of vestigial code that is no longer usable as it's masked by other test setup. For instance, the conf fixture always sets the db connection string to in memory db. Simplify what the Database fixture is doing to just the inmemory schema caching and reconstruction. Also provide a test case demonstrating that this both sets up the db correctly, as well as resets it after we've made changes. Change-Id: Idc9b587c705c1c1ab4e1173ad1e8e244037284d7
This commit is contained in:
60
nova/test.py
60
nova/test.py
@@ -28,7 +28,6 @@ import copy
|
||||
import inspect
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
|
||||
import fixtures
|
||||
from oslo.config import cfg
|
||||
@@ -43,14 +42,11 @@ import testtools
|
||||
from nova.api.openstack import wsgi
|
||||
from nova import context
|
||||
from nova import db
|
||||
from nova.db import migration
|
||||
from nova.db.sqlalchemy import api as session
|
||||
from nova.network import manager as network_manager
|
||||
from nova import objects
|
||||
from nova.objects import base as objects_base
|
||||
from nova.openstack.common.fixture import logging as log_fixture
|
||||
from nova.openstack.common import log as nova_logging
|
||||
from nova import paths
|
||||
from nova import rpc
|
||||
from nova.tests import fixtures as nova_fixtures
|
||||
from nova.tests.unit import conf_fixture
|
||||
@@ -58,14 +54,7 @@ from nova.tests.unit import policy_fixture
|
||||
from nova import utils
|
||||
|
||||
|
||||
test_opts = [
|
||||
cfg.StrOpt('sqlite_clean_db',
|
||||
default='clean.sqlite',
|
||||
help='File name of clean sqlite db'),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(test_opts)
|
||||
CONF.import_opt('enabled', 'nova.api.openstack', group='osapi_v3')
|
||||
CONF.set_override('use_stderr', False)
|
||||
|
||||
@@ -76,49 +65,9 @@ nova_logging.setup('nova')
|
||||
# tests that run at import time.
|
||||
objects.register_all()
|
||||
|
||||
_DB_CACHE = None
|
||||
_TRUE_VALUES = ('True', 'true', '1', 'yes')
|
||||
|
||||
|
||||
class Database(fixtures.Fixture):
|
||||
|
||||
def __init__(self, db_session, db_migrate, sql_connection,
|
||||
sqlite_db, sqlite_clean_db):
|
||||
self.sql_connection = sql_connection
|
||||
self.sqlite_db = sqlite_db
|
||||
self.sqlite_clean_db = sqlite_clean_db
|
||||
|
||||
self.engine = db_session.get_engine()
|
||||
self.engine.dispose()
|
||||
conn = self.engine.connect()
|
||||
if sql_connection == "sqlite://":
|
||||
if db_migrate.db_version() > db_migrate.db_initial_version():
|
||||
return
|
||||
else:
|
||||
testdb = paths.state_path_rel(sqlite_db)
|
||||
if os.path.exists(testdb):
|
||||
return
|
||||
db_migrate.db_sync()
|
||||
if sql_connection == "sqlite://":
|
||||
conn = self.engine.connect()
|
||||
self._DB = "".join(line for line in conn.connection.iterdump())
|
||||
self.engine.dispose()
|
||||
else:
|
||||
cleandb = paths.state_path_rel(sqlite_clean_db)
|
||||
shutil.copyfile(testdb, cleandb)
|
||||
|
||||
def setUp(self):
|
||||
super(Database, self).setUp()
|
||||
|
||||
if self.sql_connection == "sqlite://":
|
||||
conn = self.engine.connect()
|
||||
conn.connection.executescript(self._DB)
|
||||
self.addCleanup(self.engine.dispose)
|
||||
else:
|
||||
shutil.copyfile(paths.state_path_rel(self.sqlite_clean_db),
|
||||
paths.state_path_rel(self.sqlite_db))
|
||||
|
||||
|
||||
class SampleNetworks(fixtures.Fixture):
|
||||
|
||||
"""Create sample networks in the database."""
|
||||
@@ -266,14 +215,7 @@ class TestCase(testtools.TestCase):
|
||||
rpc.init(CONF)
|
||||
|
||||
if self.USES_DB:
|
||||
global _DB_CACHE
|
||||
if not _DB_CACHE:
|
||||
_DB_CACHE = Database(session, migration,
|
||||
sql_connection=CONF.database.connection,
|
||||
sqlite_db=CONF.database.sqlite_db,
|
||||
sqlite_clean_db=CONF.sqlite_clean_db)
|
||||
|
||||
self.useFixture(_DB_CACHE)
|
||||
self.useFixture(nova_fixtures.Database())
|
||||
|
||||
# NOTE(danms): Make sure to reset us back to non-remote objects
|
||||
# for each test to avoid interactions. Also, backup the object
|
||||
|
||||
@@ -23,11 +23,17 @@ import os
|
||||
import uuid
|
||||
|
||||
import fixtures
|
||||
from oslo.config import cfg
|
||||
|
||||
from nova.db import migration
|
||||
from nova.db.sqlalchemy import api as session
|
||||
from nova import service
|
||||
|
||||
_TRUE_VALUES = ('True', 'true', '1', 'yes')
|
||||
|
||||
CONF = cfg.CONF
|
||||
DB_SCHEMA = ""
|
||||
|
||||
|
||||
class ServiceFixture(fixtures.Fixture):
|
||||
"""Run a service as a test fixture."""
|
||||
@@ -189,3 +195,25 @@ class Timeout(fixtures.Fixture):
|
||||
super(Timeout, self).setUp()
|
||||
if self.test_timeout > 0:
|
||||
self.useFixture(fixtures.Timeout(self.test_timeout, gentle=True))
|
||||
|
||||
|
||||
class Database(fixtures.Fixture):
|
||||
def _cache_schema(self):
|
||||
global DB_SCHEMA
|
||||
if not DB_SCHEMA:
|
||||
engine = session.get_engine()
|
||||
conn = engine.connect()
|
||||
migration.db_sync()
|
||||
DB_SCHEMA = "".join(line for line in conn.connection.iterdump())
|
||||
engine.dispose()
|
||||
|
||||
def reset(self):
|
||||
self._cache_schema()
|
||||
engine = session.get_engine()
|
||||
engine.dispose()
|
||||
conn = engine.connect()
|
||||
conn.connection.executescript(DB_SCHEMA)
|
||||
|
||||
def setUp(self):
|
||||
super(Database, self).setUp()
|
||||
self.reset()
|
||||
|
||||
@@ -21,6 +21,7 @@ import fixtures as fx
|
||||
from oslo.config import cfg
|
||||
import testtools
|
||||
|
||||
from nova.db.sqlalchemy import api as session
|
||||
from nova.tests.unit import conf_fixture
|
||||
from nova.tests import fixtures
|
||||
|
||||
@@ -145,3 +146,36 @@ class TestTimeout(testtools.TestCase):
|
||||
self.assertEqual(timeout.test_timeout, 10)
|
||||
timeout = fixtures.Timeout("10", 2)
|
||||
self.assertEqual(timeout.test_timeout, 20)
|
||||
|
||||
|
||||
class TestDatabaseFixture(testtools.TestCase):
|
||||
def test_fixture_reset(self):
|
||||
# because this sets up reasonable db connection strings
|
||||
self.useFixture(conf_fixture.ConfFixture())
|
||||
self.useFixture(fixtures.Database())
|
||||
engine = session.get_engine()
|
||||
conn = engine.connect()
|
||||
result = conn.execute("select * from instance_types")
|
||||
rows = result.fetchall()
|
||||
self.assertEqual(len(rows), 5, "Rows %s" % rows)
|
||||
|
||||
# insert a 6th instance type, column 5 below is an int id
|
||||
# which has a constraint on it, so if new standard instance
|
||||
# types are added you have to bump it.
|
||||
conn.execute("insert into instance_types VALUES "
|
||||
"(NULL, NULL, NULL, 't1.test', 6, 4096, 2, 0, NULL, '87'"
|
||||
", 1.0, 40, 0, 0, 1, 0)")
|
||||
result = conn.execute("select * from instance_types")
|
||||
rows = result.fetchall()
|
||||
self.assertEqual(len(rows), 6, "Rows %s" % rows)
|
||||
|
||||
# reset by invoking the fixture again
|
||||
#
|
||||
# NOTE(sdague): it's important to reestablish the db
|
||||
# connection because otherwise we have a reference to the old
|
||||
# in mem db.
|
||||
self.useFixture(fixtures.Database())
|
||||
conn = engine.connect()
|
||||
result = conn.execute("select * from instance_types")
|
||||
rows = result.fetchall()
|
||||
self.assertEqual(len(rows), 5, "Rows %s" % rows)
|
||||
|
||||
Reference in New Issue
Block a user