diff options
| author | Anssi Kääriäinen <akaariai@gmail.com> | 2013-02-05 23:52:29 +0200 |
|---|---|---|
| committer | Anssi Kääriäinen <akaariai@gmail.com> | 2013-02-10 17:34:38 +0200 |
| commit | 9918b3f50212bfb408eebc8f9965beb061baf840 (patch) | |
| tree | 2318cf4b8020dfd571a4bfae3ed9d3a3637575ec /tests | |
| parent | 498a5de07bd325628c9bd7a804144a9f714ca721 (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.py | 22 | ||||
| -rw-r--r-- | tests/regressiontests/requests/tests.py | 35 |
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) |
