mirror of
https://github.com/open-telemetry/opentelemetry-python-contrib.git
synced 2025-07-28 12:43:39 +08:00
Prepare asgi tests to support newer asgiref version (#2778)
This commit is contained in:

committed by
GitHub

parent
bc4d2c5b75
commit
19f8e775ce
@ -1,7 +1,21 @@
|
||||
# Copyright The OpenTelemetry Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
|
||||
import opentelemetry.instrumentation.asgi as otel_asgi
|
||||
from opentelemetry.test.asgitestutil import AsgiTestBase
|
||||
from opentelemetry.test.asgitestutil import AsyncAsgiTestBase
|
||||
from opentelemetry.test.test_base import TestBase
|
||||
from opentelemetry.trace import SpanKind
|
||||
from opentelemetry.util.http import (
|
||||
@ -90,7 +104,7 @@ async def websocket_app_with_custom_headers(scope, receive, send):
|
||||
break
|
||||
|
||||
|
||||
class TestCustomHeaders(AsgiTestBase, TestBase):
|
||||
class TestCustomHeaders(AsyncAsgiTestBase):
|
||||
constructor_params = {}
|
||||
__test__ = False
|
||||
|
||||
@ -108,7 +122,7 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
|
||||
**self.constructor_params,
|
||||
)
|
||||
|
||||
def test_http_custom_request_headers_in_span_attributes(self):
|
||||
async def test_http_custom_request_headers_in_span_attributes(self):
|
||||
self.scope["headers"].extend(
|
||||
[
|
||||
(b"custom-test-header-1", b"test-header-value-1"),
|
||||
@ -119,8 +133,8 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
|
||||
]
|
||||
)
|
||||
self.seed_app(self.app)
|
||||
self.send_default_request()
|
||||
self.get_all_output()
|
||||
await self.send_default_request()
|
||||
await self.get_all_output()
|
||||
span_list = self.exporter.get_finished_spans()
|
||||
expected = {
|
||||
"http.request.header.custom_test_header_1": (
|
||||
@ -139,7 +153,7 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
|
||||
if span.kind == SpanKind.SERVER:
|
||||
self.assertSpanHasAttributes(span, expected)
|
||||
|
||||
def test_http_repeat_request_headers_in_span_attributes(self):
|
||||
async def test_http_repeat_request_headers_in_span_attributes(self):
|
||||
self.scope["headers"].extend(
|
||||
[
|
||||
(b"custom-test-header-1", b"test-header-value-1"),
|
||||
@ -147,8 +161,8 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
|
||||
]
|
||||
)
|
||||
self.seed_app(self.app)
|
||||
self.send_default_request()
|
||||
self.get_all_output()
|
||||
await self.send_default_request()
|
||||
await self.get_all_output()
|
||||
span_list = self.exporter.get_finished_spans()
|
||||
expected = {
|
||||
"http.request.header.custom_test_header_1": (
|
||||
@ -159,15 +173,15 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
|
||||
span = next(span for span in span_list if span.kind == SpanKind.SERVER)
|
||||
self.assertSpanHasAttributes(span, expected)
|
||||
|
||||
def test_http_custom_request_headers_not_in_span_attributes(self):
|
||||
async def test_http_custom_request_headers_not_in_span_attributes(self):
|
||||
self.scope["headers"].extend(
|
||||
[
|
||||
(b"custom-test-header-1", b"test-header-value-1"),
|
||||
]
|
||||
)
|
||||
self.seed_app(self.app)
|
||||
self.send_default_request()
|
||||
self.get_all_output()
|
||||
await self.send_default_request()
|
||||
await self.get_all_output()
|
||||
span_list = self.exporter.get_finished_spans()
|
||||
expected = {
|
||||
"http.request.header.custom_test_header_1": (
|
||||
@ -185,15 +199,15 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
|
||||
for key, _ in not_expected.items():
|
||||
self.assertNotIn(key, span.attributes)
|
||||
|
||||
def test_http_custom_response_headers_in_span_attributes(self):
|
||||
async def test_http_custom_response_headers_in_span_attributes(self):
|
||||
self.app = otel_asgi.OpenTelemetryMiddleware(
|
||||
http_app_with_custom_headers,
|
||||
tracer_provider=self.tracer_provider,
|
||||
**self.constructor_params,
|
||||
)
|
||||
self.seed_app(self.app)
|
||||
self.send_default_request()
|
||||
self.get_all_output()
|
||||
await self.send_default_request()
|
||||
await self.get_all_output()
|
||||
span_list = self.exporter.get_finished_spans()
|
||||
expected = {
|
||||
"http.response.header.custom_test_header_1": (
|
||||
@ -214,15 +228,15 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
|
||||
if span.kind == SpanKind.SERVER:
|
||||
self.assertSpanHasAttributes(span, expected)
|
||||
|
||||
def test_http_repeat_response_headers_in_span_attributes(self):
|
||||
async def test_http_repeat_response_headers_in_span_attributes(self):
|
||||
self.app = otel_asgi.OpenTelemetryMiddleware(
|
||||
http_app_with_repeat_headers,
|
||||
tracer_provider=self.tracer_provider,
|
||||
**self.constructor_params,
|
||||
)
|
||||
self.seed_app(self.app)
|
||||
self.send_default_request()
|
||||
self.get_all_output()
|
||||
await self.send_default_request()
|
||||
await self.get_all_output()
|
||||
span_list = self.exporter.get_finished_spans()
|
||||
expected = {
|
||||
"http.response.header.custom_test_header_1": (
|
||||
@ -233,15 +247,15 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
|
||||
span = next(span for span in span_list if span.kind == SpanKind.SERVER)
|
||||
self.assertSpanHasAttributes(span, expected)
|
||||
|
||||
def test_http_custom_response_headers_not_in_span_attributes(self):
|
||||
async def test_http_custom_response_headers_not_in_span_attributes(self):
|
||||
self.app = otel_asgi.OpenTelemetryMiddleware(
|
||||
http_app_with_custom_headers,
|
||||
tracer_provider=self.tracer_provider,
|
||||
**self.constructor_params,
|
||||
)
|
||||
self.seed_app(self.app)
|
||||
self.send_default_request()
|
||||
self.get_all_output()
|
||||
await self.send_default_request()
|
||||
await self.get_all_output()
|
||||
span_list = self.exporter.get_finished_spans()
|
||||
not_expected = {
|
||||
"http.response.header.custom_test_header_3": (
|
||||
@ -253,7 +267,7 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
|
||||
for key, _ in not_expected.items():
|
||||
self.assertNotIn(key, span.attributes)
|
||||
|
||||
def test_websocket_custom_request_headers_in_span_attributes(self):
|
||||
async def test_websocket_custom_request_headers_in_span_attributes(self):
|
||||
self.scope = {
|
||||
"type": "websocket",
|
||||
"http_version": "1.1",
|
||||
@ -271,11 +285,11 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
|
||||
"server": ("127.0.0.1", 80),
|
||||
}
|
||||
self.seed_app(self.app)
|
||||
self.send_input({"type": "websocket.connect"})
|
||||
self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
self.send_input({"type": "websocket.disconnect"})
|
||||
await self.send_input({"type": "websocket.connect"})
|
||||
await self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
await self.send_input({"type": "websocket.disconnect"})
|
||||
|
||||
self.get_all_output()
|
||||
await self.get_all_output()
|
||||
span_list = self.exporter.get_finished_spans()
|
||||
expected = {
|
||||
"http.request.header.custom_test_header_1": (
|
||||
@ -294,7 +308,9 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
|
||||
if span.kind == SpanKind.SERVER:
|
||||
self.assertSpanHasAttributes(span, expected)
|
||||
|
||||
def test_websocket_custom_request_headers_not_in_span_attributes(self):
|
||||
async def test_websocket_custom_request_headers_not_in_span_attributes(
|
||||
self,
|
||||
):
|
||||
self.scope = {
|
||||
"type": "websocket",
|
||||
"http_version": "1.1",
|
||||
@ -309,11 +325,11 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
|
||||
"server": ("127.0.0.1", 80),
|
||||
}
|
||||
self.seed_app(self.app)
|
||||
self.send_input({"type": "websocket.connect"})
|
||||
self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
self.send_input({"type": "websocket.disconnect"})
|
||||
await self.send_input({"type": "websocket.connect"})
|
||||
await self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
await self.send_input({"type": "websocket.disconnect"})
|
||||
|
||||
self.get_all_output()
|
||||
await self.get_all_output()
|
||||
span_list = self.exporter.get_finished_spans()
|
||||
not_expected = {
|
||||
"http.request.header.custom_test_header_3": (
|
||||
@ -325,7 +341,7 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
|
||||
for key, _ in not_expected.items():
|
||||
self.assertNotIn(key, span.attributes)
|
||||
|
||||
def test_websocket_custom_response_headers_in_span_attributes(self):
|
||||
async def test_websocket_custom_response_headers_in_span_attributes(self):
|
||||
self.scope = {
|
||||
"type": "websocket",
|
||||
"http_version": "1.1",
|
||||
@ -342,10 +358,10 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
|
||||
**self.constructor_params,
|
||||
)
|
||||
self.seed_app(self.app)
|
||||
self.send_input({"type": "websocket.connect"})
|
||||
self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
self.send_input({"type": "websocket.disconnect"})
|
||||
self.get_all_output()
|
||||
await self.send_input({"type": "websocket.connect"})
|
||||
await self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
await self.send_input({"type": "websocket.disconnect"})
|
||||
await self.get_all_output()
|
||||
span_list = self.exporter.get_finished_spans()
|
||||
expected = {
|
||||
"http.response.header.custom_test_header_1": (
|
||||
@ -366,7 +382,9 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
|
||||
if span.kind == SpanKind.SERVER:
|
||||
self.assertSpanHasAttributes(span, expected)
|
||||
|
||||
def test_websocket_custom_response_headers_not_in_span_attributes(self):
|
||||
async def test_websocket_custom_response_headers_not_in_span_attributes(
|
||||
self,
|
||||
):
|
||||
self.scope = {
|
||||
"type": "websocket",
|
||||
"http_version": "1.1",
|
||||
@ -383,10 +401,10 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
|
||||
**self.constructor_params,
|
||||
)
|
||||
self.seed_app(self.app)
|
||||
self.send_input({"type": "websocket.connect"})
|
||||
self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
self.send_input({"type": "websocket.disconnect"})
|
||||
self.get_all_output()
|
||||
await self.send_input({"type": "websocket.connect"})
|
||||
await self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
await self.send_input({"type": "websocket.disconnect"})
|
||||
await self.get_all_output()
|
||||
span_list = self.exporter.get_finished_spans()
|
||||
not_expected = {
|
||||
"http.response.header.custom_test_header_3": (
|
||||
|
@ -14,7 +14,6 @@
|
||||
|
||||
# pylint: disable=too-many-lines
|
||||
|
||||
import asyncio
|
||||
import sys
|
||||
import time
|
||||
import unittest
|
||||
@ -64,7 +63,7 @@ from opentelemetry.semconv.attributes.user_agent_attributes import (
|
||||
)
|
||||
from opentelemetry.semconv.trace import SpanAttributes
|
||||
from opentelemetry.test.asgitestutil import (
|
||||
AsgiTestBase,
|
||||
AsyncAsgiTestBase,
|
||||
setup_testing_defaults,
|
||||
)
|
||||
from opentelemetry.test.test_base import TestBase
|
||||
@ -275,7 +274,7 @@ async def error_asgi(scope, receive, send):
|
||||
|
||||
|
||||
# pylint: disable=too-many-public-methods
|
||||
class TestAsgiApplication(AsgiTestBase):
|
||||
class TestAsgiApplication(AsyncAsgiTestBase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
@ -477,31 +476,31 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
"opentelemetry.instrumentation.asgi",
|
||||
)
|
||||
|
||||
def test_basic_asgi_call(self):
|
||||
async def test_basic_asgi_call(self):
|
||||
"""Test that spans are emitted as expected."""
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
outputs = self.get_all_output()
|
||||
await self.send_default_request()
|
||||
outputs = await self.get_all_output()
|
||||
self.validate_outputs(outputs)
|
||||
|
||||
def test_basic_asgi_call_new_semconv(self):
|
||||
async def test_basic_asgi_call_new_semconv(self):
|
||||
"""Test that spans are emitted as expected."""
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
outputs = self.get_all_output()
|
||||
await self.send_default_request()
|
||||
outputs = await self.get_all_output()
|
||||
self.validate_outputs(outputs, old_sem_conv=False, new_sem_conv=True)
|
||||
|
||||
def test_basic_asgi_call_both_semconv(self):
|
||||
async def test_basic_asgi_call_both_semconv(self):
|
||||
"""Test that spans are emitted as expected."""
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
outputs = self.get_all_output()
|
||||
await self.send_default_request()
|
||||
outputs = await self.get_all_output()
|
||||
self.validate_outputs(outputs, old_sem_conv=True, new_sem_conv=True)
|
||||
|
||||
def test_asgi_not_recording(self):
|
||||
async def test_asgi_not_recording(self):
|
||||
mock_tracer = mock.Mock()
|
||||
mock_span = mock.Mock()
|
||||
mock_span.is_recording.return_value = False
|
||||
@ -514,21 +513,21 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
tracer.return_value = mock_tracer
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
self.assertFalse(mock_span.is_recording())
|
||||
self.assertTrue(mock_span.is_recording.called)
|
||||
self.assertFalse(mock_span.set_attribute.called)
|
||||
self.assertFalse(mock_span.set_status.called)
|
||||
|
||||
def test_asgi_exc_info(self):
|
||||
async def test_asgi_exc_info(self):
|
||||
"""Test that exception information is emitted as expected."""
|
||||
app = otel_asgi.OpenTelemetryMiddleware(error_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
outputs = self.get_all_output()
|
||||
await self.send_default_request()
|
||||
outputs = await self.get_all_output()
|
||||
self.validate_outputs(outputs, error=ValueError)
|
||||
|
||||
def test_long_response(self):
|
||||
async def test_long_response(self):
|
||||
"""Test that the server span is ended on the final response body message.
|
||||
|
||||
If the server span is ended early then this test will fail due
|
||||
@ -536,8 +535,8 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
"""
|
||||
app = otel_asgi.OpenTelemetryMiddleware(long_response_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
outputs = self.get_all_output()
|
||||
await self.send_default_request()
|
||||
outputs = await self.get_all_output()
|
||||
|
||||
def add_more_body_spans(expected: list):
|
||||
more_body_span = {
|
||||
@ -551,12 +550,12 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
|
||||
self.validate_outputs(outputs, modifiers=[add_more_body_spans])
|
||||
|
||||
def test_background_execution(self):
|
||||
async def test_background_execution(self):
|
||||
"""Test that the server span is ended BEFORE the background task is finished."""
|
||||
app = otel_asgi.OpenTelemetryMiddleware(background_execution_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
outputs = self.get_all_output()
|
||||
await self.send_default_request()
|
||||
outputs = await self.get_all_output()
|
||||
self.validate_outputs(outputs)
|
||||
span_list = self.memory_exporter.get_finished_spans()
|
||||
server_span = span_list[-1]
|
||||
@ -567,15 +566,15 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
_SIMULATED_BACKGROUND_TASK_EXECUTION_TIME_S * 10**9,
|
||||
)
|
||||
|
||||
def test_trailers(self):
|
||||
async def test_trailers(self):
|
||||
"""Test that trailers are emitted as expected and that the server span is ended
|
||||
BEFORE the background task is finished."""
|
||||
app = otel_asgi.OpenTelemetryMiddleware(
|
||||
background_execution_trailers_asgi
|
||||
)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
outputs = self.get_all_output()
|
||||
await self.send_default_request()
|
||||
outputs = await self.get_all_output()
|
||||
|
||||
def add_body_and_trailer_span(expected: list):
|
||||
body_span = {
|
||||
@ -602,7 +601,7 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
_SIMULATED_BACKGROUND_TASK_EXECUTION_TIME_S * 10**9,
|
||||
)
|
||||
|
||||
def test_override_span_name(self):
|
||||
async def test_override_span_name(self):
|
||||
"""Test that default span_names can be overwritten by our callback function."""
|
||||
span_name = "Dymaxion"
|
||||
|
||||
@ -623,11 +622,11 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
simple_asgi, default_span_details=get_predefined_span_details
|
||||
)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
outputs = self.get_all_output()
|
||||
await self.send_default_request()
|
||||
outputs = await self.get_all_output()
|
||||
self.validate_outputs(outputs, modifiers=[update_expected_span_name])
|
||||
|
||||
def test_custom_tracer_provider_otel_asgi(self):
|
||||
async def test_custom_tracer_provider_otel_asgi(self):
|
||||
resource = resources.Resource.create({"service-test-key": "value"})
|
||||
result = TestBase.create_tracer_provider(resource=resource)
|
||||
tracer_provider, exporter = result
|
||||
@ -636,28 +635,28 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
simple_asgi, tracer_provider=tracer_provider
|
||||
)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
span_list = exporter.get_finished_spans()
|
||||
for span in span_list:
|
||||
self.assertEqual(
|
||||
span.resource.attributes["service-test-key"], "value"
|
||||
)
|
||||
|
||||
def test_no_op_tracer_provider_otel_asgi(self):
|
||||
async def test_no_op_tracer_provider_otel_asgi(self):
|
||||
app = otel_asgi.OpenTelemetryMiddleware(
|
||||
simple_asgi, tracer_provider=trace_api.NoOpTracerProvider()
|
||||
)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
|
||||
response_start, response_body, *_ = self.get_all_output()
|
||||
response_start, response_body, *_ = await self.get_all_output()
|
||||
self.assertEqual(response_body["body"], b"*")
|
||||
self.assertEqual(response_start["status"], 200)
|
||||
|
||||
span_list = self.memory_exporter.get_finished_spans()
|
||||
self.assertEqual(len(span_list), 0)
|
||||
|
||||
def test_behavior_with_scope_server_as_none(self):
|
||||
async def test_behavior_with_scope_server_as_none(self):
|
||||
"""Test that middleware is ok when server is none in scope."""
|
||||
|
||||
def update_expected_server(expected):
|
||||
@ -673,11 +672,11 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
self.scope["server"] = None
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
outputs = self.get_all_output()
|
||||
await self.send_default_request()
|
||||
outputs = await self.get_all_output()
|
||||
self.validate_outputs(outputs, modifiers=[update_expected_server])
|
||||
|
||||
def test_behavior_with_scope_server_as_none_new_semconv(self):
|
||||
async def test_behavior_with_scope_server_as_none_new_semconv(self):
|
||||
"""Test that middleware is ok when server is none in scope."""
|
||||
|
||||
def update_expected_server(expected):
|
||||
@ -692,8 +691,8 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
self.scope["server"] = None
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
outputs = self.get_all_output()
|
||||
await self.send_default_request()
|
||||
outputs = await self.get_all_output()
|
||||
self.validate_outputs(
|
||||
outputs,
|
||||
modifiers=[update_expected_server],
|
||||
@ -701,7 +700,7 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
new_sem_conv=True,
|
||||
)
|
||||
|
||||
def test_behavior_with_scope_server_as_none_both_semconv(self):
|
||||
async def test_behavior_with_scope_server_as_none_both_semconv(self):
|
||||
"""Test that middleware is ok when server is none in scope."""
|
||||
|
||||
def update_expected_server(expected):
|
||||
@ -719,8 +718,8 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
self.scope["server"] = None
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
outputs = self.get_all_output()
|
||||
await self.send_default_request()
|
||||
outputs = await self.get_all_output()
|
||||
self.validate_outputs(
|
||||
outputs,
|
||||
modifiers=[update_expected_server],
|
||||
@ -728,7 +727,7 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
new_sem_conv=True,
|
||||
)
|
||||
|
||||
def test_host_header(self):
|
||||
async def test_host_header(self):
|
||||
"""Test that host header is converted to http.server_name."""
|
||||
hostname = b"server_name_1"
|
||||
|
||||
@ -741,11 +740,11 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
self.scope["headers"].append([b"host", hostname])
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
outputs = self.get_all_output()
|
||||
await self.send_default_request()
|
||||
outputs = await self.get_all_output()
|
||||
self.validate_outputs(outputs, modifiers=[update_expected_server])
|
||||
|
||||
def test_host_header_both_semconv(self):
|
||||
async def test_host_header_both_semconv(self):
|
||||
"""Test that host header is converted to http.server_name."""
|
||||
hostname = b"server_name_1"
|
||||
|
||||
@ -758,8 +757,8 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
self.scope["headers"].append([b"host", hostname])
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
outputs = self.get_all_output()
|
||||
await self.send_default_request()
|
||||
outputs = await self.get_all_output()
|
||||
self.validate_outputs(
|
||||
outputs,
|
||||
modifiers=[update_expected_server],
|
||||
@ -767,7 +766,7 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
new_sem_conv=True,
|
||||
)
|
||||
|
||||
def test_user_agent(self):
|
||||
async def test_user_agent(self):
|
||||
"""Test that host header is converted to http.server_name."""
|
||||
user_agent = b"test-agent"
|
||||
|
||||
@ -780,11 +779,11 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
self.scope["headers"].append([b"user-agent", user_agent])
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
outputs = self.get_all_output()
|
||||
await self.send_default_request()
|
||||
outputs = await self.get_all_output()
|
||||
self.validate_outputs(outputs, modifiers=[update_expected_user_agent])
|
||||
|
||||
def test_user_agent_new_semconv(self):
|
||||
async def test_user_agent_new_semconv(self):
|
||||
"""Test that host header is converted to http.server_name."""
|
||||
user_agent = b"test-agent"
|
||||
|
||||
@ -797,8 +796,8 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
self.scope["headers"].append([b"user-agent", user_agent])
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
outputs = self.get_all_output()
|
||||
await self.send_default_request()
|
||||
outputs = await self.get_all_output()
|
||||
self.validate_outputs(
|
||||
outputs,
|
||||
modifiers=[update_expected_user_agent],
|
||||
@ -806,7 +805,7 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
new_sem_conv=True,
|
||||
)
|
||||
|
||||
def test_user_agent_both_semconv(self):
|
||||
async def test_user_agent_both_semconv(self):
|
||||
"""Test that host header is converted to http.server_name."""
|
||||
user_agent = b"test-agent"
|
||||
|
||||
@ -822,8 +821,8 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
self.scope["headers"].append([b"user-agent", user_agent])
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
outputs = self.get_all_output()
|
||||
await self.send_default_request()
|
||||
outputs = await self.get_all_output()
|
||||
self.validate_outputs(
|
||||
outputs,
|
||||
modifiers=[update_expected_user_agent],
|
||||
@ -831,7 +830,7 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
new_sem_conv=True,
|
||||
)
|
||||
|
||||
def test_traceresponse_header(self):
|
||||
async def test_traceresponse_header(self):
|
||||
"""Test a traceresponse header is sent when a global propagator is set."""
|
||||
|
||||
orig = get_global_response_propagator()
|
||||
@ -839,12 +838,12 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
response_start, response_body, *_ = await self.get_all_output()
|
||||
|
||||
span = self.memory_exporter.get_finished_spans()[-1]
|
||||
self.assertEqual(trace_api.SpanKind.SERVER, span.kind)
|
||||
|
||||
response_start, response_body, *_ = self.get_all_output()
|
||||
self.assertEqual(response_body["body"], b"*")
|
||||
self.assertEqual(response_start["status"], 200)
|
||||
|
||||
@ -864,7 +863,7 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
|
||||
set_global_response_propagator(orig)
|
||||
|
||||
def test_websocket(self):
|
||||
async def test_websocket(self):
|
||||
self.scope = {
|
||||
"method": "GET",
|
||||
"type": "websocket",
|
||||
@ -878,10 +877,10 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
}
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_input({"type": "websocket.connect"})
|
||||
self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
self.send_input({"type": "websocket.disconnect"})
|
||||
self.get_all_output()
|
||||
await self.send_input({"type": "websocket.connect"})
|
||||
await self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
await self.send_input({"type": "websocket.disconnect"})
|
||||
await self.get_all_output()
|
||||
span_list = self.memory_exporter.get_finished_spans()
|
||||
self.assertEqual(len(span_list), 6)
|
||||
expected = [
|
||||
@ -938,7 +937,7 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
self.assertEqual(span.kind, expected["kind"])
|
||||
self.assertDictEqual(dict(span.attributes), expected["attributes"])
|
||||
|
||||
def test_websocket_new_semconv(self):
|
||||
async def test_websocket_new_semconv(self):
|
||||
self.scope = {
|
||||
"method": "GET",
|
||||
"type": "websocket",
|
||||
@ -952,10 +951,10 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
}
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_input({"type": "websocket.connect"})
|
||||
self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
self.send_input({"type": "websocket.disconnect"})
|
||||
self.get_all_output()
|
||||
await self.send_input({"type": "websocket.connect"})
|
||||
await self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
await self.send_input({"type": "websocket.disconnect"})
|
||||
await self.get_all_output()
|
||||
span_list = self.memory_exporter.get_finished_spans()
|
||||
self.assertEqual(len(span_list), 6)
|
||||
expected = [
|
||||
@ -1010,7 +1009,7 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
self.assertEqual(span.kind, expected["kind"])
|
||||
self.assertDictEqual(dict(span.attributes), expected["attributes"])
|
||||
|
||||
def test_websocket_both_semconv(self):
|
||||
async def test_websocket_both_semconv(self):
|
||||
self.scope = {
|
||||
"method": "GET",
|
||||
"type": "websocket",
|
||||
@ -1024,10 +1023,10 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
}
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_input({"type": "websocket.connect"})
|
||||
self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
self.send_input({"type": "websocket.disconnect"})
|
||||
self.get_all_output()
|
||||
await self.send_input({"type": "websocket.connect"})
|
||||
await self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
await self.send_input({"type": "websocket.disconnect"})
|
||||
await self.get_all_output()
|
||||
span_list = self.memory_exporter.get_finished_spans()
|
||||
self.assertEqual(len(span_list), 6)
|
||||
expected = [
|
||||
@ -1094,7 +1093,7 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
self.assertEqual(span.kind, expected["kind"])
|
||||
self.assertDictEqual(dict(span.attributes), expected["attributes"])
|
||||
|
||||
def test_websocket_traceresponse_header(self):
|
||||
async def test_websocket_traceresponse_header(self):
|
||||
"""Test a traceresponse header is set for websocket messages"""
|
||||
|
||||
orig = get_global_response_propagator()
|
||||
@ -1112,10 +1111,10 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
}
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_input({"type": "websocket.connect"})
|
||||
self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
self.send_input({"type": "websocket.disconnect"})
|
||||
_, socket_send, *_ = self.get_all_output()
|
||||
await self.send_input({"type": "websocket.connect"})
|
||||
await self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
await self.send_input({"type": "websocket.disconnect"})
|
||||
_, socket_send, *_ = await self.get_all_output()
|
||||
|
||||
span = self.memory_exporter.get_finished_spans()[-1]
|
||||
self.assertEqual(trace_api.SpanKind.SERVER, span.kind)
|
||||
@ -1134,15 +1133,15 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
|
||||
set_global_response_propagator(orig)
|
||||
|
||||
def test_lifespan(self):
|
||||
async def test_lifespan(self):
|
||||
self.scope["type"] = "lifespan"
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
span_list = self.memory_exporter.get_finished_spans()
|
||||
self.assertEqual(len(span_list), 0)
|
||||
|
||||
def test_hooks(self):
|
||||
async def test_hooks(self):
|
||||
def server_request_hook(span, scope):
|
||||
span.update_name("name from server hook")
|
||||
|
||||
@ -1169,20 +1168,23 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
client_response_hook=client_response_hook,
|
||||
)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
outputs = self.get_all_output()
|
||||
await self.send_default_request()
|
||||
outputs = await self.get_all_output()
|
||||
self.validate_outputs(
|
||||
outputs, modifiers=[update_expected_hook_results]
|
||||
)
|
||||
|
||||
def test_asgi_metrics(self):
|
||||
async def test_asgi_metrics(self):
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
await self.get_all_output()
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
await self.get_all_output()
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
await self.get_all_output()
|
||||
metrics_list = self.memory_metrics_reader.get_metrics_data()
|
||||
number_data_point_seen = False
|
||||
histogram_data_point_seen = False
|
||||
@ -1211,14 +1213,17 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
)
|
||||
self.assertTrue(number_data_point_seen and histogram_data_point_seen)
|
||||
|
||||
def test_asgi_metrics_new_semconv(self):
|
||||
async def test_asgi_metrics_new_semconv(self):
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
await self.get_all_output()
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
await self.get_all_output()
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
await self.get_all_output()
|
||||
metrics_list = self.memory_metrics_reader.get_metrics_data()
|
||||
number_data_point_seen = False
|
||||
histogram_data_point_seen = False
|
||||
@ -1247,14 +1252,17 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
)
|
||||
self.assertTrue(number_data_point_seen and histogram_data_point_seen)
|
||||
|
||||
def test_asgi_metrics_both_semconv(self):
|
||||
async def test_asgi_metrics_both_semconv(self):
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
await self.get_all_output()
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
await self.get_all_output()
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
await self.get_all_output()
|
||||
metrics_list = self.memory_metrics_reader.get_metrics_data()
|
||||
number_data_point_seen = False
|
||||
histogram_data_point_seen = False
|
||||
@ -1283,12 +1291,13 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
)
|
||||
self.assertTrue(number_data_point_seen and histogram_data_point_seen)
|
||||
|
||||
def test_basic_metric_success(self):
|
||||
async def test_basic_metric_success(self):
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
start = default_timer()
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
duration = max(round((default_timer() - start) * 1000), 0)
|
||||
await self.get_all_output()
|
||||
expected_duration_attributes = {
|
||||
"http.method": "GET",
|
||||
"http.host": "127.0.0.1",
|
||||
@ -1330,7 +1339,7 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
)
|
||||
self.assertEqual(point.value, 0)
|
||||
|
||||
def test_basic_metric_success_nonrecording_span(self):
|
||||
async def test_basic_metric_success_nonrecording_span(self):
|
||||
mock_tracer = mock.Mock()
|
||||
mock_span = mock.Mock()
|
||||
mock_span.is_recording.return_value = False
|
||||
@ -1344,8 +1353,9 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
start = default_timer()
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
duration = max(round((default_timer() - start) * 1000), 0)
|
||||
await self.get_all_output()
|
||||
expected_duration_attributes = {
|
||||
"http.method": "GET",
|
||||
"http.host": "127.0.0.1",
|
||||
@ -1374,7 +1384,7 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
self.assertEqual(point.count, 1)
|
||||
if metric.name == "http.server.duration":
|
||||
self.assertAlmostEqual(
|
||||
duration, point.sum, delta=5
|
||||
duration, point.sum, delta=15
|
||||
)
|
||||
elif (
|
||||
metric.name == "http.server.response.size"
|
||||
@ -1389,12 +1399,13 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
)
|
||||
self.assertEqual(point.value, 0)
|
||||
|
||||
def test_basic_metric_success_new_semconv(self):
|
||||
async def test_basic_metric_success_new_semconv(self):
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
start = default_timer()
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
duration_s = max(default_timer() - start, 0)
|
||||
await self.get_all_output()
|
||||
expected_duration_attributes = {
|
||||
"http.request.method": "GET",
|
||||
"url.scheme": "http",
|
||||
@ -1436,13 +1447,14 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
)
|
||||
self.assertEqual(point.value, 0)
|
||||
|
||||
def test_basic_metric_success_both_semconv(self):
|
||||
async def test_basic_metric_success_both_semconv(self):
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
start = default_timer()
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
duration = max(round((default_timer() - start) * 1000), 0)
|
||||
duration_s = max(default_timer() - start, 0)
|
||||
await self.get_all_output()
|
||||
expected_duration_attributes_old = {
|
||||
"http.method": "GET",
|
||||
"http.host": "127.0.0.1",
|
||||
@ -1524,7 +1536,7 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
)
|
||||
self.assertEqual(point.value, 0)
|
||||
|
||||
def test_metric_target_attribute(self):
|
||||
async def test_metric_target_attribute(self):
|
||||
expected_target = "/api/user/{id}"
|
||||
|
||||
class TestRoute:
|
||||
@ -1540,7 +1552,8 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
|
||||
app = otel_asgi.OpenTelemetryMiddleware(target_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
await self.get_all_output()
|
||||
metrics_list = self.memory_metrics_reader.get_metrics_data()
|
||||
assertions = 0
|
||||
for resource_metric in metrics_list.resource_metrics:
|
||||
@ -1557,7 +1570,7 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
assertions += 1
|
||||
self.assertEqual(assertions, 3)
|
||||
|
||||
def test_no_metric_for_websockets(self):
|
||||
async def test_no_metric_for_websockets(self):
|
||||
self.scope = {
|
||||
"type": "websocket",
|
||||
"http_version": "1.1",
|
||||
@ -1570,10 +1583,10 @@ class TestAsgiApplication(AsgiTestBase):
|
||||
}
|
||||
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
|
||||
self.seed_app(app)
|
||||
self.send_input({"type": "websocket.connect"})
|
||||
self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
self.send_input({"type": "websocket.disconnect"})
|
||||
self.get_all_output()
|
||||
await self.send_input({"type": "websocket.connect"})
|
||||
await self.send_input({"type": "websocket.receive", "text": "ping"})
|
||||
await self.send_input({"type": "websocket.disconnect"})
|
||||
await self.get_all_output()
|
||||
self.assertIsNone(self.memory_metrics_reader.get_metrics_data())
|
||||
|
||||
|
||||
@ -1790,8 +1803,10 @@ class TestAsgiAttributes(unittest.TestCase):
|
||||
)
|
||||
|
||||
|
||||
class TestWrappedApplication(AsgiTestBase):
|
||||
def test_mark_span_internal_in_presence_of_span_from_other_framework(self):
|
||||
class TestWrappedApplication(AsyncAsgiTestBase):
|
||||
async def test_mark_span_internal_in_presence_of_span_from_other_framework(
|
||||
self,
|
||||
):
|
||||
tracer_provider, exporter = TestBase.create_tracer_provider()
|
||||
tracer = tracer_provider.get_tracer(__name__)
|
||||
app = otel_asgi.OpenTelemetryMiddleware(
|
||||
@ -1806,7 +1821,8 @@ class TestWrappedApplication(AsgiTestBase):
|
||||
await app(scope, receive, send)
|
||||
|
||||
self.seed_app(wrapped_app)
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
await self.get_all_output()
|
||||
span_list = exporter.get_finished_spans()
|
||||
|
||||
self.assertEqual(SpanKind.INTERNAL, span_list[0].kind)
|
||||
@ -1823,11 +1839,11 @@ class TestWrappedApplication(AsgiTestBase):
|
||||
)
|
||||
|
||||
|
||||
class TestAsgiApplicationRaisingError(AsgiTestBase):
|
||||
class TestAsgiApplicationRaisingError(AsyncAsgiTestBase):
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_asgi_issue_1883(self):
|
||||
async def test_asgi_value_error_exception(self):
|
||||
"""
|
||||
Test that exception UnboundLocalError local variable 'start' referenced before assignment is not raised
|
||||
See https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1883
|
||||
@ -1838,11 +1854,9 @@ class TestAsgiApplicationRaisingError(AsgiTestBase):
|
||||
|
||||
app = otel_asgi.OpenTelemetryMiddleware(bad_app)
|
||||
self.seed_app(app)
|
||||
self.send_default_request()
|
||||
await self.send_default_request()
|
||||
try:
|
||||
asyncio.get_event_loop().run_until_complete(
|
||||
self.communicator.stop()
|
||||
)
|
||||
await self.communicator.wait()
|
||||
except ValueError as exc_info:
|
||||
self.assertEqual(exc_info.args[0], "whatever")
|
||||
except Exception as exc_info: # pylint: disable=W0703
|
||||
|
Reference in New Issue
Block a user