Skip to content

Commit 5babfb2

Browse files
authored
aiohttp-server: migrate test telemetry management to test_base (#4121)
* aiohttp-server: migrate test telemetry management to test_base * Lint * Lint
1 parent 5429c6c commit 5babfb2

1 file changed

Lines changed: 48 additions & 111 deletions

File tree

instrumentation/opentelemetry-instrumentation-aiohttp-server/tests/test_aiohttp_server_integration.py

Lines changed: 48 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
import pytest_asyncio
2121
from multidict import CIMultiDict
2222

23-
from opentelemetry import metrics as metrics_api
24-
from opentelemetry import trace as trace_api
2523
from opentelemetry.instrumentation._semconv import (
2624
HTTP_DURATION_HISTOGRAM_BUCKETS_NEW,
2725
OTEL_SEMCONV_STABILITY_OPT_IN,
@@ -73,10 +71,6 @@
7371
from opentelemetry.semconv.attributes.user_agent_attributes import (
7472
USER_AGENT_ORIGINAL,
7573
)
76-
from opentelemetry.test.globals_test import (
77-
reset_metrics_globals,
78-
reset_trace_globals,
79-
)
8074
from opentelemetry.test.test_base import TestBase
8175
from opentelemetry.util._importlib_metadata import entry_points
8276
from opentelemetry.util.http import (
@@ -103,33 +97,24 @@ def __repr__(self):
10397
TRACE = "TRACE"
10498

10599

106-
@pytest.fixture(name="tracer", scope="function")
107-
def fixture_tracer():
100+
@pytest.fixture(name="test_base", scope="function")
101+
def fixture_test_base():
108102
test_base = TestBase()
103+
test_base.setUp()
104+
try:
105+
yield test_base
106+
finally:
107+
test_base.tearDown()
109108

110-
tracer_provider, memory_exporter = test_base.create_tracer_provider()
111-
112-
reset_trace_globals()
113-
trace_api.set_tracer_provider(tracer_provider)
114-
115-
yield tracer_provider, memory_exporter
116109

117-
reset_trace_globals()
118-
memory_exporter.clear()
110+
@pytest.fixture(name="tracer", scope="function")
111+
def fixture_tracer(test_base: TestBase):
112+
return test_base.tracer_provider, test_base.memory_exporter
119113

120114

121115
@pytest.fixture(name="meter", scope="function")
122-
def fixture_meter():
123-
test_base = TestBase()
124-
125-
meter_provider, memory_reader = test_base.create_meter_provider()
126-
127-
reset_metrics_globals()
128-
metrics_api.set_meter_provider(meter_provider)
129-
130-
yield meter_provider, memory_reader
131-
132-
reset_metrics_globals()
116+
def fixture_meter(test_base: TestBase):
117+
return test_base.meter_provider, test_base.memory_metrics_reader
133118

134119

135120
async def default_handler(request, status=200):
@@ -143,7 +128,7 @@ def fixture_suppress():
143128

144129
@pytest_asyncio.fixture(name="server_fixture")
145130
async def fixture_server_fixture(tracer, aiohttp_server, suppress):
146-
tracer_provider, memory_exporter = tracer
131+
tracer_provider, _ = tracer
147132

148133
AioHttpServerInstrumentor().instrument(tracer_provider=tracer_provider)
149134

@@ -157,8 +142,6 @@ async def fixture_server_fixture(tracer, aiohttp_server, suppress):
157142

158143
yield server, app
159144

160-
memory_exporter.clear()
161-
162145
AioHttpServerInstrumentor().uninstrument()
163146

164147

@@ -179,31 +162,27 @@ def test_checking_instrumentor_pkg_installed():
179162
],
180163
)
181164
async def test_status_code_instrumentation(
182-
tracer,
183-
meter,
165+
test_base: TestBase,
184166
server_fixture,
185167
aiohttp_client,
186168
url,
187169
expected_method,
188170
expected_status_code,
189171
):
190-
_, memory_exporter = tracer
191-
_, metrics_reader = meter
192172
server, _ = server_fixture
193173

194-
assert len(memory_exporter.get_finished_spans()) == 0
195-
metrics = _get_sorted_metrics(metrics_reader.get_metrics_data())
174+
assert len(test_base.get_finished_spans()) == 0
175+
metrics = test_base.get_sorted_metrics()
196176
assert len(metrics) == 0
197177

198178
client = await aiohttp_client(server)
199179
await client.get(url)
200180

201-
assert len(memory_exporter.get_finished_spans()) == 1
202-
metrics = _get_sorted_metrics(metrics_reader.get_metrics_data())
181+
assert len(test_base.get_finished_spans()) == 1
182+
metrics = test_base.get_sorted_metrics()
203183
assert len(metrics) == 2
204184

205-
[span] = memory_exporter.get_finished_spans()
206-
185+
[span] = test_base.get_finished_spans()
207186
assert expected_method.value == span.attributes[HTTP_METHOD]
208187
assert expected_status_code == span.attributes[HTTP_STATUS_CODE]
209188
assert url == span.attributes[HTTP_TARGET]
@@ -212,23 +191,22 @@ async def test_status_code_instrumentation(
212191
@pytest.mark.asyncio
213192
@pytest.mark.parametrize("suppress", [True])
214193
async def test_suppress_instrumentation(
215-
tracer, server_fixture, aiohttp_client
194+
test_base: TestBase, server_fixture, aiohttp_client
216195
):
217-
_, memory_exporter = tracer
218196
server, _ = server_fixture
219-
assert len(memory_exporter.get_finished_spans()) == 0
197+
assert len(test_base.get_finished_spans()) == 0
220198

221199
client = await aiohttp_client(server)
222200
await client.get("/test-path")
223201

224-
assert len(memory_exporter.get_finished_spans()) == 0
202+
assert len(test_base.get_finished_spans()) == 0
225203

226204

227205
@pytest.mark.asyncio
228-
async def test_remove_sensitive_params(tracer, aiohttp_server, monkeypatch):
206+
async def test_remove_sensitive_params(
207+
test_base: TestBase, aiohttp_server, monkeypatch
208+
):
229209
"""Test that sensitive information in URLs is properly redacted."""
230-
_, memory_exporter = tracer
231-
232210
# Use old semconv to test HTTP_URL redaction
233211
monkeypatch.setenv(
234212
OTEL_SEMCONV_STABILITY_OPT_IN, _StabilityMode.DEFAULT.value
@@ -257,7 +235,7 @@ async def handler(request):
257235
assert await response.text() == "hello"
258236

259237
# Verify redaction in span attributes
260-
spans = memory_exporter.get_finished_spans()
238+
spans = test_base.get_finished_spans()
261239
assert len(spans) == 1
262240

263241
span = spans[0]
@@ -270,16 +248,13 @@ async def handler(request):
270248

271249
# Clean up
272250
AioHttpServerInstrumentor().uninstrument()
273-
memory_exporter.clear()
274251

275252

276253
@pytest.mark.asyncio
277254
async def test_remove_sensitive_params_new(
278-
tracer, aiohttp_server, monkeypatch
255+
test_base: TestBase, aiohttp_server, monkeypatch
279256
):
280257
"""Test URL handling with new semantic conventions (no redaction for URL_PATH/URL_QUERY)."""
281-
_, memory_exporter = tracer
282-
283258
# Use new semconv
284259
monkeypatch.setenv(
285260
OTEL_SEMCONV_STABILITY_OPT_IN, _StabilityMode.HTTP.value
@@ -308,7 +283,7 @@ async def handler(request):
308283
assert await response.text() == "hello"
309284

310285
# Verify span attributes with new semconv
311-
spans = memory_exporter.get_finished_spans()
286+
spans = test_base.get_finished_spans()
312287
assert len(spans) == 1
313288

314289
span = spans[0]
@@ -320,21 +295,6 @@ async def handler(request):
320295

321296
# Clean up
322297
AioHttpServerInstrumentor().uninstrument()
323-
memory_exporter.clear()
324-
325-
326-
def _get_sorted_metrics(metrics_data):
327-
resource_metrics = metrics_data.resource_metrics if metrics_data else []
328-
329-
all_metrics = []
330-
for metrics in resource_metrics:
331-
for scope_metrics in metrics.scope_metrics:
332-
all_metrics.extend(scope_metrics.metrics)
333-
334-
return sorted(
335-
all_metrics,
336-
key=lambda m: m.name,
337-
)
338298

339299

340300
@pytest.mark.asyncio
@@ -343,12 +303,9 @@ def _get_sorted_metrics(metrics_data):
343303
["OTEL_PYTHON_AIOHTTP_SERVER_EXCLUDED_URLS", "OTEL_PYTHON_EXCLUDED_URLS"],
344304
)
345305
async def test_excluded_urls(
346-
tracer, meter, aiohttp_server, monkeypatch, env_var
306+
test_base: TestBase, aiohttp_server, monkeypatch, env_var
347307
):
348308
"""Test that excluded env vars are taken into account."""
349-
_, memory_exporter = tracer
350-
_, metrics_reader = meter
351-
352309
monkeypatch.setenv(env_var, "/status/200")
353310
AioHttpServerInstrumentor().instrument()
354311

@@ -367,10 +324,10 @@ async def handler(request):
367324
assert response.status == 200
368325
assert await response.text() == "hello"
369326

370-
spans = memory_exporter.get_finished_spans()
327+
spans = test_base.get_finished_spans()
371328
assert len(spans) == 0
372329

373-
metrics = _get_sorted_metrics(metrics_reader.get_metrics_data())
330+
metrics = test_base.get_sorted_metrics()
374331
assert len(metrics) == 0
375332

376333
AioHttpServerInstrumentor().uninstrument()
@@ -415,25 +372,11 @@ async def test_non_global_tracer_provider(
415372
)
416373

417374

418-
def _get_sorted_metrics(metrics_data):
419-
resource_metrics = metrics_data.resource_metrics if metrics_data else []
420-
421-
all_metrics = []
422-
for metrics in resource_metrics:
423-
for scope_metrics in metrics.scope_metrics:
424-
all_metrics.extend(scope_metrics.metrics)
425-
426-
return sorted(
427-
all_metrics,
428-
key=lambda m: m.name,
429-
)
430-
431-
432375
@pytest.mark.asyncio
433-
async def test_custom_request_headers(tracer, aiohttp_server, monkeypatch):
376+
async def test_custom_request_headers(
377+
test_base: TestBase, aiohttp_server, monkeypatch
378+
):
434379
# pylint: disable=too-many-locals
435-
_, memory_exporter = tracer
436-
437380
monkeypatch.setenv(
438381
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS,
439382
".*my-secret.*",
@@ -466,7 +409,7 @@ async def handler(request):
466409
assert response.status == 200
467410
assert await response.text() == "hello"
468411

469-
spans = memory_exporter.get_finished_spans()
412+
spans = test_base.get_finished_spans()
470413
assert len(spans) == 1
471414

472415
span = spans[0]
@@ -489,9 +432,9 @@ async def handler(request):
489432

490433

491434
@pytest.mark.asyncio
492-
async def test_custom_response_headers(tracer, aiohttp_server, monkeypatch):
493-
_, memory_exporter = tracer
494-
435+
async def test_custom_response_headers(
436+
test_base: TestBase, aiohttp_server, monkeypatch
437+
):
495438
monkeypatch.setenv(
496439
OTEL_INSTRUMENTATION_HTTP_CAPTURE_HEADERS_SANITIZE_FIELDS,
497440
".*my-secret.*",
@@ -526,7 +469,7 @@ async def handler(request):
526469
assert response.status == 200
527470
assert await response.text() == "hello"
528471

529-
spans = memory_exporter.get_finished_spans()
472+
spans = test_base.get_finished_spans()
530473
assert len(spans) == 1
531474

532475
span = spans[0]
@@ -553,10 +496,8 @@ async def handler(request):
553496
# pylint: disable=too-many-locals
554497
@pytest.mark.asyncio
555498
async def test_semantic_conventions_metrics_old_default(
556-
tracer, meter, aiohttp_server, monkeypatch
499+
test_base: TestBase, aiohttp_server, monkeypatch
557500
):
558-
_, memory_exporter = tracer
559-
_, metrics_reader = meter
560501
monkeypatch.setenv(
561502
OTEL_SEMCONV_STABILITY_OPT_IN, _StabilityMode.DEFAULT.value
562503
)
@@ -573,7 +514,7 @@ async def test_semantic_conventions_metrics_old_default(
573514
url, headers={"User-Agent": "test-agent"}
574515
) as response:
575516
assert response.status == 200
576-
spans = memory_exporter.get_finished_spans()
517+
spans = test_base.get_finished_spans()
577518
assert len(spans) == 1
578519
span = spans[0]
579520

@@ -604,7 +545,7 @@ async def test_semantic_conventions_metrics_old_default(
604545
assert NETWORK_PROTOCOL_VERSION not in span.attributes
605546
assert HTTP_RESPONSE_STATUS_CODE not in span.attributes
606547

607-
metrics = _get_sorted_metrics(metrics_reader.get_metrics_data())
548+
metrics = test_base.get_sorted_metrics()
608549
expected_metric_names = [
609550
"http.server.active_requests",
610551
"http.server.duration",
@@ -629,10 +570,8 @@ async def test_semantic_conventions_metrics_old_default(
629570
# pylint: disable=too-many-locals
630571
@pytest.mark.asyncio
631572
async def test_semantic_conventions_metrics_new(
632-
tracer, meter, aiohttp_server, monkeypatch
573+
test_base: TestBase, meter, aiohttp_server, monkeypatch
633574
):
634-
_, memory_exporter = tracer
635-
_, metrics_reader = meter
636575
monkeypatch.setenv(
637576
OTEL_SEMCONV_STABILITY_OPT_IN, _StabilityMode.HTTP.value
638577
)
@@ -649,7 +588,7 @@ async def test_semantic_conventions_metrics_new(
649588
url, headers={"User-Agent": "test-agent"}
650589
) as response:
651590
assert response.status == 200
652-
spans = memory_exporter.get_finished_spans()
591+
spans = test_base.get_finished_spans()
653592
assert len(spans) == 1
654593
span = spans[0]
655594

@@ -680,7 +619,7 @@ async def test_semantic_conventions_metrics_new(
680619
assert HTTP_FLAVOR not in span.attributes
681620
assert HTTP_STATUS_CODE not in span.attributes
682621

683-
metrics = _get_sorted_metrics(metrics_reader.get_metrics_data())
622+
metrics = test_base.get_sorted_metrics()
684623
expected_metric_names = [
685624
"http.server.active_requests",
686625
"http.server.request.duration",
@@ -714,10 +653,8 @@ async def test_semantic_conventions_metrics_new(
714653
# pylint: disable=too-many-statements
715654
@pytest.mark.asyncio
716655
async def test_semantic_conventions_metrics_both(
717-
tracer, meter, aiohttp_server, monkeypatch
656+
test_base: TestBase, meter, aiohttp_server, monkeypatch
718657
):
719-
_, memory_exporter = tracer
720-
_, metrics_reader = meter
721658
monkeypatch.setenv(
722659
OTEL_SEMCONV_STABILITY_OPT_IN, _StabilityMode.HTTP_DUP.value
723660
)
@@ -734,7 +671,7 @@ async def test_semantic_conventions_metrics_both(
734671
url, headers={"User-Agent": "test-agent"}
735672
) as response:
736673
assert response.status == 200
737-
spans = memory_exporter.get_finished_spans()
674+
spans = test_base.get_finished_spans()
738675
assert len(spans) == 1
739676
span = spans[0]
740677

@@ -764,7 +701,7 @@ async def test_semantic_conventions_metrics_both(
764701
assert span.attributes.get(HTTP_RESPONSE_STATUS_CODE) == 200
765702
assert span.attributes.get(HTTP_ROUTE) == "default_handler"
766703

767-
metrics = _get_sorted_metrics(metrics_reader.get_metrics_data())
704+
metrics = test_base.get_sorted_metrics()
768705
assert len(metrics) == 3 # Both duration metrics + active requests
769706
server_active_requests_count_attrs_both = list(
770707
_server_active_requests_count_attrs_old

0 commit comments

Comments
 (0)