]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
try to liberalize the pool._refs assertion a bit
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 26 Mar 2014 20:52:04 +0000 (16:52 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 26 Mar 2014 20:52:04 +0000 (16:52 -0400)
lib/sqlalchemy/testing/assertions.py

index a0b5ed0c9fdeaa268b6b6c58c24e6d5e6864b90f..0a65a1b7c26d5bf686d935b22196a95d8d43068a 100644 (file)
@@ -128,7 +128,6 @@ def expect_deprecated(*messages):
         resetwarnings()
 
 
-
 def global_cleanup_assertions():
     """Check things that have to be finalized at the end of a test suite.
 
@@ -137,9 +136,42 @@ def global_cleanup_assertions():
     dropped, etc.
 
     """
+    _assert_no_stray_pool_connections()
+
+_STRAY_CONNECTION_FAILURES = 0
+def _assert_no_stray_pool_connections():
+    global _STRAY_CONNECTION_FAILURES
 
+    # lazy gc on cPython means "do nothing."  pool connections
+    # shouldn't be in cycles, should go away.
     testutil.lazy_gc()
-    assert not pool._refs, str(pool._refs)
+
+    # however, once in awhile, on an EC2 machine usually,
+    # there's a ref in there.  usually just one.
+    if pool._refs:
+        # OK, let's be somewhat forgiving.  Increment a counter,
+        # we'll allow a couple of these at most.
+        _STRAY_CONNECTION_FAILURES += 1
+
+        util.warn("Encountered a stray connection in test cleanup: %s"
+                        % str(pool._refs))
+        # then do a real GC sweep.   We shouldn't even be here
+        # so a single sweep should really be doing it, otherwise
+        # there's probably a real unreachable cycle somewhere.
+        testutil.gc_collect()
+
+    # if we've already had two of these occurrences, or
+    # after a hard gc sweep we still have pool._refs?!
+    # now we have to raise.
+    if _STRAY_CONNECTION_FAILURES >= 2 or pool._refs:
+        err = str(pool._refs)
+
+        # but clean out the pool refs collection directly,
+        # reset the counter,
+        # so the error doesn't at least keep happening.
+        pool._refs.clear()
+        _STRAY_CONNECTION_FAILURES = 0
+        assert False, err
 
 
 def eq_(a, b, msg=None):