summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2014-12-12 12:48:22 +0000
committerGerrit Code Review <review@openstack.org>2014-12-12 12:48:22 +0000
commit571433bfc4936d90602bfac4cbd7e9170c0a8d07 (patch)
tree817a211de61cd707ee19c6609275db333da72a2a
parent8d07501262cac8ff7b4312e62f89ccbf2f854327 (diff)
parent0265aa4e01270b8fc7cab1266b8602e1921c9ddb (diff)
downloadoslo-db-571433bfc4936d90602bfac4cbd7e9170c0a8d07.tar.gz
Merge "Repair string-based disconnect filters for MySQL, DB2"1.3.0
-rw-r--r--oslo/db/sqlalchemy/exc_filters.py5
-rw-r--r--tests/sqlalchemy/test_exc_filters.py32
2 files changed, 29 insertions, 8 deletions
diff --git a/oslo/db/sqlalchemy/exc_filters.py b/oslo/db/sqlalchemy/exc_filters.py
index f997237..f283f08 100644
--- a/oslo/db/sqlalchemy/exc_filters.py
+++ b/oslo/db/sqlalchemy/exc_filters.py
@@ -269,9 +269,8 @@ def _raise_operational_errors_directly_filter(operational_error,
raise operational_error
-# For the db2, the error code is -30081 since the db2 is still not ready
-@filters("mysql", sqla_exc.OperationalError, r".*\((?:2002|2003|2006|2013)")
-@filters("ibm_db_sa", sqla_exc.OperationalError, r".*(?:-30081)")
+@filters("mysql", sqla_exc.OperationalError, r".*\(.*(?:2002|2003|2006|2013)")
+@filters("ibm_db_sa", sqla_exc.OperationalError, r".*(?:30081)")
def _is_db_connection_error(operational_error, match, engine_name,
is_disconnect):
"""Detect the exception as indicating a recoverable error on connect."""
diff --git a/tests/sqlalchemy/test_exc_filters.py b/tests/sqlalchemy/test_exc_filters.py
index 07b00dd..a3f91a6 100644
--- a/tests/sqlalchemy/test_exc_filters.py
+++ b/tests/sqlalchemy/test_exc_filters.py
@@ -665,7 +665,9 @@ class IntegrationTest(test_base.DbTestCase):
class TestDBDisconnected(TestsExceptionFilter):
@contextlib.contextmanager
- def _fixture(self, dialect_name, exception, num_disconnects):
+ def _fixture(
+ self,
+ dialect_name, exception, num_disconnects, is_disconnect=True):
engine = self.engine
compat.engine_connect(engine, session._connect_ping_listener)
@@ -686,12 +688,13 @@ class TestDBDisconnected(TestsExceptionFilter):
fake_do_execute),
mock.patch.object(engine.dialect,
"is_disconnect",
- mock.Mock(return_value=True))
+ mock.Mock(return_value=is_disconnect))
):
yield
- def _test_ping_listener_disconnected(self, dialect_name, exc_obj):
- with self._fixture(dialect_name, exc_obj, 1):
+ def _test_ping_listener_disconnected(
+ self, dialect_name, exc_obj, is_disconnect=True):
+ with self._fixture(dialect_name, exc_obj, 1, is_disconnect):
conn = self.engine.connect()
with conn.begin():
self.assertEqual(conn.scalar(sqla.select([1])), 1)
@@ -699,7 +702,7 @@ class TestDBDisconnected(TestsExceptionFilter):
self.assertFalse(conn.invalidated)
self.assertTrue(conn.in_transaction())
- with self._fixture(dialect_name, exc_obj, 2):
+ with self._fixture(dialect_name, exc_obj, 2, is_disconnect):
self.assertRaises(
exception.DBConnectionError,
self.engine.connect
@@ -716,6 +719,17 @@ class TestDBDisconnected(TestsExceptionFilter):
self.OperationalError('%d MySQL server has gone away' % code)
)
+ def test_mysql_ping_listener_disconnected_regex_only(self):
+ # intentionally set the is_disconnect flag to False
+ # in the "sqlalchemy" layer to make sure the regexp
+ # on _is_db_connection_error is catching
+ for code in [2002, 2003, 2006, 2013]:
+ self._test_ping_listener_disconnected(
+ "mysql",
+ self.OperationalError('%d MySQL server has gone away' % code),
+ is_disconnect=False
+ )
+
def test_db2_ping_listener_disconnected(self):
self._test_ping_listener_disconnected(
"ibm_db_sa",
@@ -723,6 +737,14 @@ class TestDBDisconnected(TestsExceptionFilter):
'SQL30081N: DB2 Server connection is no longer active')
)
+ def test_db2_ping_listener_disconnected_regex_only(self):
+ self._test_ping_listener_disconnected(
+ "ibm_db_sa",
+ self.OperationalError(
+ 'SQL30081N: DB2 Server connection is no longer active'),
+ is_disconnect=False
+ )
+
class TestDBConnectRetry(TestsExceptionFilter):