Stop creating a context manager during db._api module import

This patch exposes accessors methods for the context manager,
pulls latest changes according to bp/enginefacade-switch, and
publishes a Sql fixture.

Original-commit: I28b741bfa27bf04cbe273586e6e3e00e14fbe683
Co-authored-by: Ann Taraday <akamyshnikova@mirantis.com>
Change-Id: I6e923e9b228ba20a8b782e787504239da713c652
This commit is contained in:
Armando Migliaccio 2017-01-18 18:37:15 -08:00
parent 0587be438c
commit dff79c608f
8 changed files with 106 additions and 57 deletions

View File

@ -18,9 +18,8 @@ import datetime
from oslo_context import context as oslo_context
from oslo_db.sqlalchemy import enginefacade
# TODO(HenryG): replace db/_api.py with the real db/api.py
from neutron_lib import _policy as policy
from neutron_lib.db import _api as db_api
from neutron_lib.db import api as db_api
class ContextBase(oslo_context.RequestContext):
@ -144,7 +143,8 @@ class Context(ContextBaseWithSession):
if hasattr(super(Context, self), 'session'):
return super(Context, self).session
if self._session is None:
self._session = db_api.get_session()
self._session = db_api.get_writer_session()
return self._session

View File

@ -1,26 +0,0 @@
# 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.
from oslo_db.sqlalchemy import enginefacade
context_manager = enginefacade.transaction_context()
context_manager.configure(sqlite_fk=True)
# TODO(akamyshnikova): when all places in the code, which use sessions/
# connections will be updated, this won't be needed
def get_session(autocommit=True, expire_on_commit=False, use_slave=False):
"""Helper method to grab session."""
return context_manager.get_legacy_facade().get_session(
autocommit=autocommit, expire_on_commit=expire_on_commit,
use_slave=use_slave)

54
neutron_lib/db/api.py Normal file
View File

@ -0,0 +1,54 @@
# 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.
from oslo_concurrency import lockutils
from oslo_db.sqlalchemy import enginefacade
_synchronized = lockutils.synchronized_with_prefix("neutron-")
_CTX_MANAGER = None
@_synchronized("context-manager")
def _create_context_manager():
global _CTX_MANAGER
if _CTX_MANAGER is None:
_CTX_MANAGER = enginefacade.transaction_context()
_CTX_MANAGER.configure(sqlite_fk=True)
return _CTX_MANAGER
def get_context_manager():
"""Transaction Context Manager accessor.
:returns: The transaction context manager.
"""
if _CTX_MANAGER is None:
return _create_context_manager()
return _CTX_MANAGER
def get_reader_session():
"""Helper to get reader session.
:returns: The reader session.
"""
return get_context_manager().reader.get_sessionmaker()()
def get_writer_session():
"""Helper to get writer session.
:returns: The writer session.
"""
return get_context_manager().writer.get_sessionmaker()()

View File

@ -14,6 +14,8 @@ import fixtures
from neutron_lib.callbacks import manager
from neutron_lib.callbacks import registry
from neutron_lib.db import api as db_api
from neutron_lib.db import model_base
from neutron_lib.plugins import directory
@ -59,3 +61,24 @@ class CallbackRegistryFixture(fixtures.Fixture):
def _restore(self):
registry._CALLBACK_MANAGER = self._orig_manager
class SqlFixture(fixtures.Fixture):
# flag to indicate that the models have been loaded
_TABLES_ESTABLISHED = False
def _setUp(self):
# Register all data models
engine = db_api.get_context_manager().writer.get_engine()
if not SqlFixture._TABLES_ESTABLISHED:
model_base.BASEV2.metadata.create_all(engine)
SqlFixture._TABLES_ESTABLISHED = True
def clear_tables():
with engine.begin() as conn:
for table in reversed(
model_base.BASEV2.metadata.sorted_tables):
conn.execute(table.delete())
self.addCleanup(clear_tables)

View File

@ -15,37 +15,12 @@ Base classes for unit tests needing DB backend.
Only sqlite is supported in neutron-lib.
"""
import fixtures
from neutron_lib.db import _api as db_api
from neutron_lib.db import model_base
from neutron_lib import fixture
from neutron_lib.tests import _base as base
class SqlFixture(fixtures.Fixture):
# flag to indicate that the models have been loaded
_TABLES_ESTABLISHED = False
def _setUp(self):
# Register all data models
engine = db_api.context_manager.get_legacy_facade().get_engine()
if not SqlFixture._TABLES_ESTABLISHED:
model_base.BASEV2.metadata.create_all(engine)
SqlFixture._TABLES_ESTABLISHED = True
def clear_tables():
with engine.begin() as conn:
for table in reversed(
model_base.BASEV2.metadata.sorted_tables):
conn.execute(table.delete())
self.addCleanup(clear_tables)
class SqlTestCase(base.BaseTestCase):
def setUp(self):
super(SqlTestCase, self).setUp()
self.useFixture(SqlFixture())
self.useFixture(fixture.SqlFixture())

View File

@ -22,7 +22,7 @@ class TestNeutronContext(_base.BaseTestCase):
def setUp(self):
super(TestNeutronContext, self).setUp()
db_api = 'neutron_lib.db._api.get_session'
db_api = 'neutron_lib.db.api.get_writer_session'
self._db_api_session_patcher = mock.patch(db_api)
self.db_api_session = self._db_api_session_patcher.start()

View File

@ -12,9 +12,12 @@
import mock
from oslo_config import cfg
from oslo_db import options
from oslotest import base
from neutron_lib.callbacks import registry
from neutron_lib.db import model_base
from neutron_lib import fixture
from neutron_lib.plugins import directory
@ -43,3 +46,16 @@ class CallbackRegistryFixtureTestCase(base.BaseTestCase):
def test_fixture(self):
registry.notify('a', 'b', self)
self.assertTrue(self.manager.notify.called)
class SqlFixtureTestCase(base.BaseTestCase):
def setUp(self):
super(SqlFixtureTestCase, self).setUp()
options.set_defaults(
cfg.CONF,
connection='sqlite://')
self.useFixture(fixture.SqlFixture())
def test_fixture(self):
self.assertIsNotNone(model_base.BASEV2.metadata.sorted_tables)

View File

@ -0,0 +1,7 @@
---
features:
- |
``neutron_lib.db`` has a public module ``api`` that provides
accessor functions for transactional context manager services.
- |
``neutron_lib.fixture`` has a new ``SqlFixture`` available.