|
26 | 26 | DjangoInstrumentor,
|
27 | 27 | _DjangoMiddleware,
|
28 | 28 | )
|
| 29 | +from opentelemetry.instrumentation.propagators import ( |
| 30 | + TraceResponsePropagator, |
| 31 | + set_global_back_propagator, |
| 32 | +) |
29 | 33 | from opentelemetry.sdk.trace import Span
|
30 | 34 | from opentelemetry.test.test_base import TestBase
|
31 | 35 | from opentelemetry.test.wsgitestutil import WsgiTestBase
|
32 |
| -from opentelemetry.trace import SpanKind, StatusCode |
| 36 | +from opentelemetry.trace import ( |
| 37 | + SpanKind, |
| 38 | + StatusCode, |
| 39 | + format_span_id, |
| 40 | + format_trace_id, |
| 41 | +) |
33 | 42 | from opentelemetry.util.http import get_excluded_urls, get_traced_request_attrs
|
34 | 43 |
|
35 | 44 | # pylint: disable=import-error
|
|
41 | 50 | route_span_name,
|
42 | 51 | traced,
|
43 | 52 | traced_template,
|
| 53 | + with_response_header, |
44 | 54 | )
|
45 | 55 |
|
46 | 56 | DJANGO_2_2 = VERSION >= (2, 2)
|
|
52 | 62 | url(r"^excluded_arg/", excluded),
|
53 | 63 | url(r"^excluded_noarg/", excluded_noarg),
|
54 | 64 | url(r"^excluded_noarg2/", excluded_noarg2),
|
| 65 | + url(r"^response_header/", with_response_header), |
55 | 66 | url(r"^span_name/([0-9]{4})/$", route_span_name),
|
56 | 67 | ]
|
57 | 68 | _django_instrumentor = DjangoInstrumentor()
|
@@ -309,3 +320,55 @@ def response_hook(span, request, response):
|
309 | 320 | self.assertIsInstance(response_hook_args[1], HttpRequest)
|
310 | 321 | self.assertIsInstance(response_hook_args[2], HttpResponse)
|
311 | 322 | self.assertEqual(response_hook_args[2], response)
|
| 323 | + |
| 324 | + def test_trace_response_headers(self): |
| 325 | + response = Client().get("/span_name/1234/") |
| 326 | + self.assertNotIn("Server-Timing", response._headers) |
| 327 | + self.memory_exporter.clear() |
| 328 | + |
| 329 | + set_global_back_propagator(TraceResponsePropagator()) |
| 330 | + |
| 331 | + response = Client().get("/span_name/1234/") |
| 332 | + span = self.memory_exporter.get_finished_spans()[0] |
| 333 | + |
| 334 | + self.assertIn("traceresponse", response._headers) |
| 335 | + self.assertEqual( |
| 336 | + response._headers["access-control-expose-headers"][0], |
| 337 | + "Access-Control-Expose-Headers", |
| 338 | + ) |
| 339 | + self.assertEqual( |
| 340 | + response._headers["access-control-expose-headers"][1], |
| 341 | + "traceresponse", |
| 342 | + ) |
| 343 | + self.assertEqual( |
| 344 | + response._headers["traceresponse"][0], "traceresponse" |
| 345 | + ) |
| 346 | + self.assertEqual( |
| 347 | + response._headers["traceresponse"][1], |
| 348 | + "00-{0}-{1}-01".format( |
| 349 | + format_trace_id(span.get_span_context().trace_id), |
| 350 | + format_span_id(span.get_span_context().span_id), |
| 351 | + ), |
| 352 | + ) |
| 353 | + self.memory_exporter.clear() |
| 354 | + |
| 355 | + def test_trace_response_header_pre_existing_header(self): |
| 356 | + set_global_back_propagator(TraceResponsePropagator()) |
| 357 | + |
| 358 | + response = Client().get("/response_header/") |
| 359 | + span = self.memory_exporter.get_finished_spans()[0] |
| 360 | + self.assertIn("traceresponse", response._headers) |
| 361 | + self.assertEqual( |
| 362 | + response._headers["access-control-expose-headers"][1], |
| 363 | + "X-Test-Header, traceresponse", |
| 364 | + ) |
| 365 | + self.assertEqual( |
| 366 | + response._headers["traceresponse"][1], |
| 367 | + "abc; val=1, " |
| 368 | + + "00-{0}-{1}-01".format( |
| 369 | + format_trace_id(span.get_span_context().trace_id), |
| 370 | + format_span_id(span.get_span_context().span_id), |
| 371 | + ), |
| 372 | + ) |
| 373 | + |
| 374 | + self.memory_exporter.clear() |
0 commit comments