summaryrefslogtreecommitdiff
path: root/test/engine
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2018-03-28 11:58:47 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2018-03-28 15:49:17 -0400
commitc5437296713288cbfcd323032ca48a75a97e10e5 (patch)
treee44af08faca6a4935ddd595ead614d20da40f51c /test/engine
parentf9c4b5ea7deca071d38e89cbd5643b98f78dd25f (diff)
downloadsqlalchemy-c5437296713288cbfcd323032ca48a75a97e10e5.tar.gz
Invalidate on failed connect handler
Fixed bug in connection pool where a connection could be present in the pool without all of its "connect" event handlers called, if a previous "connect" handler threw an exception; note that the dialects themselves have connect handlers that emit SQL, such as those which set transaction isolation, which can fail if the database is in a non-available state, but still allows a connection. The connection is now invalidated first if any of the connect handlers fail. Change-Id: I61d6f4827a98ab8455f1c3e1c55d046eeccec09a Fixes: #4225
Diffstat (limited to 'test/engine')
-rw-r--r--test/engine/test_pool.py29
1 files changed, 29 insertions, 0 deletions
diff --git a/test/engine/test_pool.py b/test/engine/test_pool.py
index e3f34dfa7..b699afbc6 100644
--- a/test/engine/test_pool.py
+++ b/test/engine/test_pool.py
@@ -730,6 +730,35 @@ class PoolEventsTest(PoolTestBase):
p2.connect()
eq_(canary, ["listen_one", "listen_two", "listen_one", "listen_three"])
+ def test_connect_event_fails_invalidates(self):
+ fail = False
+
+ def listen_one(conn, rec):
+ if fail:
+ raise Exception("it failed")
+
+ def listen_two(conn, rec):
+ rec.info['important_flag'] = True
+
+ p1 = pool.QueuePool(
+ creator=MockDBAPI().connect, pool_size=1, max_overflow=0)
+ event.listen(p1, 'connect', listen_one)
+ event.listen(p1, 'connect', listen_two)
+
+ conn = p1.connect()
+ eq_(conn.info['important_flag'], True)
+ conn.invalidate()
+ conn.close()
+
+ fail = True
+ assert_raises(Exception, p1.connect)
+
+ fail = False
+
+ conn = p1.connect()
+ eq_(conn.info['important_flag'], True)
+ conn.close()
+
def teardown(self):
# TODO: need to get remove() functionality
# going