Skip to content

Commit bf536ad

Browse files
author
Ryo Kather
committed
Finished implementations in tornado, wsgi, and asgi
Restored aiohttp test due to overwritten test Readded aiohttp url credential test Addressed yarl not found in tornado client in some tests
1 parent 7558742 commit bf536ad

File tree

8 files changed

+111
-22
lines changed

8 files changed

+111
-22
lines changed

instrumentation/opentelemetry-instrumentation-aiohttp-client/tests/test_aiohttp_client_integration.py

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -263,37 +263,34 @@ async def do_request(url):
263263
]
264264
)
265265
self.memory_exporter.clear()
266-
267-
def test_credential_removal(self):
268-
trace_configs = [aiohttp_client.create_trace_config()]
269-
270-
url = "http://username:[email protected]/"
271-
with self.subTest(url=url):
272266

273-
async def do_request(url):
274-
async with aiohttp.ClientSession(
275-
trace_configs=trace_configs,
276-
) as session:
277-
async with session.get(url):
278-
pass
267+
def test_timeout(self):
268+
async def request_handler(request):
269+
await asyncio.sleep(1)
270+
assert "traceparent" in request.headers
271+
return aiohttp.web.Response()
279272

280-
loop = asyncio.get_event_loop()
281-
loop.run_until_complete(do_request(url))
273+
host, port = self._http_request(
274+
trace_config=aiohttp_client.create_trace_config(),
275+
url="/test_timeout",
276+
request_handler=request_handler,
277+
timeout=aiohttp.ClientTimeout(sock_read=0.01),
278+
)
282279

283280
self.assert_spans(
284281
[
285282
(
286283
"HTTP GET",
287-
(StatusCode.UNSET, None),
284+
(StatusCode.ERROR, None),
288285
{
289286
SpanAttributes.HTTP_METHOD: "GET",
290-
SpanAttributes.HTTP_URL: "http://httpbin.org/",
291-
SpanAttributes.HTTP_STATUS_CODE: int(HTTPStatus.OK),
287+
SpanAttributes.HTTP_URL: "http://{}:{}/test_timeout".format(
288+
host, port
289+
),
292290
},
293291
)
294292
]
295293
)
296-
self.memory_exporter.clear()
297294

298295
def test_too_many_redirects(self):
299296
async def request_handler(request):
@@ -324,6 +321,37 @@ async def request_handler(request):
324321
]
325322
)
326323

324+
def test_credential_removal(self):
325+
trace_configs = [aiohttp_client.create_trace_config()]
326+
327+
url = "http://username:[email protected]/status/200"
328+
with self.subTest(url=url):
329+
330+
async def do_request(url):
331+
async with aiohttp.ClientSession(
332+
trace_configs=trace_configs,
333+
) as session:
334+
async with session.get(url):
335+
pass
336+
337+
loop = asyncio.get_event_loop()
338+
loop.run_until_complete(do_request(url))
339+
340+
self.assert_spans(
341+
[
342+
(
343+
"HTTP GET",
344+
(StatusCode.UNSET, None),
345+
{
346+
SpanAttributes.HTTP_METHOD: "GET",
347+
SpanAttributes.HTTP_URL: "http://httpbin.org/status/200",
348+
SpanAttributes.HTTP_STATUS_CODE: int(HTTPStatus.OK),
349+
},
350+
)
351+
]
352+
)
353+
self.memory_exporter.clear()
354+
327355

328356
class TestAioHttpClientInstrumentor(TestBase):
329357
URL = "/test-path"

instrumentation/opentelemetry-instrumentation-asgi/src/opentelemetry/instrumentation/asgi/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import typing
2222
import urllib
23+
import yarl
2324
from functools import wraps
2425
from typing import Tuple
2526

@@ -80,6 +81,11 @@ def collect_request_attributes(scope):
8081
query_string = query_string.decode("utf8")
8182
http_url = http_url + ("?" + urllib.parse.unquote(query_string))
8283

84+
try:
85+
http_url = str(yarl.URL(http_url).with_user(None))
86+
except ValueError: # invalid url was passed
87+
pass
88+
8389
result = {
8490
SpanAttributes.HTTP_SCHEME: scope.get("scheme"),
8591
SpanAttributes.HTTP_HOST: server_host,

instrumentation/opentelemetry-instrumentation-asgi/tests/test_asgi_middleware.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,14 @@ def test_response_attributes(self):
429429
def test_response_attributes_invalid_status_code(self):
430430
otel_asgi.set_status_code(self.span, "Invalid Status Code")
431431
self.assertEqual(self.span.set_status.call_count, 1)
432+
433+
def test_credential_removal(self):
434+
self.scope["server"] = ("username:[email protected]", 80)
435+
self.scope["path"] = "/status/200"
436+
attrs = otel_asgi.collect_request_attributes(self.scope)
437+
self.assertEqual(
438+
attrs[SpanAttributes.HTTP_URL], "http://httpbin.org/status/200"
439+
)
432440

433441

434442
if __name__ == "__main__":

instrumentation/opentelemetry-instrumentation-tornado/src/opentelemetry/instrumentation/tornado/client.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
import functools
1616

17+
import yarl
18+
1719
from tornado.httpclient import HTTPError, HTTPRequest
1820

1921
from opentelemetry import trace
@@ -60,8 +62,13 @@ def fetch_async(tracer, request_hook, response_hook, func, _, args, kwargs):
6062
request_hook(span, request)
6163

6264
if span.is_recording():
65+
try:
66+
url = str(yarl.URL(request.url).with_user(None))
67+
except ValueError: # invalid url was passed
68+
pass
69+
6370
attributes = {
64-
SpanAttributes.HTTP_URL: request.url,
71+
SpanAttributes.HTTP_URL: url,
6572
SpanAttributes.HTTP_METHOD: request.method,
6673
}
6774
for key, value in attributes.items():

instrumentation/opentelemetry-instrumentation-tornado/tests/test_instrumentation.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,25 @@ def test_response_headers(self):
456456
set_global_response_propagator(orig)
457457

458458
def test_credential_removal(self):
459-
pass
459+
response = self.fetch("http://username:[email protected]/status/200")
460+
self.assertEqual(response.code, 200)
461+
462+
spans = self.sorted_spans(self.memory_exporter.get_finished_spans())
463+
self.assertEqual(len(spans), 1)
464+
client = spans[0]
465+
466+
self.assertEqual(client.name, "GET")
467+
self.assertEqual(client.kind, SpanKind.CLIENT)
468+
self.assert_span_has_attributes(
469+
client,
470+
{
471+
SpanAttributes.HTTP_URL: "http://httpbin.org/status/200",
472+
SpanAttributes.HTTP_METHOD: "GET",
473+
SpanAttributes.HTTP_STATUS_CODE: 200,
474+
},
475+
)
476+
477+
self.memory_exporter.clear()
460478

461479

462480
class TornadoHookTest(TornadoTest):

instrumentation/opentelemetry-instrumentation-wsgi/src/opentelemetry/instrumentation/wsgi/__init__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ def hello():
5757
import functools
5858
import typing
5959
import wsgiref.util as wsgiref_util
60+
import yarl
6061

6162
from opentelemetry import context, trace
6263
from opentelemetry.instrumentation.utils import http_status_to_status_code
@@ -128,7 +129,12 @@ def collect_request_attributes(environ):
128129
if target is not None:
129130
result[SpanAttributes.HTTP_TARGET] = target
130131
else:
131-
result[SpanAttributes.HTTP_URL] = wsgiref_util.request_uri(environ)
132+
try:
133+
url = str(yarl.URL(wsgiref_util.request_uri(environ)).with_user(None))
134+
except ValueError: # invalid url was passed
135+
pass
136+
137+
result[SpanAttributes.HTTP_URL] = url
132138

133139
remote_addr = environ.get("REMOTE_ADDR")
134140
if remote_addr:

instrumentation/opentelemetry-instrumentation-wsgi/tests/test_wsgi_middleware.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,18 @@ def test_response_attributes(self):
364364
self.assertEqual(self.span.set_attribute.call_count, len(expected))
365365
self.span.set_attribute.assert_has_calls(expected, any_order=True)
366366

367+
def test_credential_removal(self):
368+
self.environ["HTTP_HOST"] = "username:[email protected]"
369+
self.environ["PATH_INFO"] = "/status/200"
370+
expected = {
371+
SpanAttributes.HTTP_URL: "http://httpbin.com/status/200",
372+
SpanAttributes.NET_HOST_PORT: 80,
373+
}
374+
self.assertGreaterEqual(
375+
otel_wsgi.collect_request_attributes(self.environ).items(),
376+
expected.items(),
377+
)
378+
367379

368380
class TestWsgiMiddlewareWithTracerProvider(WsgiTestBase):
369381
def validate_response(

tox.ini

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ commands_pre =
277277

278278
starlette: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-starlette[test]
279279

280-
tornado: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-tornado[test]
280+
tornado: pip install yarl {toxinidir}/instrumentation/opentelemetry-instrumentation-tornado[test]
281281

282282
jinja2: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-jinja2[test]
283283

@@ -287,6 +287,10 @@ commands_pre =
287287

288288
aiopg: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-dbapi pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-aiopg[test]
289289

290+
asgi: pip install yarl {toxinidir}/instrumentation/opentelemetry-instrumentation-asgi[test]
291+
292+
wsgi: pip install yarl {toxinidir}/instrumentation/opentelemetry-instrumentation-wsgi[test]
293+
290294
datadog: pip install flaky {toxinidir}/exporter/opentelemetry-exporter-datadog[test]
291295

292296
sklearn: pip install {toxinidir}/instrumentation/opentelemetry-instrumentation-sklearn[test]

0 commit comments

Comments
 (0)