|
32 | 32 | from opentelemetry.test.test_base import TestBase
|
33 | 33 | from opentelemetry.test.wsgitestutil import WsgiTestBase
|
34 | 34 | from opentelemetry.trace import SpanKind
|
35 |
| -from opentelemetry.util.http import get_excluded_urls, get_traced_request_attrs |
| 35 | +from opentelemetry.util.http import ( |
| 36 | + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST, |
| 37 | + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE, |
| 38 | + get_excluded_urls, |
| 39 | + get_traced_request_attrs, |
| 40 | +) |
36 | 41 |
|
37 | 42 | from .tornado_test_app import (
|
38 | 43 | AsyncHandler,
|
@@ -604,3 +609,122 @@ def test_mark_span_internal_in_presence_of_another_span(self):
|
604 | 609 | self.assertEqual(
|
605 | 610 | test_span.context.span_id, tornado_handler_span.parent.span_id
|
606 | 611 | )
|
| 612 | + |
| 613 | + |
| 614 | +class TestTornadoCustomRequestResponseHeadersAddedWithServerSpan(TornadoTest): |
| 615 | + @patch.dict( |
| 616 | + "os.environ", |
| 617 | + { |
| 618 | + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3" |
| 619 | + }, |
| 620 | + ) |
| 621 | + def test_custom_request_headers_added_in_server_span(self): |
| 622 | + headers = { |
| 623 | + "Custom-Test-Header-1": "Test Value 1", |
| 624 | + "Custom-Test-Header-2": "TestValue2,TestValue3", |
| 625 | + } |
| 626 | + response = self.fetch("/", headers=headers) |
| 627 | + self.assertEqual(response.code, 201) |
| 628 | + _, tornado_span, _ = self.sorted_spans( |
| 629 | + self.memory_exporter.get_finished_spans() |
| 630 | + ) |
| 631 | + expected = { |
| 632 | + "http.request.header.custom_test_header_1": ("Test Value 1",), |
| 633 | + "http.request.header.custom_test_header_2": ( |
| 634 | + "TestValue2,TestValue3", |
| 635 | + ), |
| 636 | + } |
| 637 | + self.assertEqual(tornado_span.kind, trace.SpanKind.SERVER) |
| 638 | + self.assertSpanHasAttributes(tornado_span, expected) |
| 639 | + |
| 640 | + @patch.dict( |
| 641 | + "os.environ", |
| 642 | + { |
| 643 | + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE: "content-type,content-length,my-custom-header,invalid-header" |
| 644 | + }, |
| 645 | + ) |
| 646 | + def test_custom_response_headers_added_in_server_span(self): |
| 647 | + response = self.fetch("/test_custom_response_headers") |
| 648 | + self.assertEqual(response.code, 200) |
| 649 | + tornado_span, _ = self.sorted_spans( |
| 650 | + self.memory_exporter.get_finished_spans() |
| 651 | + ) |
| 652 | + expected = { |
| 653 | + "http.response.header.content_type": ( |
| 654 | + "text/plain; charset=utf-8", |
| 655 | + ), |
| 656 | + "http.response.header.content_length": ("0",), |
| 657 | + "http.response.header.my_custom_header": ( |
| 658 | + "my-custom-value-1,my-custom-header-2", |
| 659 | + ), |
| 660 | + } |
| 661 | + self.assertEqual(tornado_span.kind, trace.SpanKind.SERVER) |
| 662 | + self.assertSpanHasAttributes(tornado_span, expected) |
| 663 | + |
| 664 | + |
| 665 | +class TestTornadoCustomRequestResponseHeadersNotAddedWithInternalSpan( |
| 666 | + TornadoTest |
| 667 | +): |
| 668 | + def get_app(self): |
| 669 | + tracer = trace.get_tracer(__name__) |
| 670 | + app = make_app(tracer) |
| 671 | + |
| 672 | + def middleware(request): |
| 673 | + """Wraps the request with a server span""" |
| 674 | + with tracer.start_as_current_span( |
| 675 | + "test", kind=trace.SpanKind.SERVER |
| 676 | + ): |
| 677 | + app(request) |
| 678 | + |
| 679 | + return middleware |
| 680 | + |
| 681 | + @patch.dict( |
| 682 | + "os.environ", |
| 683 | + { |
| 684 | + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3" |
| 685 | + }, |
| 686 | + ) |
| 687 | + def test_custom_request_headers_not_added_in_internal_span(self): |
| 688 | + headers = { |
| 689 | + "Custom-Test-Header-1": "Test Value 1", |
| 690 | + "Custom-Test-Header-2": "TestValue2,TestValue3", |
| 691 | + } |
| 692 | + response = self.fetch("/", headers=headers) |
| 693 | + self.assertEqual(response.code, 201) |
| 694 | + _, tornado_span, _, _ = self.sorted_spans( |
| 695 | + self.memory_exporter.get_finished_spans() |
| 696 | + ) |
| 697 | + not_expected = { |
| 698 | + "http.request.header.custom_test_header_1": ("Test Value 1",), |
| 699 | + "http.request.header.custom_test_header_2": ( |
| 700 | + "TestValue2,TestValue3", |
| 701 | + ), |
| 702 | + } |
| 703 | + self.assertEqual(tornado_span.kind, trace.SpanKind.INTERNAL) |
| 704 | + for key, _ in not_expected.items(): |
| 705 | + self.assertNotIn(key, tornado_span.attributes) |
| 706 | + |
| 707 | + @patch.dict( |
| 708 | + "os.environ", |
| 709 | + { |
| 710 | + OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE: "content-type,content-length,my-custom-header,invalid-header" |
| 711 | + }, |
| 712 | + ) |
| 713 | + def test_custom_response_headers_not_added_in_internal_span(self): |
| 714 | + response = self.fetch("/test_custom_response_headers") |
| 715 | + self.assertEqual(response.code, 200) |
| 716 | + tornado_span, _, _ = self.sorted_spans( |
| 717 | + self.memory_exporter.get_finished_spans() |
| 718 | + ) |
| 719 | + not_expected = { |
| 720 | + "http.response.header.content_type": ( |
| 721 | + "text/plain; charset=utf-8", |
| 722 | + ), |
| 723 | + "http.response.header.content_length": ("0",), |
| 724 | + "http.response.header.my_custom_header": ( |
| 725 | + "my-custom-value-1,my-custom-header-2", |
| 726 | + ), |
| 727 | + } |
| 728 | + self.assertEqual(tornado_span.kind, trace.SpanKind.INTERNAL) |
| 729 | + for key, _ in not_expected.items(): |
| 730 | + self.assertNotIn(key, tornado_span.attributes) |
0 commit comments