I have a test-case with both a setUp and tearDown method:
TESTCONF = SafeConfigParser(...)
ENGINE = create_engine(TESTCONF.get('database', 'dsn'))
class TestBase(TestCase):
def setUp(self):
self.config = TESTCONF
self.connection = ENGINE.connect()
self.trans = self.connection.begin()
self.session = Session(bind=self.connection)
def tearDown(self):
print "post teardown 0", ENGINE.pool.status()
self.trans.rollback()
print "post teardown 1", ENGINE.pool.status()
self.session.close()
print "post teardown 2", ENGINE.pool.status()
self.connection.close()
print "post teardown 3", ENGINE.pool.status(), "\n"
All DB related test-cases inherit from this class. It seems as if tearDown is not always called. I am having trouble to localize the error. At one point, the test-runner hangs on
self.connection = ENGINE.connect()
I assume that the close method was not always called to release a connection from the pool.
Any ideas what to look for?
Update: I how added some print statements (also added them in the example code above), and my initial though was correct. Some connections are not properly closed and are not handed back to the pool. This happens for all "Errors" (not "Failures") in the tests. The following block shows the output I get using the above tearDown method (cut off prematurely for brevity). As you can see, the lines with errors (those starting with Epre instead of .pre) do not call any tearDown lines. Not even the post tearDown 0 message shows up!
I have now traced back the error to using self.assertRaisesRegEx instead of self.assertRaisesRegExp, so the exception is raised inside the unit-test, not inside the tested code!
pre setup Pool size: 5 Connections in pool: 0 Current Overflow: -5 Current Checked out connections: 0
post connect Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 0 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 1 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 2 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 3 Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
.pre setup Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
post connect Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 0 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 1 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 2 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 3 Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
.pre setup Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
post connect Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 0 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 1 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 2 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 3 Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
.pre setup Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
post connect Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
'TestCommonBase' object has no attribute 'assertRaisesRegex'
post teardown 0 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 1 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 2 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 3 Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
.pre setup Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
post connect Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 0 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 1 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 2 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 3 Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
.pre setup Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
post connect Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 0 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 1 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 2 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 3 Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
.pre setup Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
post connect Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 0 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 1 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 2 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 3 Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
.pre setup Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
post connect Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
'TestCommonBase' object has no attribute 'assertRaisesRegex'
post teardown 0 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 1 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 2 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 3 Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
.pre setup Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
post connect Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 0 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 1 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 2 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 3 Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
.pre setup Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
post connect Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 0 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 1 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 2 Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post teardown 3 Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
.SSpre setup Pool size: 5 Connections in pool: 1 Current Overflow: -4 Current Checked out connections: 0
post connect Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
ESpre setup Pool size: 5 Connections in pool: 0 Current Overflow: -4 Current Checked out connections: 1
post connect Pool size: 5 Connections in pool: 0 Current Overflow: -3 Current Checked out connections: 2
Epre setup Pool size: 5 Connections in pool: 0 Current Overflow: -3 Current Checked out connections: 2
post connect Pool size: 5 Connections in pool: 0 Current Overflow: -2 Current Checked out connections: 3
Epre setup Pool size: 5 Connections in pool: 0 Current Overflow: -2 Current Checked out connections: 3
post connect Pool size: 5 Connections in pool: 0 Current Overflow: -1 Current Checked out connections: 4
Epre setup Pool size: 5 Connections in pool: 0 Current Overflow: -1 Current Checked out connections: 4
post connect Pool size: 5 Connections in pool: 0 Current Overflow: 0 Current Checked out connections: 5
Epre setup Pool size: 5 Connections in pool: 0 Current Overflow: 0 Current Checked out connections: 5
post connect Pool size: 5 Connections in pool: 0 Current Overflow: 1 Current Checked out connections: 6
Epre setup Pool size: 5 Connections in pool: 0 Current Overflow: 1 Current Checked out connections: 6
post connect Pool size: 5 Connections in pool: 0 Current Overflow: 2 Current Checked out connections: 7
Epre setup Pool size: 5 Connections in pool: 0 Current Overflow: 2 Current Checked out connections: 7
post connect Pool size: 5 Connections in pool: 0 Current Overflow: 3 Current Checked out connections: 8
Epre setup Pool size: 5 Connections in pool: 0 Current Overflow: 3 Current Checked out connections: 8
post connect Pool size: 5 Connections in pool: 0 Current Overflow: 4 Current Checked out connections: 9
Epre setup Pool size: 5 Connections in pool: 0 Current Overflow: 4 Current Checked out connections: 9
post connect Pool size: 5 Connections in pool: 0 Current Overflow: 5 Current Checked out connections: 10
Epre setup Pool size: 5 Connections in pool: 0 Current Overflow: 5 Current Checked out connections: 10
post connect Pool size: 5 Connections in pool: 0 Current Overflow: 6 Current Checked out connections: 11
Epre setup Pool size: 5 Connections in pool: 0 Current Overflow: 6 Current Checked out connections: 11
post connect Pool size: 5 Connections in pool: 0 Current Overflow: 7 Current Checked out connections: 12
Epre setup Pool size: 5 Connections in pool: 0 Current Overflow: 7 Current Checked out connections: 12
post connect Pool size: 5 Connections in pool: 0 Current Overflow: 8 Current Checked out connections: 13
Epre setup Pool size: 5 Connections in pool: 0 Current Overflow: 8 Current Checked out connections: 13
post connect Pool size: 5 Connections in pool: 0 Current Overflow: 9 Current Checked out connections: 14
Epre setup Pool size: 5 Connections in pool: 0 Current Overflow: 9 Current Checked out connections: 14
post connect Pool size: 5 Connections in pool: 0 Current Overflow: 10 Current Checked out connections: 15
post teardown 0 Pool size: 5 Connections in pool: 0 Current Overflow: 10 Current Checked out connections: 15
post teardown 1 Pool size: 5 Connections in pool: 0 Current Overflow: 10 Current Checked out connections: 15
post teardown 2 Pool size: 5 Connections in pool: 0 Current Overflow: 10 Current Checked out connections: 15
post teardown 3 Pool size: 5 Connections in pool: 1 Current Overflow: 10 Current Checked out connections: 14
.pre setup Pool size: 5 Connections in pool: 1 Current Overflow: 10 Current Checked out connections: 14
post connect Pool size: 5 Connections in pool: 0 Current Overflow: 10 Current Checked out connections: 15
Epost teardown 0 Pool size: 5 Connections in pool: 0 Current Overflow: 10 Current Checked out connections: 15
post teardown 1 Pool size: 5 Connections in pool: 0 Current Overflow: 10 Current Checked out connections: 15
post teardown 2 Pool size: 5 Connections in pool: 0 Current Overflow: 10 Current Checked out connections: 15
post teardown 3 Pool size: 5 Connections in pool: 1 Current Overflow: 10 Current Checked out connections: 14
Additional details:
For the sake of this question, I wrote a very small reproducible example. Unfortunately that one did not exhibit this behaviour:
class MyTest(TestCase):
"""
Example test case meant to demonstrate that ``tearDown`` is not called.
It turns out, in this case, ``tearDown`` *is* called as expected!
"""
def setUp(self):
print "setup"
def tearDown(self):
print "tearDown"
def test_failing(self):
print int('yes')
if __name__ == '__main__':
main()
So what makes this example different from my real-world code? Why is tearDown called in the simple example, but not in my production code?
I will continue to investigate...