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 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": (
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user