From a4e97cf315142e61bb4bc3ed8259b95d8586d09c Mon Sep 17 00:00:00 2001 From: Anssi Kääriäinen Date: Tue, 5 Feb 2013 23:52:29 +0200 Subject: Fixed #19707 -- Reset transaction state after requests --- tests/regressiontests/requests/tests.py | 42 +++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'tests/regressiontests/requests/tests.py') diff --git a/tests/regressiontests/requests/tests.py b/tests/regressiontests/requests/tests.py index 799cd9b302..d89f6d68be 100644 --- a/tests/regressiontests/requests/tests.py +++ b/tests/regressiontests/requests/tests.py @@ -6,9 +6,12 @@ import warnings from datetime import datetime, timedelta from io import BytesIO +from django.db import connection, connections, DEFAULT_DB_ALIAS +from django.core import signals from django.core.exceptions import SuspiciousOperation from django.core.handlers.wsgi import WSGIRequest, LimitedStream from django.http import HttpRequest, HttpResponse, parse_cookie, build_request_repr, UnreadablePostError +from django.test import TransactionTestCase from django.test.client import FakePayload from django.test.utils import override_settings, str_prefix from django.utils import six @@ -524,3 +527,42 @@ class RequestsTests(unittest.TestCase): with self.assertRaises(UnreadablePostError): request.body + +class TransactionRequestTests(TransactionTestCase): + def test_request_finished_db_state(self): + # The GET below will not succeed, but it will give a response with + # defined ._handler_class. That is needed for sending the + # request_finished signal. + response = self.client.get('/') + # Make sure there is an open connection + connection.cursor() + connection.enter_transaction_management() + connection.managed(True) + signals.request_finished.send(sender=response._handler_class) + # In-memory sqlite doesn't actually close connections. + if connection.vendor != 'sqlite': + self.assertIs(connection.connection, None) + self.assertEqual(len(connection.transaction_state), 0) + + @unittest.skipIf(connection.vendor == 'sqlite', + 'This test will close the connection, in-memory ' + 'sqlite connections must not be closed.') + def test_request_finished_failed_connection(self): + # See comments in test_request_finished_db_state() for the self.client + # usage. + response = self.client.get('/') + conn = connections[DEFAULT_DB_ALIAS] + conn.enter_transaction_management() + conn.managed(True) + conn.set_dirty() + # Test that the rollback doesn't succeed (for example network failure + # could cause this). + def fail_horribly(): + raise Exception("Horrible failure!") + conn._rollback = fail_horribly + signals.request_finished.send(sender=response._handler_class) + # As even rollback wasn't possible the connection wrapper itself was + # abandoned. Accessing the connections[alias] will create a new + # connection wrapper, whch must be different than the original one. + self.assertIsNot(conn, connections[DEFAULT_DB_ALIAS]) + self.assertEqual(len(connection.transaction_state), 0) -- cgit v1.3