Skip to content

Commit

Permalink
Clear cached engine when global engine changes
Browse files Browse the repository at this point in the history
The keystone.common.sql.core.Base class cached the global database
engine when get_session() was called. When the global database engine
changed to a new instance, the cached copy was used in subsequent
calls to get_session(), leading to using the old engine and tests
failing to run by themselves.

This change makes it so that when the global database engine is
changed, Base will use the new engine rather than the invalid one.

Change-Id: I75aa3c230d9b4fd666ab8d478c9e9a27669905e8
Fixes: Bug #1179259
  • Loading branch information
Brant Knudson committed Jul 12, 2013
1 parent 24a6f41 commit 405a914
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
11 changes: 8 additions & 3 deletions keystone/common/sql/core.py
Expand Up @@ -250,9 +250,10 @@ class Base(object):

def get_session(self, autocommit=True, expire_on_commit=False):
"""Return a SQLAlchemy session."""
self._engine = self._engine or self.get_engine()
self._sessionmaker = self._sessionmaker or self.get_sessionmaker(
self._engine)
if not self._engine:
self._engine = self.get_engine()
self._sessionmaker = self.get_sessionmaker(self._engine)
register_global_engine_callback(self.clear_engine)
return self._sessionmaker(autocommit=autocommit,
expire_on_commit=expire_on_commit)

Expand Down Expand Up @@ -307,6 +308,10 @@ def get_sessionmaker(self, engine, autocommit=True,
autocommit=autocommit,
expire_on_commit=expire_on_commit)

def clear_engine(self):
self._engine = None
self._sessionmaker = None


def handle_conflicts(type='object'):
"""Converts IntegrityError into HTTP 409 Conflict."""
Expand Down
8 changes: 8 additions & 0 deletions tests/test_sql_core.py
Expand Up @@ -172,3 +172,11 @@ def test_get_session(self):

self.assertFalse(session.autocommit)
self.assertTrue(session.expire_on_commit)

def test_get_session_invalidated(self):
# If clear the global engine, a new engine is used for get_session().
base = sql.Base()
session1 = base.get_session()
sql.set_global_engine(None)
session2 = base.get_session()
self.assertIsNot(session1.bind, session2.bind)

0 comments on commit 405a914

Please sign in to comment.