|
15 | 15 | # pylint: disable=E0611 |
16 | 16 | # pylint: disable=too-many-lines |
17 | 17 |
|
| 18 | +import logging |
18 | 19 | from sys import modules |
19 | 20 | from timeit import default_timer |
| 21 | +from unittest import TestCase |
20 | 22 | from unittest.mock import Mock, patch |
21 | 23 |
|
22 | 24 | from django import VERSION, conf |
23 | | -from django.core.handlers.wsgi import WSGIRequest |
24 | 25 | from django.http import HttpRequest, HttpResponse |
25 | 26 | from django.test.client import Client |
26 | 27 | from django.test.utils import setup_test_environment, teardown_test_environment |
|
36 | 37 | DjangoInstrumentor, |
37 | 38 | _DjangoMiddleware, |
38 | 39 | ) |
| 40 | +from opentelemetry.instrumentation.django.middleware.otel_middleware import ( |
| 41 | + RequestFilter, |
| 42 | +) |
39 | 43 | from opentelemetry.instrumentation.propagators import ( |
40 | 44 | TraceResponsePropagator, |
41 | 45 | set_global_response_propagator, |
@@ -101,6 +105,53 @@ def path(path_argument, *args, **kwargs): |
101 | 105 | _django_instrumentor = DjangoInstrumentor() |
102 | 106 |
|
103 | 107 |
|
| 108 | +# pylint: disable=too-many-public-methods |
| 109 | +class TestRequestFilter(TestCase): |
| 110 | + def test_converts_http_request_to_string(self): |
| 111 | + class DummyRequest: |
| 112 | + def __str__(self): |
| 113 | + return "<DummyRequest method=GET path=/example/>" |
| 114 | + |
| 115 | + request = DummyRequest() |
| 116 | + |
| 117 | + record = logging.LogRecord( |
| 118 | + name="django.request", |
| 119 | + level=logging.ERROR, |
| 120 | + pathname=__file__, |
| 121 | + lineno=0, |
| 122 | + msg="test message", |
| 123 | + args=(), |
| 124 | + exc_info=None, |
| 125 | + ) |
| 126 | + record.request = request |
| 127 | + |
| 128 | + expected_repr = str(request) |
| 129 | + |
| 130 | + request_filter = RequestFilter() |
| 131 | + result = request_filter.filter(record) |
| 132 | + |
| 133 | + self.assertTrue(result) |
| 134 | + self.assertEqual(record.request, expected_repr) |
| 135 | + self.assertIsInstance(record.request, str) |
| 136 | + |
| 137 | + def test_handles_missing_request_attribute(self): |
| 138 | + record = logging.LogRecord( |
| 139 | + name="django.request", |
| 140 | + level=logging.INFO, |
| 141 | + pathname=__file__, |
| 142 | + lineno=0, |
| 143 | + msg="no request", |
| 144 | + args=(), |
| 145 | + exc_info=None, |
| 146 | + ) |
| 147 | + |
| 148 | + request_filter = RequestFilter() |
| 149 | + result = request_filter.filter(record) |
| 150 | + |
| 151 | + self.assertTrue(result) |
| 152 | + self.assertEqual(record.request, "None") |
| 153 | + |
| 154 | + |
104 | 155 | # pylint: disable=too-many-public-methods |
105 | 156 | class TestMiddleware(WsgiTestBase): |
106 | 157 | @classmethod |
@@ -1020,102 +1071,6 @@ def tearDownClass(cls): |
1020 | 1071 | super().tearDownClass() |
1021 | 1072 | conf.settings = conf.LazySettings() |
1022 | 1073 |
|
1023 | | - def test_wsgi_request_in_header_is_properly_formatted(self): |
1024 | | - mock_wsgi_request = Mock(spec=WSGIRequest) |
1025 | | - mock_wsgi_request.method = "GET" |
1026 | | - mock_wsgi_request.path = "/test/path" |
1027 | | - mock_wsgi_request.__class__.__name__ = "WSGIRequest" |
1028 | | - |
1029 | | - input_attributes = { |
1030 | | - "http.request.header.test_wsgirequest_header": [mock_wsgi_request] |
1031 | | - } |
1032 | | - expected_attributes = { |
1033 | | - "http.request.header.test_wsgirequest_header": [ |
1034 | | - str(mock_wsgi_request) |
1035 | | - ] |
1036 | | - } |
1037 | | - |
1038 | | - formatted_attributes = ( |
1039 | | - _DjangoMiddleware.format_request_objects_in_headers( |
1040 | | - input_attributes |
1041 | | - ) |
1042 | | - ) |
1043 | | - |
1044 | | - self.assertEqual(formatted_attributes, expected_attributes) |
1045 | | - |
1046 | | - def test_wsgi_request_handles_extraction_error(self): |
1047 | | - mock_wsgi_request = Mock(spec=WSGIRequest) |
1048 | | - mock_wsgi_request.__class__.__name__ = "WSGIRequest" |
1049 | | - |
1050 | | - type(mock_wsgi_request).method = property( |
1051 | | - lambda self: (_ for _ in ()).throw(ValueError("Test error")) |
1052 | | - ) |
1053 | | - |
1054 | | - input_attributes = { |
1055 | | - "http.request.header.test_wsgirequest_header": [mock_wsgi_request] |
1056 | | - } |
1057 | | - expected_attributes = { |
1058 | | - "http.request.header.test_wsgirequest_header": [ |
1059 | | - str(mock_wsgi_request) |
1060 | | - ] |
1061 | | - } |
1062 | | - |
1063 | | - formatted_attributes = ( |
1064 | | - _DjangoMiddleware.format_request_objects_in_headers( |
1065 | | - input_attributes |
1066 | | - ) |
1067 | | - ) |
1068 | | - |
1069 | | - self.assertEqual(formatted_attributes, expected_attributes) |
1070 | | - |
1071 | | - def test_handles_http_request_as_well(self): |
1072 | | - mock_http_request = Mock(spec=HttpRequest) |
1073 | | - mock_http_request.method = "POST" |
1074 | | - mock_http_request.path = "/api/data" |
1075 | | - mock_http_request.__class__.__name__ = "HttpRequest" |
1076 | | - |
1077 | | - input_attributes = { |
1078 | | - "http.request.header.test_httprequest_header": [mock_http_request] |
1079 | | - } |
1080 | | - expected_attributes = { |
1081 | | - "http.request.header.test_httprequest_header": [ |
1082 | | - str(mock_http_request) |
1083 | | - ] |
1084 | | - } |
1085 | | - |
1086 | | - formatted_attributes = ( |
1087 | | - _DjangoMiddleware.format_request_objects_in_headers( |
1088 | | - input_attributes |
1089 | | - ) |
1090 | | - ) |
1091 | | - |
1092 | | - self.assertEqual(formatted_attributes, expected_attributes) |
1093 | | - |
1094 | | - def test_regular_header_values_are_preserved(self): |
1095 | | - mock_wsgi_request = Mock(spec=WSGIRequest) |
1096 | | - mock_wsgi_request.method = "GET" |
1097 | | - mock_wsgi_request.path = "/test/path" |
1098 | | - mock_wsgi_request.__class__.__name__ = "WSGIRequest" |
1099 | | - |
1100 | | - input_attributes = { |
1101 | | - "http.request.header.test_wsgirequest_header": [mock_wsgi_request], |
1102 | | - "http.request.header.test_regular_header": ["regular-value"], |
1103 | | - } |
1104 | | - expected_attributes = { |
1105 | | - "http.request.header.test_wsgirequest_header": [ |
1106 | | - str(mock_wsgi_request) |
1107 | | - ], |
1108 | | - "http.request.header.test_regular_header": ["regular-value"], |
1109 | | - } |
1110 | | - |
1111 | | - formatted_attributes = ( |
1112 | | - _DjangoMiddleware.format_request_objects_in_headers( |
1113 | | - input_attributes |
1114 | | - ) |
1115 | | - ) |
1116 | | - |
1117 | | - self.assertEqual(formatted_attributes, expected_attributes) |
1118 | | - |
1119 | 1074 | def test_http_custom_request_headers_in_span_attributes(self): |
1120 | 1075 | expected = { |
1121 | 1076 | "http.request.header.custom_test_header_1": ( |
|
0 commit comments