summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorAnssi Kääriäinen <akaariai@gmail.com>2013-02-05 23:52:29 +0200
committerAnssi Kääriäinen <akaariai@gmail.com>2013-02-10 17:34:38 +0200
commit9918b3f50212bfb408eebc8f9965beb061baf840 (patch)
tree2318cf4b8020dfd571a4bfae3ed9d3a3637575ec /tests
parent498a5de07bd325628c9bd7a804144a9f714ca721 (diff)
[1.4.x] Fixed #19707 -- Reset transaction state after requests
Backpatch of a4e97cf315142e61bb4bc3ed8259b95d8586d09c.
Diffstat (limited to 'tests')
-rw-r--r--tests/regressiontests/middleware/tests.py22
-rw-r--r--tests/regressiontests/requests/tests.py35
2 files changed, 56 insertions, 1 deletions
diff --git a/tests/regressiontests/middleware/tests.py b/tests/regressiontests/middleware/tests.py
index 00e4e3ecc1..138ee50e43 100644
--- a/tests/regressiontests/middleware/tests.py
+++ b/tests/regressiontests/middleware/tests.py
@@ -8,7 +8,8 @@ import StringIO
from django.conf import settings
from django.core import mail
-from django.db import transaction
+from django.db import (transaction, connections, DEFAULT_DB_ALIAS,
+ IntegrityError)
from django.http import HttpRequest
from django.http import HttpResponse
from django.middleware.clickjacking import XFrameOptionsMiddleware
@@ -660,3 +661,22 @@ class TransactionMiddlewareTest(TransactionTestCase):
TransactionMiddleware().process_exception(self.request, None)
self.assertEqual(Band.objects.count(), 0)
self.assertFalse(transaction.is_dirty())
+
+ def test_failing_commit(self):
+ # It is possible that connection.commit() fails. Check that
+ # TransactionMiddleware handles such cases correctly.
+ try:
+ def raise_exception():
+ raise IntegrityError()
+ connections[DEFAULT_DB_ALIAS].commit = raise_exception
+ transaction.enter_transaction_management()
+ transaction.managed(True)
+ Band.objects.create(name='The Beatles')
+ self.assertTrue(transaction.is_dirty())
+ with self.assertRaises(IntegrityError):
+ TransactionMiddleware().process_response(self.request, None)
+ self.assertEqual(Band.objects.count(), 0)
+ self.assertFalse(transaction.is_dirty())
+ self.assertFalse(transaction.is_managed())
+ finally:
+ del connections[DEFAULT_DB_ALIAS].commit
diff --git a/tests/regressiontests/requests/tests.py b/tests/regressiontests/requests/tests.py
index caa25aea21..aba0461c79 100644
--- a/tests/regressiontests/requests/tests.py
+++ b/tests/regressiontests/requests/tests.py
@@ -6,11 +6,14 @@ import warnings
from datetime import datetime, timedelta
from StringIO import StringIO
+from django.db import connection, connections, DEFAULT_DB_ALIAS
+from django.core import signals
from django.conf import settings
from django.core.handlers.modpython import ModPythonRequest
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.utils import get_warnings_state, restore_warnings_state
from django.utils import unittest
from django.utils.http import cookie_date
@@ -530,3 +533,35 @@ class RequestsTests(unittest.TestCase):
with self.assertRaises(UnreadablePostError):
request.raw_post_data
+
+class TransactionRequestTests(TransactionTestCase):
+ def test_request_finished_db_state(self):
+ # Make sure there is an open connection
+ connection.cursor()
+ connection.enter_transaction_management()
+ connection.managed(True)
+ signals.request_finished.send(sender=self.__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):
+ 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=self.__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)