|
10 | 10 |
|
11 | 11 | import pip |
12 | 12 | import pytest |
13 | | -from fastapi import FastAPI |
| 13 | +from fastapi import FastAPI, status |
14 | 14 | from fastapi.exceptions import HTTPException |
15 | | -from fastapi.responses import PlainTextResponse |
| 15 | +from fastapi.responses import JSONResponse, PlainTextResponse |
16 | 16 | from fastapi.testclient import TestClient |
17 | 17 | from opentelemetry import trace |
18 | 18 | from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter |
|
21 | 21 | get_tracing_instrumentation_lifespan, |
22 | 22 | initialize_fastapi_app_tracing, |
23 | 23 | ) |
24 | | -from servicelib.tracing import _OSPARC_TRACE_ID_HEADER |
| 24 | +from servicelib.tracing import ( |
| 25 | + _OSPARC_TRACE_ID_HEADER, |
| 26 | + _PROFILE_ATTRIBUTE_NAME, |
| 27 | + with_profiled_span, |
| 28 | +) |
25 | 29 | from settings_library.tracing import TracingSettings |
26 | 30 |
|
27 | 31 |
|
@@ -224,3 +228,49 @@ async def handler(handler_data: dict): |
224 | 228 | trace_id = response.headers[_OSPARC_TRACE_ID_HEADER] |
225 | 229 | assert len(trace_id) == 32 # Ensure trace ID is a 32-character hex string |
226 | 230 | assert trace_id == handler_data[_OSPARC_TRACE_ID_HEADER] |
| 231 | + |
| 232 | + |
| 233 | +@pytest.mark.parametrize( |
| 234 | + "tracing_settings_in", |
| 235 | + [ |
| 236 | + ("http://opentelemetry-collector", 4318), |
| 237 | + ], |
| 238 | + indirect=True, |
| 239 | +) |
| 240 | +async def test_with_profile_span( |
| 241 | + mock_otel_collector: InMemorySpanExporter, |
| 242 | + mocked_app: FastAPI, |
| 243 | + set_and_clean_settings_env_vars: Callable[[], None], |
| 244 | + tracing_settings_in: Callable, |
| 245 | +): |
| 246 | + tracing_settings = TracingSettings() |
| 247 | + |
| 248 | + @with_profiled_span |
| 249 | + async def handler(): |
| 250 | + current_span = trace.get_current_span() |
| 251 | + return JSONResponse( |
| 252 | + content={ |
| 253 | + "trace_id": f"{format(current_span.get_span_context().trace_id, '032x')}" |
| 254 | + }, |
| 255 | + ) |
| 256 | + |
| 257 | + mocked_app.get("/")(handler) |
| 258 | + |
| 259 | + async for _ in get_tracing_instrumentation_lifespan( |
| 260 | + tracing_settings=tracing_settings, |
| 261 | + service_name="Mock-OpenTelemetry-Pytest", |
| 262 | + )(app=mocked_app): |
| 263 | + initialize_fastapi_app_tracing(mocked_app, add_response_trace_id_header=True) |
| 264 | + client = TestClient(mocked_app) |
| 265 | + response = client.get("/") |
| 266 | + assert response.status_code == status.HTTP_200_OK |
| 267 | + trace_id = response.json().get("trace_id") |
| 268 | + assert trace_id is not None |
| 269 | + |
| 270 | + spans = mock_otel_collector.get_finished_spans() |
| 271 | + assert any( |
| 272 | + span.context.trace_id == int(trace_id, 16) |
| 273 | + and _PROFILE_ATTRIBUTE_NAME in span.attributes.keys() |
| 274 | + for span in spans |
| 275 | + if span.context is not None and span.attributes is not None |
| 276 | + ) |
0 commit comments