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:
parent
0587be438c
commit
dff79c608f
|
@ -18,9 +18,8 @@ import datetime
|
||||||
from oslo_context import context as oslo_context
|
from oslo_context import context as oslo_context
|
||||||
from oslo_db.sqlalchemy import enginefacade
|
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 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):
|
class ContextBase(oslo_context.RequestContext):
|
||||||
|
@ -144,7 +143,8 @@ class Context(ContextBaseWithSession):
|
||||||
if hasattr(super(Context, self), 'session'):
|
if hasattr(super(Context, self), 'session'):
|
||||||
return super(Context, self).session
|
return super(Context, self).session
|
||||||
if self._session is None:
|
if self._session is None:
|
||||||
self._session = db_api.get_session()
|
self._session = db_api.get_writer_session()
|
||||||
|
|
||||||
return self._session
|
return self._session
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
|
|
@ -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()()
|
|
@ -14,6 +14,8 @@ import fixtures
|
||||||
|
|
||||||
from neutron_lib.callbacks import manager
|
from neutron_lib.callbacks import manager
|
||||||
from neutron_lib.callbacks import registry
|
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
|
from neutron_lib.plugins import directory
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,3 +61,24 @@ class CallbackRegistryFixture(fixtures.Fixture):
|
||||||
|
|
||||||
def _restore(self):
|
def _restore(self):
|
||||||
registry._CALLBACK_MANAGER = self._orig_manager
|
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)
|
||||||
|
|
|
@ -15,37 +15,12 @@ Base classes for unit tests needing DB backend.
|
||||||
Only sqlite is supported in neutron-lib.
|
Only sqlite is supported in neutron-lib.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import fixtures
|
from neutron_lib import fixture
|
||||||
|
|
||||||
from neutron_lib.db import _api as db_api
|
|
||||||
from neutron_lib.db import model_base
|
|
||||||
|
|
||||||
from neutron_lib.tests import _base as base
|
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):
|
class SqlTestCase(base.BaseTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(SqlTestCase, self).setUp()
|
super(SqlTestCase, self).setUp()
|
||||||
self.useFixture(SqlFixture())
|
self.useFixture(fixture.SqlFixture())
|
||||||
|
|
|
@ -22,7 +22,7 @@ class TestNeutronContext(_base.BaseTestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
super(TestNeutronContext, self).setUp()
|
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_patcher = mock.patch(db_api)
|
||||||
self.db_api_session = self._db_api_session_patcher.start()
|
self.db_api_session = self._db_api_session_patcher.start()
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,12 @@
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
|
||||||
|
from oslo_config import cfg
|
||||||
|
from oslo_db import options
|
||||||
from oslotest import base
|
from oslotest import base
|
||||||
|
|
||||||
from neutron_lib.callbacks import registry
|
from neutron_lib.callbacks import registry
|
||||||
|
from neutron_lib.db import model_base
|
||||||
from neutron_lib import fixture
|
from neutron_lib import fixture
|
||||||
from neutron_lib.plugins import directory
|
from neutron_lib.plugins import directory
|
||||||
|
|
||||||
|
@ -43,3 +46,16 @@ class CallbackRegistryFixtureTestCase(base.BaseTestCase):
|
||||||
def test_fixture(self):
|
def test_fixture(self):
|
||||||
registry.notify('a', 'b', self)
|
registry.notify('a', 'b', self)
|
||||||
self.assertTrue(self.manager.notify.called)
|
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)
|
||||||
|
|
|
@ -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.
|
Loading…
Reference in New Issue