Skip to content

Commit ffe44f8

Browse files
committed
split fastapi instrumentation tests, to prevent pylint to complain (too-many-lines)
1 parent e955c20 commit ffe44f8

File tree

2 files changed

+357
-349
lines changed

2 files changed

+357
-349
lines changed

Diff for: instrumentation/opentelemetry-instrumentation-fastapi/tests/test_fastapi_instrumentation.py

-349
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,12 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14-
# pylint: disable=too-many-lines
15-
1614
import unittest
1715
from timeit import default_timer
1816
from unittest.mock import patch
1917

2018
import fastapi
2119
from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
22-
from fastapi.responses import JSONResponse
2320
from fastapi.testclient import TestClient
2421

2522
import opentelemetry.instrumentation.fastapi as otel_fastapi
@@ -31,12 +28,8 @@
3128
)
3229
from opentelemetry.sdk.resources import Resource
3330
from opentelemetry.semconv.trace import SpanAttributes
34-
from opentelemetry.test.globals_test import reset_trace_globals
3531
from opentelemetry.test.test_base import TestBase
3632
from opentelemetry.util.http import (
37-
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS,
38-
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST,
39-
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE,
4033
_active_requests_count_attrs,
4134
_duration_attrs,
4235
get_excluded_urls,
@@ -701,345 +694,3 @@ def test_mark_span_internal_in_presence_of_span_from_other_framework(self):
701694
self.assertEqual(
702695
parent_span.context.span_id, span_list[3].context.span_id
703696
)
704-
705-
706-
@patch.dict(
707-
"os.environ",
708-
{
709-
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS: ".*my-secret.*",
710-
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,Regex-Test-Header-.*,Regex-Invalid-Test-Header-.*,.*my-secret.*",
711-
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,my-custom-regex-header-.*,invalid-regex-header-.*,.*my-secret.*",
712-
},
713-
)
714-
class TestHTTPAppWithCustomHeaders(TestBase):
715-
def setUp(self):
716-
super().setUp()
717-
self.app = self._create_app()
718-
otel_fastapi.FastAPIInstrumentor().instrument_app(self.app)
719-
self.client = TestClient(self.app)
720-
721-
def tearDown(self) -> None:
722-
super().tearDown()
723-
with self.disable_logging():
724-
otel_fastapi.FastAPIInstrumentor().uninstrument_app(self.app)
725-
726-
@staticmethod
727-
def _create_app():
728-
app = fastapi.FastAPI()
729-
730-
@app.get("/foobar")
731-
async def _():
732-
headers = {
733-
"custom-test-header-1": "test-header-value-1",
734-
"custom-test-header-2": "test-header-value-2",
735-
"my-custom-regex-header-1": "my-custom-regex-value-1,my-custom-regex-value-2",
736-
"My-Custom-Regex-Header-2": "my-custom-regex-value-3,my-custom-regex-value-4",
737-
"My-Secret-Header": "My Secret Value",
738-
}
739-
content = {"message": "hello world"}
740-
return JSONResponse(content=content, headers=headers)
741-
742-
return app
743-
744-
def test_http_custom_request_headers_in_span_attributes(self):
745-
expected = {
746-
"http.request.header.custom_test_header_1": (
747-
"test-header-value-1",
748-
),
749-
"http.request.header.custom_test_header_2": (
750-
"test-header-value-2",
751-
),
752-
"http.request.header.regex_test_header_1": ("Regex Test Value 1",),
753-
"http.request.header.regex_test_header_2": (
754-
"RegexTestValue2,RegexTestValue3",
755-
),
756-
"http.request.header.my_secret_header": ("[REDACTED]",),
757-
}
758-
resp = self.client.get(
759-
"/foobar",
760-
headers={
761-
"custom-test-header-1": "test-header-value-1",
762-
"custom-test-header-2": "test-header-value-2",
763-
"Regex-Test-Header-1": "Regex Test Value 1",
764-
"regex-test-header-2": "RegexTestValue2,RegexTestValue3",
765-
"My-Secret-Header": "My Secret Value",
766-
},
767-
)
768-
self.assertEqual(200, resp.status_code)
769-
span_list = self.memory_exporter.get_finished_spans()
770-
self.assertEqual(len(span_list), 3)
771-
772-
server_span = [
773-
span for span in span_list if span.kind == trace.SpanKind.SERVER
774-
][0]
775-
776-
self.assertSpanHasAttributes(server_span, expected)
777-
778-
def test_http_custom_request_headers_not_in_span_attributes(self):
779-
not_expected = {
780-
"http.request.header.custom_test_header_3": (
781-
"test-header-value-3",
782-
),
783-
}
784-
resp = self.client.get(
785-
"/foobar",
786-
headers={
787-
"custom-test-header-1": "test-header-value-1",
788-
"custom-test-header-2": "test-header-value-2",
789-
"Regex-Test-Header-1": "Regex Test Value 1",
790-
"regex-test-header-2": "RegexTestValue2,RegexTestValue3",
791-
"My-Secret-Header": "My Secret Value",
792-
},
793-
)
794-
self.assertEqual(200, resp.status_code)
795-
span_list = self.memory_exporter.get_finished_spans()
796-
self.assertEqual(len(span_list), 3)
797-
798-
server_span = [
799-
span for span in span_list if span.kind == trace.SpanKind.SERVER
800-
][0]
801-
802-
for key, _ in not_expected.items():
803-
self.assertNotIn(key, server_span.attributes)
804-
805-
def test_http_custom_response_headers_in_span_attributes(self):
806-
expected = {
807-
"http.response.header.custom_test_header_1": (
808-
"test-header-value-1",
809-
),
810-
"http.response.header.custom_test_header_2": (
811-
"test-header-value-2",
812-
),
813-
"http.response.header.my_custom_regex_header_1": (
814-
"my-custom-regex-value-1,my-custom-regex-value-2",
815-
),
816-
"http.response.header.my_custom_regex_header_2": (
817-
"my-custom-regex-value-3,my-custom-regex-value-4",
818-
),
819-
"http.response.header.my_secret_header": ("[REDACTED]",),
820-
}
821-
resp = self.client.get("/foobar")
822-
self.assertEqual(200, resp.status_code)
823-
span_list = self.memory_exporter.get_finished_spans()
824-
self.assertEqual(len(span_list), 3)
825-
826-
server_span = [
827-
span for span in span_list if span.kind == trace.SpanKind.SERVER
828-
][0]
829-
self.assertSpanHasAttributes(server_span, expected)
830-
831-
def test_http_custom_response_headers_not_in_span_attributes(self):
832-
not_expected = {
833-
"http.response.header.custom_test_header_3": (
834-
"test-header-value-3",
835-
),
836-
}
837-
resp = self.client.get("/foobar")
838-
self.assertEqual(200, resp.status_code)
839-
span_list = self.memory_exporter.get_finished_spans()
840-
self.assertEqual(len(span_list), 3)
841-
842-
server_span = [
843-
span for span in span_list if span.kind == trace.SpanKind.SERVER
844-
][0]
845-
846-
for key, _ in not_expected.items():
847-
self.assertNotIn(key, server_span.attributes)
848-
849-
850-
@patch.dict(
851-
"os.environ",
852-
{
853-
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS: ".*my-secret.*",
854-
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,Regex-Test-Header-.*,Regex-Invalid-Test-Header-.*,.*my-secret.*",
855-
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_RESPONSE: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,my-custom-regex-header-.*,invalid-regex-header-.*,.*my-secret.*",
856-
},
857-
)
858-
class TestWebSocketAppWithCustomHeaders(TestBase):
859-
def setUp(self):
860-
super().setUp()
861-
self.app = self._create_app()
862-
otel_fastapi.FastAPIInstrumentor().instrument_app(self.app)
863-
self.client = TestClient(self.app)
864-
865-
def tearDown(self) -> None:
866-
super().tearDown()
867-
with self.disable_logging():
868-
otel_fastapi.FastAPIInstrumentor().uninstrument_app(self.app)
869-
870-
@staticmethod
871-
def _create_app():
872-
app = fastapi.FastAPI()
873-
874-
@app.websocket("/foobar_web")
875-
async def _(websocket: fastapi.WebSocket):
876-
message = await websocket.receive()
877-
if message.get("type") == "websocket.connect":
878-
await websocket.send(
879-
{
880-
"type": "websocket.accept",
881-
"headers": [
882-
(b"custom-test-header-1", b"test-header-value-1"),
883-
(b"custom-test-header-2", b"test-header-value-2"),
884-
(b"Regex-Test-Header-1", b"Regex Test Value 1"),
885-
(
886-
b"regex-test-header-2",
887-
b"RegexTestValue2,RegexTestValue3",
888-
),
889-
(b"My-Secret-Header", b"My Secret Value"),
890-
],
891-
}
892-
)
893-
await websocket.send_json({"message": "hello world"})
894-
await websocket.close()
895-
if message.get("type") == "websocket.disconnect":
896-
pass
897-
898-
return app
899-
900-
def test_web_socket_custom_request_headers_in_span_attributes(self):
901-
expected = {
902-
"http.request.header.custom_test_header_1": (
903-
"test-header-value-1",
904-
),
905-
"http.request.header.custom_test_header_2": (
906-
"test-header-value-2",
907-
),
908-
}
909-
910-
with self.client.websocket_connect(
911-
"/foobar_web",
912-
headers={
913-
"custom-test-header-1": "test-header-value-1",
914-
"custom-test-header-2": "test-header-value-2",
915-
},
916-
) as websocket:
917-
data = websocket.receive_json()
918-
self.assertEqual(data, {"message": "hello world"})
919-
920-
span_list = self.memory_exporter.get_finished_spans()
921-
self.assertEqual(len(span_list), 5)
922-
923-
server_span = [
924-
span for span in span_list if span.kind == trace.SpanKind.SERVER
925-
][0]
926-
927-
self.assertSpanHasAttributes(server_span, expected)
928-
929-
@patch.dict(
930-
"os.environ",
931-
{
932-
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS: ".*my-secret.*",
933-
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3,Regex-Test-Header-.*,Regex-Invalid-Test-Header-.*,.*my-secret.*",
934-
},
935-
)
936-
def test_web_socket_custom_request_headers_not_in_span_attributes(self):
937-
not_expected = {
938-
"http.request.header.custom_test_header_3": (
939-
"test-header-value-3",
940-
),
941-
}
942-
943-
with self.client.websocket_connect(
944-
"/foobar_web",
945-
headers={
946-
"custom-test-header-1": "test-header-value-1",
947-
"custom-test-header-2": "test-header-value-2",
948-
},
949-
) as websocket:
950-
data = websocket.receive_json()
951-
self.assertEqual(data, {"message": "hello world"})
952-
953-
span_list = self.memory_exporter.get_finished_spans()
954-
self.assertEqual(len(span_list), 5)
955-
956-
server_span = [
957-
span for span in span_list if span.kind == trace.SpanKind.SERVER
958-
][0]
959-
960-
for key, _ in not_expected.items():
961-
self.assertNotIn(key, server_span.attributes)
962-
963-
def test_web_socket_custom_response_headers_in_span_attributes(self):
964-
expected = {
965-
"http.response.header.custom_test_header_1": (
966-
"test-header-value-1",
967-
),
968-
"http.response.header.custom_test_header_2": (
969-
"test-header-value-2",
970-
),
971-
}
972-
973-
with self.client.websocket_connect("/foobar_web") as websocket:
974-
data = websocket.receive_json()
975-
self.assertEqual(data, {"message": "hello world"})
976-
977-
span_list = self.memory_exporter.get_finished_spans()
978-
self.assertEqual(len(span_list), 5)
979-
980-
server_span = [
981-
span for span in span_list if span.kind == trace.SpanKind.SERVER
982-
][0]
983-
984-
self.assertSpanHasAttributes(server_span, expected)
985-
986-
def test_web_socket_custom_response_headers_not_in_span_attributes(self):
987-
not_expected = {
988-
"http.response.header.custom_test_header_3": (
989-
"test-header-value-3",
990-
),
991-
}
992-
993-
with self.client.websocket_connect("/foobar_web") as websocket:
994-
data = websocket.receive_json()
995-
self.assertEqual(data, {"message": "hello world"})
996-
997-
span_list = self.memory_exporter.get_finished_spans()
998-
self.assertEqual(len(span_list), 5)
999-
1000-
server_span = [
1001-
span for span in span_list if span.kind == trace.SpanKind.SERVER
1002-
][0]
1003-
1004-
for key, _ in not_expected.items():
1005-
self.assertNotIn(key, server_span.attributes)
1006-
1007-
1008-
@patch.dict(
1009-
"os.environ",
1010-
{
1011-
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SERVER_REQUEST: "Custom-Test-Header-1,Custom-Test-Header-2,Custom-Test-Header-3",
1012-
},
1013-
)
1014-
class TestNonRecordingSpanWithCustomHeaders(TestBase):
1015-
def setUp(self):
1016-
super().setUp()
1017-
self.app = fastapi.FastAPI()
1018-
1019-
@self.app.get("/foobar")
1020-
async def _():
1021-
return {"message": "hello world"}
1022-
1023-
reset_trace_globals()
1024-
tracer_provider = trace.NoOpTracerProvider()
1025-
trace.set_tracer_provider(tracer_provider=tracer_provider)
1026-
1027-
self._instrumentor = otel_fastapi.FastAPIInstrumentor()
1028-
self._instrumentor.instrument_app(self.app)
1029-
self.client = TestClient(self.app)
1030-
1031-
def tearDown(self) -> None:
1032-
super().tearDown()
1033-
with self.disable_logging():
1034-
self._instrumentor.uninstrument_app(self.app)
1035-
1036-
def test_custom_header_not_present_in_non_recording_span(self):
1037-
resp = self.client.get(
1038-
"/foobar",
1039-
headers={
1040-
"custom-test-header-1": "test-header-value-1",
1041-
},
1042-
)
1043-
self.assertEqual(200, resp.status_code)
1044-
span_list = self.memory_exporter.get_finished_spans()
1045-
self.assertEqual(len(span_list), 0)

0 commit comments

Comments
 (0)