Files
Joe McGinley a164d37a3c Chore: Drop support for Python 3.8 (#3399)
Python 3.8 was EoL @ 2024-10-07, our 6 month promise for support ended on 2024-04-07.

Changes:
* Updated basline refs to 3.9
* Removed 3.8 sys.version_info checks
* Fixed botocore test failure
* Applied ruff formatting
2025-05-27 17:26:02 +02:00

141 lines
4.9 KiB
Python

# 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.
from http.client import HTTPConnection, HTTPResponse, HTTPSConnection
from opentelemetry import trace
from opentelemetry.test.httptest import HttpTestBase
from opentelemetry.test.test_base import TestBase
from opentelemetry.trace.span import INVALID_SPAN
from opentelemetry.util.http.httplib import (
HttpClientInstrumentor,
set_ip_on_next_http_connection,
)
# pylint: disable=too-many-public-methods
class TestHttpBase(TestBase, HttpTestBase):
def setUp(self):
super().setUp()
HttpClientInstrumentor().instrument()
self.server_thread, self.server = self.run_server()
def tearDown(self):
HttpClientInstrumentor().uninstrument()
self.server.shutdown()
self.server_thread.join()
super().tearDown()
def assert_span(self, exporter=None, num_spans=1):
if exporter is None:
exporter = self.memory_exporter
span_list = exporter.get_finished_spans()
self.assertEqual(num_spans, len(span_list))
if num_spans == 0:
return None
if num_spans == 1:
return span_list[0]
return span_list
def test_basic(self):
resp, body = self.perform_request()
assert resp.status == 200
assert body == b"Hello!"
self.assert_span(num_spans=0)
def test_basic_with_span(self):
tracer = trace.get_tracer(__name__)
with (
tracer.start_as_current_span("HTTP GET") as span,
set_ip_on_next_http_connection(span),
):
resp, body = self.perform_request()
assert resp.status == 200
assert body == b"Hello!"
span = self.assert_span(num_spans=1)
self.assertEqual(span.attributes, {"net.peer.ip": "127.0.0.1"})
def test_with_nested_span(self):
tracer = trace.get_tracer(__name__)
with (
tracer.start_as_current_span("requests HTTP GET") as span,
set_ip_on_next_http_connection(span),
):
with (
tracer.start_as_current_span("urllib3 HTTP GET") as span2,
set_ip_on_next_http_connection(span2),
):
resp, body = self.perform_request()
assert resp.status == 200
assert body == b"Hello!"
for span in self.assert_span(num_spans=2):
self.assertEqual(span.attributes, {"net.peer.ip": "127.0.0.1"})
def test_with_nested_nonrecording_span(self):
tracer = trace.get_tracer(__name__)
with (
tracer.start_as_current_span("requests HTTP GET") as span,
set_ip_on_next_http_connection(span),
):
with (
trace.use_span(INVALID_SPAN),
set_ip_on_next_http_connection(INVALID_SPAN),
):
resp, body = self.perform_request()
assert resp.status == 200
assert body == b"Hello!"
span = self.assert_span(num_spans=1)
self.assertEqual(span.attributes, {"net.peer.ip": "127.0.0.1"})
def test_with_only_nonrecording_span(self):
with (
trace.use_span(INVALID_SPAN),
set_ip_on_next_http_connection(INVALID_SPAN),
):
resp, body = self.perform_request()
assert resp.status == 200
assert body == b"Hello!"
self.assert_span(num_spans=0)
def perform_request(self, secure=False) -> HTTPResponse:
conn_cls = HTTPSConnection if secure else HTTPConnection
conn = conn_cls(self.server.server_address[0], self.server.server_port)
resp = None
try:
conn.request("GET", "/", headers={"Connection": "close"})
resp = conn.getresponse()
return resp, resp.read()
finally:
if resp:
resp.close()
conn.close()
def test_uninstrument(self):
HttpClientInstrumentor().uninstrument()
tracer = trace.get_tracer(__name__)
with (
tracer.start_as_current_span("HTTP GET") as span,
set_ip_on_next_http_connection(span),
):
body = self.perform_request()[1]
self.assertEqual(b"Hello!", body)
# We should have a span, but it should have no attributes
self.assertFalse(self.assert_span(num_spans=1).attributes)
# instrument again to avoid warning message on tearDown
HttpClientInstrumentor().instrument()