mirror of
https://github.com/django/django.git
synced 2025-10-24 06:06:09 +00:00
Fixed #26688 -- Fixed HTTP request logging inconsistencies.
* Added logging of 500 responses for instantiated responses. * Added logging of all 4xx and 5xx responses.
This commit is contained in:
@@ -6,15 +6,18 @@ from admin_scripts.tests import AdminScriptTestCase
|
||||
|
||||
from django.conf import settings
|
||||
from django.core import mail
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.core.files.temp import NamedTemporaryFile
|
||||
from django.core.management import color
|
||||
from django.http.multipartparser import MultiPartParserError
|
||||
from django.test import RequestFactory, SimpleTestCase, override_settings
|
||||
from django.test.utils import LoggingCaptureMixin, patch_logger
|
||||
from django.test.utils import LoggingCaptureMixin
|
||||
from django.utils.log import (
|
||||
DEFAULT_LOGGING, AdminEmailHandler, CallbackFilter, RequireDebugFalse,
|
||||
RequireDebugTrue, ServerFormatter,
|
||||
)
|
||||
|
||||
from . import views
|
||||
from .logconfig import MyEmailBackend
|
||||
|
||||
# logging config prior to using filter with mail_admins
|
||||
@@ -106,16 +109,95 @@ class DefaultLoggingTests(SetupDefaultLoggingMixin, LoggingCaptureMixin, SimpleT
|
||||
self.assertEqual(self.logger_output.getvalue(), '')
|
||||
|
||||
|
||||
class LoggingAssertionMixin(object):
|
||||
|
||||
def assertLogsRequest(self, url, level, msg, status_code, logger='django.request', exc_class=None):
|
||||
with self.assertLogs(logger, level) as cm:
|
||||
try:
|
||||
self.client.get(url)
|
||||
except views.UncaughtException:
|
||||
pass
|
||||
self.assertEqual(
|
||||
len(cm.records), 1,
|
||||
"Wrong number of calls for logger %r in %r level." % (logger, level)
|
||||
)
|
||||
record = cm.records[0]
|
||||
self.assertEqual(record.getMessage(), msg)
|
||||
self.assertEqual(record.status_code, status_code)
|
||||
if exc_class:
|
||||
self.assertIsNotNone(record.exc_info)
|
||||
self.assertEqual(record.exc_info[0], exc_class)
|
||||
|
||||
|
||||
@override_settings(DEBUG=True, ROOT_URLCONF='logging_tests.urls')
|
||||
class HandlerLoggingTests(SetupDefaultLoggingMixin, LoggingCaptureMixin, SimpleTestCase):
|
||||
class HandlerLoggingTests(SetupDefaultLoggingMixin, LoggingAssertionMixin, LoggingCaptureMixin, SimpleTestCase):
|
||||
|
||||
def test_page_found_no_warning(self):
|
||||
self.client.get('/innocent/')
|
||||
self.assertEqual(self.logger_output.getvalue(), '')
|
||||
|
||||
def test_redirect_no_warning(self):
|
||||
self.client.get('/redirect/')
|
||||
self.assertEqual(self.logger_output.getvalue(), '')
|
||||
|
||||
def test_page_not_found_warning(self):
|
||||
self.client.get('/does_not_exist/')
|
||||
self.assertEqual(self.logger_output.getvalue(), 'Not Found: /does_not_exist/\n')
|
||||
self.assertLogsRequest(
|
||||
url='/does_not_exist/',
|
||||
level='WARNING',
|
||||
status_code=404,
|
||||
msg='Not Found: /does_not_exist/',
|
||||
)
|
||||
|
||||
def test_page_not_found_raised(self):
|
||||
self.assertLogsRequest(
|
||||
url='/does_not_exist_raised/',
|
||||
level='WARNING',
|
||||
status_code=404,
|
||||
msg='Not Found: /does_not_exist_raised/',
|
||||
)
|
||||
|
||||
def test_uncaught_exception(self):
|
||||
self.assertLogsRequest(
|
||||
url='/uncaught_exception/',
|
||||
level='ERROR',
|
||||
status_code=500,
|
||||
msg='Internal Server Error: /uncaught_exception/',
|
||||
exc_class=views.UncaughtException,
|
||||
)
|
||||
|
||||
def test_internal_server_error(self):
|
||||
self.assertLogsRequest(
|
||||
url='/internal_server_error/',
|
||||
level='ERROR',
|
||||
status_code=500,
|
||||
msg='Internal Server Error: /internal_server_error/',
|
||||
)
|
||||
|
||||
def test_internal_server_error_599(self):
|
||||
self.assertLogsRequest(
|
||||
url='/internal_server_error/?status=599',
|
||||
level='ERROR',
|
||||
status_code=599,
|
||||
msg='Unknown Status Code: /internal_server_error/',
|
||||
)
|
||||
|
||||
def test_permission_denied(self):
|
||||
self.assertLogsRequest(
|
||||
url='/permission_denied/',
|
||||
level='WARNING',
|
||||
status_code=403,
|
||||
msg='Forbidden (Permission denied): /permission_denied/',
|
||||
exc_class=PermissionDenied,
|
||||
)
|
||||
|
||||
def test_multi_part_parser_error(self):
|
||||
self.assertLogsRequest(
|
||||
url='/multi_part_parser_error/',
|
||||
level='WARNING',
|
||||
status_code=400,
|
||||
msg='Bad request (Unable to parse request body): /multi_part_parser_error/',
|
||||
exc_class=MultiPartParserError,
|
||||
)
|
||||
|
||||
|
||||
@override_settings(
|
||||
@@ -401,19 +483,25 @@ class SetupConfigureLogging(SimpleTestCase):
|
||||
|
||||
|
||||
@override_settings(DEBUG=True, ROOT_URLCONF='logging_tests.urls')
|
||||
class SecurityLoggerTest(SimpleTestCase):
|
||||
class SecurityLoggerTest(LoggingAssertionMixin, SimpleTestCase):
|
||||
|
||||
def test_suspicious_operation_creates_log_message(self):
|
||||
with patch_logger('django.security.SuspiciousOperation', 'error') as calls:
|
||||
self.client.get('/suspicious/')
|
||||
self.assertEqual(len(calls), 1)
|
||||
self.assertEqual(calls[0], 'dubious')
|
||||
self.assertLogsRequest(
|
||||
url='/suspicious/',
|
||||
level='ERROR',
|
||||
msg='dubious',
|
||||
status_code=400,
|
||||
logger='django.security.SuspiciousOperation',
|
||||
)
|
||||
|
||||
def test_suspicious_operation_uses_sublogger(self):
|
||||
with patch_logger('django.security.DisallowedHost', 'error') as calls:
|
||||
self.client.get('/suspicious_spec/')
|
||||
self.assertEqual(len(calls), 1)
|
||||
self.assertEqual(calls[0], 'dubious')
|
||||
self.assertLogsRequest(
|
||||
url='/suspicious_spec/',
|
||||
level='ERROR',
|
||||
msg='dubious',
|
||||
status_code=400,
|
||||
logger='django.security.DisallowedHost',
|
||||
)
|
||||
|
||||
@override_settings(
|
||||
ADMINS=[('admin', 'admin@example.com')],
|
||||
|
||||
Reference in New Issue
Block a user