Moves test database setup/teardown into a fixture
Change-Id: Ic59eb0a6f7d20abfcc2966a7162406cf541306b2
This commit is contained in:
parent
58d71b9ac7
commit
01b0f4cd7d
@ -45,12 +45,10 @@ from keystone import auth
|
||||
from keystone.common import dependency
|
||||
from keystone.common import kvs
|
||||
from keystone.common.kvs import core as kvs_core
|
||||
from keystone.common import sql
|
||||
from keystone.common import utils as common_utils
|
||||
from keystone import config
|
||||
from keystone import exception
|
||||
from keystone import notifications
|
||||
from keystone.openstack.common.db import options as db_options
|
||||
from keystone.openstack.common.fixture import config as config_fixture
|
||||
from keystone.openstack.common.gettextutils import _
|
||||
from keystone.openstack.common import log
|
||||
@ -119,19 +117,6 @@ class dirs:
|
||||
DEFAULT_TEST_DB_FILE = dirs.tmp('test.db')
|
||||
|
||||
|
||||
def _initialize_sql_session():
|
||||
# Make sure the DB is located in the correct location, in this case set
|
||||
# the default value, as this should be able to be overridden in some
|
||||
# test cases.
|
||||
db_file = DEFAULT_TEST_DB_FILE
|
||||
db_options.set_defaults(
|
||||
sql_connection=IN_MEM_DB_CONN_STRING,
|
||||
sqlite_db=db_file)
|
||||
|
||||
|
||||
_initialize_sql_session()
|
||||
|
||||
|
||||
def checkout_vendor(repo, rev):
|
||||
# TODO(termie): this function is a good target for some optimizations :PERF
|
||||
name = repo.split('/')[-1]
|
||||
@ -459,15 +444,6 @@ class TestCase(BaseTestCase):
|
||||
setattr(self, manager_name, manager)
|
||||
self.addCleanup(self.cleanup_instance(*drivers.keys()))
|
||||
|
||||
# The credential backend only supports SQL, so we always have to load
|
||||
# the tables.
|
||||
self.engine = sql.get_engine()
|
||||
self.addCleanup(sql.cleanup)
|
||||
self.addCleanup(self.cleanup_instance('engine'))
|
||||
|
||||
sql.ModelBase.metadata.create_all(bind=self.engine)
|
||||
self.addCleanup(sql.ModelBase.metadata.drop_all, bind=self.engine)
|
||||
|
||||
def load_fixtures(self, fixtures):
|
||||
"""Hacky basic and naive fixture loading based on a python module.
|
||||
|
||||
|
105
keystone/tests/ksfixtures/database.py
Normal file
105
keystone/tests/ksfixtures/database.py
Normal file
@ -0,0 +1,105 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import functools
|
||||
import os
|
||||
import shutil
|
||||
|
||||
import fixtures
|
||||
|
||||
from keystone.common import sql
|
||||
from keystone.common.sql import migration_helpers
|
||||
from keystone import config
|
||||
from keystone.openstack.common.db import options as db_options
|
||||
from keystone.openstack.common.db.sqlalchemy import migration
|
||||
from keystone import tests
|
||||
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
def run_once(f):
|
||||
@functools.wraps(f)
|
||||
def wrapper():
|
||||
if not wrapper.already_ran:
|
||||
f()
|
||||
wrapper.already_ran = True
|
||||
wrapper.already_ran = False
|
||||
return wrapper
|
||||
|
||||
|
||||
def _setup_database(extensions=None):
|
||||
if CONF.database.connection != tests.IN_MEM_DB_CONN_STRING:
|
||||
db = tests.dirs.tmp('test.db')
|
||||
pristine = tests.dirs.tmp('test.db.pristine')
|
||||
|
||||
if os.path.exists(db):
|
||||
os.unlink(db)
|
||||
if not os.path.exists(pristine):
|
||||
migration.db_sync(sql.get_engine(),
|
||||
migration_helpers.find_migrate_repo())
|
||||
for extension in (extensions or []):
|
||||
migration_helpers.sync_database_to_version(extension=extension)
|
||||
shutil.copyfile(db, pristine)
|
||||
else:
|
||||
shutil.copyfile(pristine, db)
|
||||
|
||||
|
||||
@run_once
|
||||
def _initialize_sql_session():
|
||||
# Make sure the DB is located in the correct location, in this case set
|
||||
# the default value, as this should be able to be overridden in some
|
||||
# test cases.
|
||||
db_options.set_defaults(
|
||||
sql_connection=tests.IN_MEM_DB_CONN_STRING,
|
||||
sqlite_db=tests.DEFAULT_TEST_DB_FILE)
|
||||
|
||||
|
||||
@run_once
|
||||
def _load_sqlalchemy_models():
|
||||
"""Find all modules containing SQLAlchemy models and import them.
|
||||
|
||||
This will create more consistent, deterministic test runs because the
|
||||
database schema will be predictable. The schema is created based on the
|
||||
models already imported. This can change during the course of a test run.
|
||||
If all models are imported ahead of time then the schema will always be
|
||||
the same.
|
||||
|
||||
"""
|
||||
keystone_root = os.path.normpath(os.path.join(
|
||||
os.path.dirname(__file__), '..', '..'))
|
||||
for root, dirs, files in os.walk(keystone_root):
|
||||
if root.endswith('backends') and 'sql.py' in files:
|
||||
module_name = root.replace(os.sep, '.') + '.sql'
|
||||
__import__(module_name)
|
||||
|
||||
|
||||
class Database(fixtures.Fixture):
|
||||
"""A fixture for setting up and tearing down a database.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, extensions=None):
|
||||
super(Database, self).__init__()
|
||||
self._extensions = extensions
|
||||
_initialize_sql_session()
|
||||
_load_sqlalchemy_models()
|
||||
|
||||
def setUp(self):
|
||||
super(Database, self).setUp()
|
||||
_setup_database(extensions=self._extensions)
|
||||
|
||||
self.engine = sql.get_engine()
|
||||
sql.ModelBase.metadata.create_all(bind=self.engine)
|
||||
self.addCleanup(sql.cleanup)
|
||||
self.addCleanup(sql.ModelBase.metadata.drop_all, bind=self.engine)
|
@ -27,6 +27,7 @@ from keystone import exception
|
||||
from keystone.openstack.common import timeutils
|
||||
from keystone import tests
|
||||
from keystone.tests import default_fixtures
|
||||
from keystone.tests.ksfixtures import database
|
||||
from keystone import token
|
||||
from keystone import trust
|
||||
|
||||
@ -68,6 +69,7 @@ def _build_user_auth(token=None, user_id=None, username=None,
|
||||
|
||||
class AuthTest(tests.TestCase):
|
||||
def setUp(self):
|
||||
self.useFixture(database.Database())
|
||||
super(AuthTest, self).setUp()
|
||||
|
||||
self.load_backends()
|
||||
|
@ -20,11 +20,16 @@ from keystone import exception
|
||||
from keystone.openstack.common import timeutils
|
||||
from keystone import tests
|
||||
from keystone.tests import default_fixtures
|
||||
from keystone.tests.ksfixtures import database
|
||||
from keystone.tests import test_backend
|
||||
|
||||
|
||||
class KvsIdentity(tests.TestCase, test_backend.IdentityTests):
|
||||
def setUp(self):
|
||||
# NOTE(dstanek): setup the database for subsystems that do not have a
|
||||
# KVS backend (like credentials)
|
||||
self.useFixture(database.Database())
|
||||
|
||||
super(KvsIdentity, self).setUp()
|
||||
self.load_backends()
|
||||
self.load_fixtures(default_fixtures)
|
||||
|
@ -32,6 +32,7 @@ from keystone import identity
|
||||
from keystone import tests
|
||||
from keystone.tests import default_fixtures
|
||||
from keystone.tests import fakeldap
|
||||
from keystone.tests.ksfixtures import database
|
||||
from keystone.tests import test_backend
|
||||
|
||||
|
||||
@ -592,6 +593,14 @@ class BaseLDAPIdentity(test_backend.IdentityTests):
|
||||
|
||||
|
||||
class LDAPIdentity(BaseLDAPIdentity, tests.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
# NOTE(dstanek): The database must be setup prior to calling the
|
||||
# parent's setUp. The parent's setUp uses services (like
|
||||
# credentials) that require a database.
|
||||
self.useFixture(database.Database())
|
||||
super(LDAPIdentity, self).setUp()
|
||||
|
||||
def test_configurable_allowed_project_actions(self):
|
||||
tenant = {'id': u'fäké1', 'name': u'fäké1', 'enabled': True}
|
||||
self.assignment_api.create_project(u'fäké1', tenant)
|
||||
@ -1332,6 +1341,7 @@ class LdapIdentitySqlAssignment(BaseLDAPIdentity, tests.SQLDriverOverrides,
|
||||
return config_files
|
||||
|
||||
def setUp(self):
|
||||
self.useFixture(database.Database())
|
||||
super(LdapIdentitySqlAssignment, self).setUp()
|
||||
self.clear_database()
|
||||
self.load_backends()
|
||||
@ -1416,6 +1426,7 @@ class MultiLDAPandSQLIdentity(BaseLDAPIdentity, tests.SQLDriverOverrides,
|
||||
|
||||
"""
|
||||
def setUp(self):
|
||||
self.useFixture(database.Database())
|
||||
super(MultiLDAPandSQLIdentity, self).setUp()
|
||||
|
||||
self.load_backends()
|
||||
|
@ -26,6 +26,7 @@ from keystone.identity.backends import sql as identity_sql
|
||||
from keystone.openstack.common.db import exception as db_exception
|
||||
from keystone import tests
|
||||
from keystone.tests import default_fixtures
|
||||
from keystone.tests.ksfixtures import database
|
||||
from keystone.tests import test_backend
|
||||
from keystone.token.backends import sql as token_sql
|
||||
|
||||
@ -38,6 +39,7 @@ class SqlTests(tests.SQLDriverOverrides, tests.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(SqlTests, self).setUp()
|
||||
self.useFixture(database.Database())
|
||||
self.load_backends()
|
||||
|
||||
# populate the engine with tables & fixtures
|
||||
@ -52,15 +54,10 @@ class SqlTests(tests.SQLDriverOverrides, tests.TestCase):
|
||||
|
||||
|
||||
class SqlModels(SqlTests):
|
||||
def setUp(self):
|
||||
super(SqlModels, self).setUp()
|
||||
|
||||
self.metadata = sql.ModelBase.metadata
|
||||
self.metadata.bind = self.engine
|
||||
|
||||
def select_table(self, name):
|
||||
table = sqlalchemy.Table(name,
|
||||
self.metadata,
|
||||
sql.ModelBase.metadata,
|
||||
autoload=True)
|
||||
s = sqlalchemy.select([table])
|
||||
return s
|
||||
|
@ -25,6 +25,7 @@ from keystone.openstack.common import timeutils
|
||||
from keystone import tests
|
||||
from keystone.tests import default_fixtures
|
||||
from keystone.tests.ksfixtures import appserver
|
||||
from keystone.tests.ksfixtures import database
|
||||
|
||||
|
||||
CONF = config.CONF
|
||||
@ -43,6 +44,7 @@ class CompatTestCase(tests.NoModule, tests.TestCase):
|
||||
# approach is to ensure we have the correct backing store. The
|
||||
# credential api makes some very SQL specific assumptions that should
|
||||
# be addressed allowing for non-SQL based testing to occur.
|
||||
self.useFixture(database.Database())
|
||||
self.load_backends()
|
||||
|
||||
self.load_fixtures(default_fixtures)
|
||||
|
@ -13,8 +13,6 @@
|
||||
# under the License.
|
||||
|
||||
import datetime
|
||||
import os
|
||||
import shutil
|
||||
import uuid
|
||||
|
||||
from lxml import etree
|
||||
@ -25,15 +23,13 @@ from keystone import auth
|
||||
from keystone.common import authorization
|
||||
from keystone.common import cache
|
||||
from keystone.common import serializer
|
||||
from keystone.common import sql
|
||||
from keystone.common.sql import migration_helpers
|
||||
from keystone import config
|
||||
from keystone import exception
|
||||
from keystone import middleware
|
||||
from keystone.openstack.common.db.sqlalchemy import migration
|
||||
from keystone.openstack.common import timeutils
|
||||
from keystone.policy.backends import rules
|
||||
from keystone import tests
|
||||
from keystone.tests.ksfixtures import database
|
||||
from keystone.tests import rest
|
||||
|
||||
|
||||
@ -43,27 +39,6 @@ DEFAULT_DOMAIN_ID = 'default'
|
||||
TIME_FORMAT = '%Y-%m-%dT%H:%M:%S.%fZ'
|
||||
|
||||
|
||||
def _setup_database(extensions=None):
|
||||
if CONF.database.connection != tests.IN_MEM_DB_CONN_STRING:
|
||||
db = tests.dirs.tmp('test.db')
|
||||
pristine = tests.dirs.tmp('test.db.pristine')
|
||||
|
||||
if os.path.exists(db):
|
||||
os.unlink(db)
|
||||
if not os.path.exists(pristine):
|
||||
migration.db_sync(sql.get_engine(),
|
||||
migration_helpers.find_migrate_repo())
|
||||
for extension in (extensions or []):
|
||||
migration_helpers.sync_database_to_version(extension=extension)
|
||||
shutil.copyfile(db, pristine)
|
||||
else:
|
||||
shutil.copyfile(pristine, db)
|
||||
|
||||
|
||||
def _teardown_database():
|
||||
sql.cleanup()
|
||||
|
||||
|
||||
class RestfulTestCase(tests.SQLDriverOverrides, rest.RestfulTestCase):
|
||||
def config_files(self):
|
||||
config_files = super(RestfulTestCase, self).config_files()
|
||||
@ -76,12 +51,6 @@ class RestfulTestCase(tests.SQLDriverOverrides, rest.RestfulTestCase):
|
||||
extensions.add(self.EXTENSION_NAME)
|
||||
return extensions
|
||||
|
||||
def setup_database(self):
|
||||
_setup_database(self.get_extensions())
|
||||
|
||||
def teardown_database(self):
|
||||
_teardown_database()
|
||||
|
||||
def generate_paste_config(self):
|
||||
new_paste_file = None
|
||||
try:
|
||||
@ -108,6 +77,8 @@ class RestfulTestCase(tests.SQLDriverOverrides, rest.RestfulTestCase):
|
||||
if new_paste_file:
|
||||
app_conf = 'config:%s' % (new_paste_file)
|
||||
|
||||
self.useFixture(database.Database(self.get_extensions()))
|
||||
|
||||
super(RestfulTestCase, self).setUp(app_conf=app_conf)
|
||||
|
||||
self.empty_context = {'environment': {}}
|
||||
@ -115,11 +86,7 @@ class RestfulTestCase(tests.SQLDriverOverrides, rest.RestfulTestCase):
|
||||
# drop the policy rules
|
||||
self.addCleanup(rules.reset)
|
||||
|
||||
self.addCleanup(self.teardown_database)
|
||||
|
||||
def load_backends(self):
|
||||
self.setup_database()
|
||||
|
||||
# ensure the cache region instance is setup
|
||||
cache.configure_cache_region(cache.REGION)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user