mirror of
https://github.com/django/django.git
synced 2025-10-24 14:16:09 +00:00
[1.5.x] Fixed #19707 -- Reset transaction state after requests
Backpatch of a4e97cf315
This commit is contained in:
@@ -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
|
||||
@@ -536,8 +539,44 @@ class RequestsTests(unittest.TestCase):
|
||||
'CONTENT_LENGTH': len(payload),
|
||||
'wsgi.input': ExplodingBytesIO(payload)})
|
||||
|
||||
with warnings.catch_warnings(record=True) as w:
|
||||
warnings.simplefilter("always")
|
||||
with self.assertRaises(UnreadablePostError):
|
||||
request.raw_post_data
|
||||
self.assertEqual(len(w), 1)
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user