Prepare asgi tests to support newer asgiref version (#2778)

This commit is contained in:
Riccardo Magliocchetti
2024-08-26 18:38:07 +02:00
committed by GitHub
parent bc4d2c5b75
commit 19f8e775ce
2 changed files with 195 additions and 163 deletions

View File

@ -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 os
import opentelemetry.instrumentation.asgi as otel_asgi 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.test.test_base import TestBase
from opentelemetry.trace import SpanKind from opentelemetry.trace import SpanKind
from opentelemetry.util.http import ( from opentelemetry.util.http import (
@ -90,7 +104,7 @@ async def websocket_app_with_custom_headers(scope, receive, send):
break break
class TestCustomHeaders(AsgiTestBase, TestBase): class TestCustomHeaders(AsyncAsgiTestBase):
constructor_params = {} constructor_params = {}
__test__ = False __test__ = False
@ -108,7 +122,7 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
**self.constructor_params, **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( self.scope["headers"].extend(
[ [
(b"custom-test-header-1", b"test-header-value-1"), (b"custom-test-header-1", b"test-header-value-1"),
@ -119,8 +133,8 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
] ]
) )
self.seed_app(self.app) self.seed_app(self.app)
self.send_default_request() await self.send_default_request()
self.get_all_output() await self.get_all_output()
span_list = self.exporter.get_finished_spans() span_list = self.exporter.get_finished_spans()
expected = { expected = {
"http.request.header.custom_test_header_1": ( "http.request.header.custom_test_header_1": (
@ -139,7 +153,7 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
if span.kind == SpanKind.SERVER: if span.kind == SpanKind.SERVER:
self.assertSpanHasAttributes(span, expected) 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( self.scope["headers"].extend(
[ [
(b"custom-test-header-1", b"test-header-value-1"), (b"custom-test-header-1", b"test-header-value-1"),
@ -147,8 +161,8 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
] ]
) )
self.seed_app(self.app) self.seed_app(self.app)
self.send_default_request() await self.send_default_request()
self.get_all_output() await self.get_all_output()
span_list = self.exporter.get_finished_spans() span_list = self.exporter.get_finished_spans()
expected = { expected = {
"http.request.header.custom_test_header_1": ( "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) span = next(span for span in span_list if span.kind == SpanKind.SERVER)
self.assertSpanHasAttributes(span, expected) 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( self.scope["headers"].extend(
[ [
(b"custom-test-header-1", b"test-header-value-1"), (b"custom-test-header-1", b"test-header-value-1"),
] ]
) )
self.seed_app(self.app) self.seed_app(self.app)
self.send_default_request() await self.send_default_request()
self.get_all_output() await self.get_all_output()
span_list = self.exporter.get_finished_spans() span_list = self.exporter.get_finished_spans()
expected = { expected = {
"http.request.header.custom_test_header_1": ( "http.request.header.custom_test_header_1": (
@ -185,15 +199,15 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
for key, _ in not_expected.items(): for key, _ in not_expected.items():
self.assertNotIn(key, span.attributes) 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( self.app = otel_asgi.OpenTelemetryMiddleware(
http_app_with_custom_headers, http_app_with_custom_headers,
tracer_provider=self.tracer_provider, tracer_provider=self.tracer_provider,
**self.constructor_params, **self.constructor_params,
) )
self.seed_app(self.app) self.seed_app(self.app)
self.send_default_request() await self.send_default_request()
self.get_all_output() await self.get_all_output()
span_list = self.exporter.get_finished_spans() span_list = self.exporter.get_finished_spans()
expected = { expected = {
"http.response.header.custom_test_header_1": ( "http.response.header.custom_test_header_1": (
@ -214,15 +228,15 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
if span.kind == SpanKind.SERVER: if span.kind == SpanKind.SERVER:
self.assertSpanHasAttributes(span, expected) 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( self.app = otel_asgi.OpenTelemetryMiddleware(
http_app_with_repeat_headers, http_app_with_repeat_headers,
tracer_provider=self.tracer_provider, tracer_provider=self.tracer_provider,
**self.constructor_params, **self.constructor_params,
) )
self.seed_app(self.app) self.seed_app(self.app)
self.send_default_request() await self.send_default_request()
self.get_all_output() await self.get_all_output()
span_list = self.exporter.get_finished_spans() span_list = self.exporter.get_finished_spans()
expected = { expected = {
"http.response.header.custom_test_header_1": ( "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) span = next(span for span in span_list if span.kind == SpanKind.SERVER)
self.assertSpanHasAttributes(span, expected) 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( self.app = otel_asgi.OpenTelemetryMiddleware(
http_app_with_custom_headers, http_app_with_custom_headers,
tracer_provider=self.tracer_provider, tracer_provider=self.tracer_provider,
**self.constructor_params, **self.constructor_params,
) )
self.seed_app(self.app) self.seed_app(self.app)
self.send_default_request() await self.send_default_request()
self.get_all_output() await self.get_all_output()
span_list = self.exporter.get_finished_spans() span_list = self.exporter.get_finished_spans()
not_expected = { not_expected = {
"http.response.header.custom_test_header_3": ( "http.response.header.custom_test_header_3": (
@ -253,7 +267,7 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
for key, _ in not_expected.items(): for key, _ in not_expected.items():
self.assertNotIn(key, span.attributes) 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 = { self.scope = {
"type": "websocket", "type": "websocket",
"http_version": "1.1", "http_version": "1.1",
@ -271,11 +285,11 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
"server": ("127.0.0.1", 80), "server": ("127.0.0.1", 80),
} }
self.seed_app(self.app) self.seed_app(self.app)
self.send_input({"type": "websocket.connect"}) await self.send_input({"type": "websocket.connect"})
self.send_input({"type": "websocket.receive", "text": "ping"}) await self.send_input({"type": "websocket.receive", "text": "ping"})
self.send_input({"type": "websocket.disconnect"}) await self.send_input({"type": "websocket.disconnect"})
self.get_all_output() await self.get_all_output()
span_list = self.exporter.get_finished_spans() span_list = self.exporter.get_finished_spans()
expected = { expected = {
"http.request.header.custom_test_header_1": ( "http.request.header.custom_test_header_1": (
@ -294,7 +308,9 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
if span.kind == SpanKind.SERVER: if span.kind == SpanKind.SERVER:
self.assertSpanHasAttributes(span, expected) 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 = { self.scope = {
"type": "websocket", "type": "websocket",
"http_version": "1.1", "http_version": "1.1",
@ -309,11 +325,11 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
"server": ("127.0.0.1", 80), "server": ("127.0.0.1", 80),
} }
self.seed_app(self.app) self.seed_app(self.app)
self.send_input({"type": "websocket.connect"}) await self.send_input({"type": "websocket.connect"})
self.send_input({"type": "websocket.receive", "text": "ping"}) await self.send_input({"type": "websocket.receive", "text": "ping"})
self.send_input({"type": "websocket.disconnect"}) await self.send_input({"type": "websocket.disconnect"})
self.get_all_output() await self.get_all_output()
span_list = self.exporter.get_finished_spans() span_list = self.exporter.get_finished_spans()
not_expected = { not_expected = {
"http.request.header.custom_test_header_3": ( "http.request.header.custom_test_header_3": (
@ -325,7 +341,7 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
for key, _ in not_expected.items(): for key, _ in not_expected.items():
self.assertNotIn(key, span.attributes) 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 = { self.scope = {
"type": "websocket", "type": "websocket",
"http_version": "1.1", "http_version": "1.1",
@ -342,10 +358,10 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
**self.constructor_params, **self.constructor_params,
) )
self.seed_app(self.app) self.seed_app(self.app)
self.send_input({"type": "websocket.connect"}) await self.send_input({"type": "websocket.connect"})
self.send_input({"type": "websocket.receive", "text": "ping"}) await self.send_input({"type": "websocket.receive", "text": "ping"})
self.send_input({"type": "websocket.disconnect"}) await self.send_input({"type": "websocket.disconnect"})
self.get_all_output() await self.get_all_output()
span_list = self.exporter.get_finished_spans() span_list = self.exporter.get_finished_spans()
expected = { expected = {
"http.response.header.custom_test_header_1": ( "http.response.header.custom_test_header_1": (
@ -366,7 +382,9 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
if span.kind == SpanKind.SERVER: if span.kind == SpanKind.SERVER:
self.assertSpanHasAttributes(span, expected) 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 = { self.scope = {
"type": "websocket", "type": "websocket",
"http_version": "1.1", "http_version": "1.1",
@ -383,10 +401,10 @@ class TestCustomHeaders(AsgiTestBase, TestBase):
**self.constructor_params, **self.constructor_params,
) )
self.seed_app(self.app) self.seed_app(self.app)
self.send_input({"type": "websocket.connect"}) await self.send_input({"type": "websocket.connect"})
self.send_input({"type": "websocket.receive", "text": "ping"}) await self.send_input({"type": "websocket.receive", "text": "ping"})
self.send_input({"type": "websocket.disconnect"}) await self.send_input({"type": "websocket.disconnect"})
self.get_all_output() await self.get_all_output()
span_list = self.exporter.get_finished_spans() span_list = self.exporter.get_finished_spans()
not_expected = { not_expected = {
"http.response.header.custom_test_header_3": ( "http.response.header.custom_test_header_3": (

View File

@ -14,7 +14,6 @@
# pylint: disable=too-many-lines # pylint: disable=too-many-lines
import asyncio
import sys import sys
import time import time
import unittest import unittest
@ -64,7 +63,7 @@ from opentelemetry.semconv.attributes.user_agent_attributes import (
) )
from opentelemetry.semconv.trace import SpanAttributes from opentelemetry.semconv.trace import SpanAttributes
from opentelemetry.test.asgitestutil import ( from opentelemetry.test.asgitestutil import (
AsgiTestBase, AsyncAsgiTestBase,
setup_testing_defaults, setup_testing_defaults,
) )
from opentelemetry.test.test_base import TestBase from opentelemetry.test.test_base import TestBase
@ -275,7 +274,7 @@ async def error_asgi(scope, receive, send):
# pylint: disable=too-many-public-methods # pylint: disable=too-many-public-methods
class TestAsgiApplication(AsgiTestBase): class TestAsgiApplication(AsyncAsgiTestBase):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
@ -477,31 +476,31 @@ class TestAsgiApplication(AsgiTestBase):
"opentelemetry.instrumentation.asgi", "opentelemetry.instrumentation.asgi",
) )
def test_basic_asgi_call(self): async def test_basic_asgi_call(self):
"""Test that spans are emitted as expected.""" """Test that spans are emitted as expected."""
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
outputs = self.get_all_output() outputs = await self.get_all_output()
self.validate_outputs(outputs) 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.""" """Test that spans are emitted as expected."""
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
outputs = self.get_all_output() outputs = await self.get_all_output()
self.validate_outputs(outputs, old_sem_conv=False, new_sem_conv=True) 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.""" """Test that spans are emitted as expected."""
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
outputs = self.get_all_output() outputs = await self.get_all_output()
self.validate_outputs(outputs, old_sem_conv=True, new_sem_conv=True) 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_tracer = mock.Mock()
mock_span = mock.Mock() mock_span = mock.Mock()
mock_span.is_recording.return_value = False mock_span.is_recording.return_value = False
@ -514,21 +513,21 @@ class TestAsgiApplication(AsgiTestBase):
tracer.return_value = mock_tracer tracer.return_value = mock_tracer
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
self.assertFalse(mock_span.is_recording()) self.assertFalse(mock_span.is_recording())
self.assertTrue(mock_span.is_recording.called) self.assertTrue(mock_span.is_recording.called)
self.assertFalse(mock_span.set_attribute.called) self.assertFalse(mock_span.set_attribute.called)
self.assertFalse(mock_span.set_status.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.""" """Test that exception information is emitted as expected."""
app = otel_asgi.OpenTelemetryMiddleware(error_asgi) app = otel_asgi.OpenTelemetryMiddleware(error_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
outputs = self.get_all_output() outputs = await self.get_all_output()
self.validate_outputs(outputs, error=ValueError) 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. """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 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) app = otel_asgi.OpenTelemetryMiddleware(long_response_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
outputs = self.get_all_output() outputs = await self.get_all_output()
def add_more_body_spans(expected: list): def add_more_body_spans(expected: list):
more_body_span = { more_body_span = {
@ -551,12 +550,12 @@ class TestAsgiApplication(AsgiTestBase):
self.validate_outputs(outputs, modifiers=[add_more_body_spans]) 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.""" """Test that the server span is ended BEFORE the background task is finished."""
app = otel_asgi.OpenTelemetryMiddleware(background_execution_asgi) app = otel_asgi.OpenTelemetryMiddleware(background_execution_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
outputs = self.get_all_output() outputs = await self.get_all_output()
self.validate_outputs(outputs) self.validate_outputs(outputs)
span_list = self.memory_exporter.get_finished_spans() span_list = self.memory_exporter.get_finished_spans()
server_span = span_list[-1] server_span = span_list[-1]
@ -567,15 +566,15 @@ class TestAsgiApplication(AsgiTestBase):
_SIMULATED_BACKGROUND_TASK_EXECUTION_TIME_S * 10**9, _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 """Test that trailers are emitted as expected and that the server span is ended
BEFORE the background task is finished.""" BEFORE the background task is finished."""
app = otel_asgi.OpenTelemetryMiddleware( app = otel_asgi.OpenTelemetryMiddleware(
background_execution_trailers_asgi background_execution_trailers_asgi
) )
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
outputs = self.get_all_output() outputs = await self.get_all_output()
def add_body_and_trailer_span(expected: list): def add_body_and_trailer_span(expected: list):
body_span = { body_span = {
@ -602,7 +601,7 @@ class TestAsgiApplication(AsgiTestBase):
_SIMULATED_BACKGROUND_TASK_EXECUTION_TIME_S * 10**9, _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.""" """Test that default span_names can be overwritten by our callback function."""
span_name = "Dymaxion" span_name = "Dymaxion"
@ -623,11 +622,11 @@ class TestAsgiApplication(AsgiTestBase):
simple_asgi, default_span_details=get_predefined_span_details simple_asgi, default_span_details=get_predefined_span_details
) )
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
outputs = self.get_all_output() outputs = await self.get_all_output()
self.validate_outputs(outputs, modifiers=[update_expected_span_name]) 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"}) resource = resources.Resource.create({"service-test-key": "value"})
result = TestBase.create_tracer_provider(resource=resource) result = TestBase.create_tracer_provider(resource=resource)
tracer_provider, exporter = result tracer_provider, exporter = result
@ -636,28 +635,28 @@ class TestAsgiApplication(AsgiTestBase):
simple_asgi, tracer_provider=tracer_provider simple_asgi, tracer_provider=tracer_provider
) )
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
span_list = exporter.get_finished_spans() span_list = exporter.get_finished_spans()
for span in span_list: for span in span_list:
self.assertEqual( self.assertEqual(
span.resource.attributes["service-test-key"], "value" 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( app = otel_asgi.OpenTelemetryMiddleware(
simple_asgi, tracer_provider=trace_api.NoOpTracerProvider() simple_asgi, tracer_provider=trace_api.NoOpTracerProvider()
) )
self.seed_app(app) 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_body["body"], b"*")
self.assertEqual(response_start["status"], 200) self.assertEqual(response_start["status"], 200)
span_list = self.memory_exporter.get_finished_spans() span_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(span_list), 0) 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.""" """Test that middleware is ok when server is none in scope."""
def update_expected_server(expected): def update_expected_server(expected):
@ -673,11 +672,11 @@ class TestAsgiApplication(AsgiTestBase):
self.scope["server"] = None self.scope["server"] = None
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
outputs = self.get_all_output() outputs = await self.get_all_output()
self.validate_outputs(outputs, modifiers=[update_expected_server]) 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.""" """Test that middleware is ok when server is none in scope."""
def update_expected_server(expected): def update_expected_server(expected):
@ -692,8 +691,8 @@ class TestAsgiApplication(AsgiTestBase):
self.scope["server"] = None self.scope["server"] = None
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
outputs = self.get_all_output() outputs = await self.get_all_output()
self.validate_outputs( self.validate_outputs(
outputs, outputs,
modifiers=[update_expected_server], modifiers=[update_expected_server],
@ -701,7 +700,7 @@ class TestAsgiApplication(AsgiTestBase):
new_sem_conv=True, 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.""" """Test that middleware is ok when server is none in scope."""
def update_expected_server(expected): def update_expected_server(expected):
@ -719,8 +718,8 @@ class TestAsgiApplication(AsgiTestBase):
self.scope["server"] = None self.scope["server"] = None
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
outputs = self.get_all_output() outputs = await self.get_all_output()
self.validate_outputs( self.validate_outputs(
outputs, outputs,
modifiers=[update_expected_server], modifiers=[update_expected_server],
@ -728,7 +727,7 @@ class TestAsgiApplication(AsgiTestBase):
new_sem_conv=True, 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.""" """Test that host header is converted to http.server_name."""
hostname = b"server_name_1" hostname = b"server_name_1"
@ -741,11 +740,11 @@ class TestAsgiApplication(AsgiTestBase):
self.scope["headers"].append([b"host", hostname]) self.scope["headers"].append([b"host", hostname])
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
outputs = self.get_all_output() outputs = await self.get_all_output()
self.validate_outputs(outputs, modifiers=[update_expected_server]) 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.""" """Test that host header is converted to http.server_name."""
hostname = b"server_name_1" hostname = b"server_name_1"
@ -758,8 +757,8 @@ class TestAsgiApplication(AsgiTestBase):
self.scope["headers"].append([b"host", hostname]) self.scope["headers"].append([b"host", hostname])
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
outputs = self.get_all_output() outputs = await self.get_all_output()
self.validate_outputs( self.validate_outputs(
outputs, outputs,
modifiers=[update_expected_server], modifiers=[update_expected_server],
@ -767,7 +766,7 @@ class TestAsgiApplication(AsgiTestBase):
new_sem_conv=True, 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.""" """Test that host header is converted to http.server_name."""
user_agent = b"test-agent" user_agent = b"test-agent"
@ -780,11 +779,11 @@ class TestAsgiApplication(AsgiTestBase):
self.scope["headers"].append([b"user-agent", user_agent]) self.scope["headers"].append([b"user-agent", user_agent])
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
outputs = self.get_all_output() outputs = await self.get_all_output()
self.validate_outputs(outputs, modifiers=[update_expected_user_agent]) 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.""" """Test that host header is converted to http.server_name."""
user_agent = b"test-agent" user_agent = b"test-agent"
@ -797,8 +796,8 @@ class TestAsgiApplication(AsgiTestBase):
self.scope["headers"].append([b"user-agent", user_agent]) self.scope["headers"].append([b"user-agent", user_agent])
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
outputs = self.get_all_output() outputs = await self.get_all_output()
self.validate_outputs( self.validate_outputs(
outputs, outputs,
modifiers=[update_expected_user_agent], modifiers=[update_expected_user_agent],
@ -806,7 +805,7 @@ class TestAsgiApplication(AsgiTestBase):
new_sem_conv=True, 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.""" """Test that host header is converted to http.server_name."""
user_agent = b"test-agent" user_agent = b"test-agent"
@ -822,8 +821,8 @@ class TestAsgiApplication(AsgiTestBase):
self.scope["headers"].append([b"user-agent", user_agent]) self.scope["headers"].append([b"user-agent", user_agent])
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
outputs = self.get_all_output() outputs = await self.get_all_output()
self.validate_outputs( self.validate_outputs(
outputs, outputs,
modifiers=[update_expected_user_agent], modifiers=[update_expected_user_agent],
@ -831,7 +830,7 @@ class TestAsgiApplication(AsgiTestBase):
new_sem_conv=True, 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.""" """Test a traceresponse header is sent when a global propagator is set."""
orig = get_global_response_propagator() orig = get_global_response_propagator()
@ -839,12 +838,12 @@ class TestAsgiApplication(AsgiTestBase):
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) 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] span = self.memory_exporter.get_finished_spans()[-1]
self.assertEqual(trace_api.SpanKind.SERVER, span.kind) 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_body["body"], b"*")
self.assertEqual(response_start["status"], 200) self.assertEqual(response_start["status"], 200)
@ -864,7 +863,7 @@ class TestAsgiApplication(AsgiTestBase):
set_global_response_propagator(orig) set_global_response_propagator(orig)
def test_websocket(self): async def test_websocket(self):
self.scope = { self.scope = {
"method": "GET", "method": "GET",
"type": "websocket", "type": "websocket",
@ -878,10 +877,10 @@ class TestAsgiApplication(AsgiTestBase):
} }
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_input({"type": "websocket.connect"}) await self.send_input({"type": "websocket.connect"})
self.send_input({"type": "websocket.receive", "text": "ping"}) await self.send_input({"type": "websocket.receive", "text": "ping"})
self.send_input({"type": "websocket.disconnect"}) await self.send_input({"type": "websocket.disconnect"})
self.get_all_output() await self.get_all_output()
span_list = self.memory_exporter.get_finished_spans() span_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(span_list), 6) self.assertEqual(len(span_list), 6)
expected = [ expected = [
@ -938,7 +937,7 @@ class TestAsgiApplication(AsgiTestBase):
self.assertEqual(span.kind, expected["kind"]) self.assertEqual(span.kind, expected["kind"])
self.assertDictEqual(dict(span.attributes), expected["attributes"]) self.assertDictEqual(dict(span.attributes), expected["attributes"])
def test_websocket_new_semconv(self): async def test_websocket_new_semconv(self):
self.scope = { self.scope = {
"method": "GET", "method": "GET",
"type": "websocket", "type": "websocket",
@ -952,10 +951,10 @@ class TestAsgiApplication(AsgiTestBase):
} }
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_input({"type": "websocket.connect"}) await self.send_input({"type": "websocket.connect"})
self.send_input({"type": "websocket.receive", "text": "ping"}) await self.send_input({"type": "websocket.receive", "text": "ping"})
self.send_input({"type": "websocket.disconnect"}) await self.send_input({"type": "websocket.disconnect"})
self.get_all_output() await self.get_all_output()
span_list = self.memory_exporter.get_finished_spans() span_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(span_list), 6) self.assertEqual(len(span_list), 6)
expected = [ expected = [
@ -1010,7 +1009,7 @@ class TestAsgiApplication(AsgiTestBase):
self.assertEqual(span.kind, expected["kind"]) self.assertEqual(span.kind, expected["kind"])
self.assertDictEqual(dict(span.attributes), expected["attributes"]) self.assertDictEqual(dict(span.attributes), expected["attributes"])
def test_websocket_both_semconv(self): async def test_websocket_both_semconv(self):
self.scope = { self.scope = {
"method": "GET", "method": "GET",
"type": "websocket", "type": "websocket",
@ -1024,10 +1023,10 @@ class TestAsgiApplication(AsgiTestBase):
} }
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_input({"type": "websocket.connect"}) await self.send_input({"type": "websocket.connect"})
self.send_input({"type": "websocket.receive", "text": "ping"}) await self.send_input({"type": "websocket.receive", "text": "ping"})
self.send_input({"type": "websocket.disconnect"}) await self.send_input({"type": "websocket.disconnect"})
self.get_all_output() await self.get_all_output()
span_list = self.memory_exporter.get_finished_spans() span_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(span_list), 6) self.assertEqual(len(span_list), 6)
expected = [ expected = [
@ -1094,7 +1093,7 @@ class TestAsgiApplication(AsgiTestBase):
self.assertEqual(span.kind, expected["kind"]) self.assertEqual(span.kind, expected["kind"])
self.assertDictEqual(dict(span.attributes), expected["attributes"]) 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""" """Test a traceresponse header is set for websocket messages"""
orig = get_global_response_propagator() orig = get_global_response_propagator()
@ -1112,10 +1111,10 @@ class TestAsgiApplication(AsgiTestBase):
} }
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_input({"type": "websocket.connect"}) await self.send_input({"type": "websocket.connect"})
self.send_input({"type": "websocket.receive", "text": "ping"}) await self.send_input({"type": "websocket.receive", "text": "ping"})
self.send_input({"type": "websocket.disconnect"}) await self.send_input({"type": "websocket.disconnect"})
_, socket_send, *_ = self.get_all_output() _, socket_send, *_ = await self.get_all_output()
span = self.memory_exporter.get_finished_spans()[-1] span = self.memory_exporter.get_finished_spans()[-1]
self.assertEqual(trace_api.SpanKind.SERVER, span.kind) self.assertEqual(trace_api.SpanKind.SERVER, span.kind)
@ -1134,15 +1133,15 @@ class TestAsgiApplication(AsgiTestBase):
set_global_response_propagator(orig) set_global_response_propagator(orig)
def test_lifespan(self): async def test_lifespan(self):
self.scope["type"] = "lifespan" self.scope["type"] = "lifespan"
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
span_list = self.memory_exporter.get_finished_spans() span_list = self.memory_exporter.get_finished_spans()
self.assertEqual(len(span_list), 0) self.assertEqual(len(span_list), 0)
def test_hooks(self): async def test_hooks(self):
def server_request_hook(span, scope): def server_request_hook(span, scope):
span.update_name("name from server hook") span.update_name("name from server hook")
@ -1169,20 +1168,23 @@ class TestAsgiApplication(AsgiTestBase):
client_response_hook=client_response_hook, client_response_hook=client_response_hook,
) )
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
outputs = self.get_all_output() outputs = await self.get_all_output()
self.validate_outputs( self.validate_outputs(
outputs, modifiers=[update_expected_hook_results] outputs, modifiers=[update_expected_hook_results]
) )
def test_asgi_metrics(self): async def test_asgi_metrics(self):
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
await self.get_all_output()
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
await self.get_all_output()
self.seed_app(app) 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() metrics_list = self.memory_metrics_reader.get_metrics_data()
number_data_point_seen = False number_data_point_seen = False
histogram_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) 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) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
await self.get_all_output()
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
await self.get_all_output()
self.seed_app(app) 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() metrics_list = self.memory_metrics_reader.get_metrics_data()
number_data_point_seen = False number_data_point_seen = False
histogram_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) 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) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
await self.get_all_output()
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
await self.get_all_output()
self.seed_app(app) 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() metrics_list = self.memory_metrics_reader.get_metrics_data()
number_data_point_seen = False number_data_point_seen = False
histogram_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) 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) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
start = default_timer() start = default_timer()
self.send_default_request() await self.send_default_request()
duration = max(round((default_timer() - start) * 1000), 0) duration = max(round((default_timer() - start) * 1000), 0)
await self.get_all_output()
expected_duration_attributes = { expected_duration_attributes = {
"http.method": "GET", "http.method": "GET",
"http.host": "127.0.0.1", "http.host": "127.0.0.1",
@ -1330,7 +1339,7 @@ class TestAsgiApplication(AsgiTestBase):
) )
self.assertEqual(point.value, 0) 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_tracer = mock.Mock()
mock_span = mock.Mock() mock_span = mock.Mock()
mock_span.is_recording.return_value = False mock_span.is_recording.return_value = False
@ -1344,8 +1353,9 @@ class TestAsgiApplication(AsgiTestBase):
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
start = default_timer() start = default_timer()
self.send_default_request() await self.send_default_request()
duration = max(round((default_timer() - start) * 1000), 0) duration = max(round((default_timer() - start) * 1000), 0)
await self.get_all_output()
expected_duration_attributes = { expected_duration_attributes = {
"http.method": "GET", "http.method": "GET",
"http.host": "127.0.0.1", "http.host": "127.0.0.1",
@ -1374,7 +1384,7 @@ class TestAsgiApplication(AsgiTestBase):
self.assertEqual(point.count, 1) self.assertEqual(point.count, 1)
if metric.name == "http.server.duration": if metric.name == "http.server.duration":
self.assertAlmostEqual( self.assertAlmostEqual(
duration, point.sum, delta=5 duration, point.sum, delta=15
) )
elif ( elif (
metric.name == "http.server.response.size" metric.name == "http.server.response.size"
@ -1389,12 +1399,13 @@ class TestAsgiApplication(AsgiTestBase):
) )
self.assertEqual(point.value, 0) 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) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
start = default_timer() start = default_timer()
self.send_default_request() await self.send_default_request()
duration_s = max(default_timer() - start, 0) duration_s = max(default_timer() - start, 0)
await self.get_all_output()
expected_duration_attributes = { expected_duration_attributes = {
"http.request.method": "GET", "http.request.method": "GET",
"url.scheme": "http", "url.scheme": "http",
@ -1436,13 +1447,14 @@ class TestAsgiApplication(AsgiTestBase):
) )
self.assertEqual(point.value, 0) 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) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
start = default_timer() start = default_timer()
self.send_default_request() await self.send_default_request()
duration = max(round((default_timer() - start) * 1000), 0) duration = max(round((default_timer() - start) * 1000), 0)
duration_s = max(default_timer() - start, 0) duration_s = max(default_timer() - start, 0)
await self.get_all_output()
expected_duration_attributes_old = { expected_duration_attributes_old = {
"http.method": "GET", "http.method": "GET",
"http.host": "127.0.0.1", "http.host": "127.0.0.1",
@ -1524,7 +1536,7 @@ class TestAsgiApplication(AsgiTestBase):
) )
self.assertEqual(point.value, 0) self.assertEqual(point.value, 0)
def test_metric_target_attribute(self): async def test_metric_target_attribute(self):
expected_target = "/api/user/{id}" expected_target = "/api/user/{id}"
class TestRoute: class TestRoute:
@ -1540,7 +1552,8 @@ class TestAsgiApplication(AsgiTestBase):
app = otel_asgi.OpenTelemetryMiddleware(target_asgi) app = otel_asgi.OpenTelemetryMiddleware(target_asgi)
self.seed_app(app) 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() metrics_list = self.memory_metrics_reader.get_metrics_data()
assertions = 0 assertions = 0
for resource_metric in metrics_list.resource_metrics: for resource_metric in metrics_list.resource_metrics:
@ -1557,7 +1570,7 @@ class TestAsgiApplication(AsgiTestBase):
assertions += 1 assertions += 1
self.assertEqual(assertions, 3) self.assertEqual(assertions, 3)
def test_no_metric_for_websockets(self): async def test_no_metric_for_websockets(self):
self.scope = { self.scope = {
"type": "websocket", "type": "websocket",
"http_version": "1.1", "http_version": "1.1",
@ -1570,10 +1583,10 @@ class TestAsgiApplication(AsgiTestBase):
} }
app = otel_asgi.OpenTelemetryMiddleware(simple_asgi) app = otel_asgi.OpenTelemetryMiddleware(simple_asgi)
self.seed_app(app) self.seed_app(app)
self.send_input({"type": "websocket.connect"}) await self.send_input({"type": "websocket.connect"})
self.send_input({"type": "websocket.receive", "text": "ping"}) await self.send_input({"type": "websocket.receive", "text": "ping"})
self.send_input({"type": "websocket.disconnect"}) await self.send_input({"type": "websocket.disconnect"})
self.get_all_output() await self.get_all_output()
self.assertIsNone(self.memory_metrics_reader.get_metrics_data()) self.assertIsNone(self.memory_metrics_reader.get_metrics_data())
@ -1790,8 +1803,10 @@ class TestAsgiAttributes(unittest.TestCase):
) )
class TestWrappedApplication(AsgiTestBase): class TestWrappedApplication(AsyncAsgiTestBase):
def test_mark_span_internal_in_presence_of_span_from_other_framework(self): async def test_mark_span_internal_in_presence_of_span_from_other_framework(
self,
):
tracer_provider, exporter = TestBase.create_tracer_provider() tracer_provider, exporter = TestBase.create_tracer_provider()
tracer = tracer_provider.get_tracer(__name__) tracer = tracer_provider.get_tracer(__name__)
app = otel_asgi.OpenTelemetryMiddleware( app = otel_asgi.OpenTelemetryMiddleware(
@ -1806,7 +1821,8 @@ class TestWrappedApplication(AsgiTestBase):
await app(scope, receive, send) await app(scope, receive, send)
self.seed_app(wrapped_app) 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() span_list = exporter.get_finished_spans()
self.assertEqual(SpanKind.INTERNAL, span_list[0].kind) self.assertEqual(SpanKind.INTERNAL, span_list[0].kind)
@ -1823,11 +1839,11 @@ class TestWrappedApplication(AsgiTestBase):
) )
class TestAsgiApplicationRaisingError(AsgiTestBase): class TestAsgiApplicationRaisingError(AsyncAsgiTestBase):
def tearDown(self): def tearDown(self):
pass 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 Test that exception UnboundLocalError local variable 'start' referenced before assignment is not raised
See https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1883 See https://github.com/open-telemetry/opentelemetry-python-contrib/issues/1883
@ -1838,11 +1854,9 @@ class TestAsgiApplicationRaisingError(AsgiTestBase):
app = otel_asgi.OpenTelemetryMiddleware(bad_app) app = otel_asgi.OpenTelemetryMiddleware(bad_app)
self.seed_app(app) self.seed_app(app)
self.send_default_request() await self.send_default_request()
try: try:
asyncio.get_event_loop().run_until_complete( await self.communicator.wait()
self.communicator.stop()
)
except ValueError as exc_info: except ValueError as exc_info:
self.assertEqual(exc_info.args[0], "whatever") self.assertEqual(exc_info.args[0], "whatever")
except Exception as exc_info: # pylint: disable=W0703 except Exception as exc_info: # pylint: disable=W0703