Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .changelog/4583.changed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`opentelemetry-instrumentation-{urllib,urllib3,requests}`: switch http mock library from abandoned httpretty to mocket
38 changes: 38 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5534,6 +5534,44 @@ jobs:
- name: Run tests
run: tox -e py313-test-instrumentation-urllib3-1 -- -ra

py314-test-instrumentation-urllib3-0_ubuntu-latest:
name: instrumentation-urllib3-0 3.14 Ubuntu
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repo @ SHA - ${{ github.sha }}
uses: actions/checkout@v4

- name: Set up Python 3.14
uses: actions/setup-python@v5
with:
python-version: "3.14"

- name: Install tox
run: pip install tox-uv

- name: Run tests
run: tox -e py314-test-instrumentation-urllib3-0 -- -ra

py314-test-instrumentation-urllib3-1_ubuntu-latest:
name: instrumentation-urllib3-1 3.14 Ubuntu
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repo @ SHA - ${{ github.sha }}
uses: actions/checkout@v4

- name: Set up Python 3.14
uses: actions/setup-python@v5
with:
python-version: "3.14"

- name: Install tox
run: pip install tox-uv

- name: Run tests
run: tox -e py314-test-instrumentation-urllib3-1 -- -ra

pypy3-test-instrumentation-urllib3-0_ubuntu-latest:
name: instrumentation-urllib3-0 pypy-3.10 Ubuntu
runs-on: ubuntu-latest
Expand Down
1 change: 0 additions & 1 deletion dev-requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
pylint==4.0.5
httpretty==1.1.4
pyright==v1.1.404
sphinx==7.1.2
sphinx-rtd-theme==2.0.0rc4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ asgiref==3.8.1
certifi==2024.7.4
charset-normalizer==3.3.2
Deprecated==1.2.14
httpretty==1.1.4
mocket==3.14.1
idna==3.7
iniconfig==2.0.0
packaging==24.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
import abc
from unittest import mock

import httpretty
import requests
from mocket import Mocket, Mocketizer
from mocket.mocks.mockhttp import Entry
from requests.adapters import BaseAdapter
from requests.models import Response

Expand Down Expand Up @@ -131,16 +132,17 @@ def setUp(self):
self.exclude_patch.start()

RequestsInstrumentor().instrument()
httpretty.enable()
httpretty.register_uri(httpretty.GET, self.URL, body="Hello!")
self.mocketizer = Mocketizer(strict_mode=True)
self.mocketizer.enter()
Entry.single_register(Entry.GET, self.URL, body="Hello!")

# pylint: disable=invalid-name
def tearDown(self):
super().tearDown()
self.env_patch.stop()
_OpenTelemetrySemanticConventionStability._initialized = False
RequestsInstrumentor().uninstrument()
httpretty.disable()
self.mocketizer.exit()

def assert_span(self, exporter=None, num_spans=1):
if exporter is None:
Expand Down Expand Up @@ -189,8 +191,8 @@ def test_basic(self):

def test_basic_new_semconv(self):
url_with_port = "http://mock:80/status/200"
httpretty.register_uri(
httpretty.GET, url_with_port, status=200, body="Hello!"
Entry.single_register(
Entry.GET, url_with_port, status=200, body="Hello!"
)
result = self.perform_request(url_with_port)
self.assertEqual(result.text, "Hello!")
Expand Down Expand Up @@ -226,8 +228,8 @@ def test_basic_new_semconv(self):

def test_basic_both_semconv(self):
url_with_port = "http://mock:80/status/200"
httpretty.register_uri(
httpretty.GET, url_with_port, status=200, body="Hello!"
Entry.single_register(
Entry.GET, url_with_port, status=200, body="Hello!"
)
result = self.perform_request(url_with_port)
self.assertEqual(result.text, "Hello!")
Expand Down Expand Up @@ -267,9 +269,12 @@ def test_basic_both_semconv(self):
span, opentelemetry.instrumentation.requests
)

@mock.patch("httpretty.http.HttpBaseClass.METHODS", ("NONSTANDARD",))
@mock.patch(
"mocket.mocks.mockhttp.Entry.METHODS",
Entry.METHODS + ("NONSTANDARD",),
)
def test_nonstandard_http_method(self):
httpretty.register_uri("NONSTANDARD", self.URL, status=405)
Entry.single_register("NONSTANDARD", self.URL, status=405)
session = requests.Session()
session.request("NONSTANDARD", self.URL)
span = self.assert_span()
Expand All @@ -287,9 +292,12 @@ def test_nonstandard_http_method(self):

self.assertIs(span.status.status_code, trace.StatusCode.ERROR)

@mock.patch("httpretty.http.HttpBaseClass.METHODS", ("NONSTANDARD",))
@mock.patch(
"mocket.mocks.mockhttp.Entry.METHODS",
Entry.METHODS + ("NONSTANDARD",),
)
def test_nonstandard_http_method_new_semconv(self):
httpretty.register_uri("NONSTANDARD", self.URL, status=405)
Entry.single_register("NONSTANDARD", self.URL, status=405)
session = requests.Session()
session.request("NONSTANDARD", self.URL)
span = self.assert_span()
Expand Down Expand Up @@ -331,8 +339,8 @@ def response_hook(span, request_obj, response):

def test_excluded_urls_explicit(self):
url_404 = "http://mock/status/404"
httpretty.register_uri(
httpretty.GET,
Entry.single_register(
Entry.GET,
url_404,
status=404,
)
Expand All @@ -346,8 +354,8 @@ def test_excluded_urls_explicit(self):

def test_excluded_urls_from_env(self):
url = "http://localhost/env_excluded_arg/123"
httpretty.register_uri(
httpretty.GET,
Entry.single_register(
Entry.GET,
url,
status=200,
)
Expand All @@ -373,8 +381,8 @@ def name_callback(method, url):

def test_not_foundbasic(self):
url_404 = "http://mock/status/404"
httpretty.register_uri(
httpretty.GET,
Entry.single_register(
Entry.GET,
url_404,
status=404,
)
Expand All @@ -392,8 +400,8 @@ def test_not_foundbasic(self):

def test_not_foundbasic_new_semconv(self):
url_404 = "http://mock/status/404"
httpretty.register_uri(
httpretty.GET,
Entry.single_register(
Entry.GET,
url_404,
status=404,
)
Expand All @@ -412,8 +420,8 @@ def test_not_foundbasic_new_semconv(self):

def test_not_foundbasic_both_semconv(self):
url_404 = "http://mock/status/404"
httpretty.register_uri(
httpretty.GET,
Entry.single_register(
Entry.GET,
url_404,
status=404,
)
Expand Down Expand Up @@ -498,7 +506,7 @@ def test_distributed_context(self):

span = self.assert_span()

headers = dict(httpretty.last_request().headers)
headers = dict(Mocket.last_request().headers)
self.assertIn(MockTextMapPropagator.TRACE_ID_KEY, headers)
self.assertEqual(
str(span.get_span_context().trace_id),
Expand Down Expand Up @@ -583,8 +591,8 @@ def test_requests_exception_without_response(self, *_, **__):
)
def test_requests_exception_new_semconv(self, *_, **__):
url_with_port = "http://mock:80/status/200"
httpretty.register_uri(
httpretty.GET, url_with_port, status=200, body="Hello!"
Entry.single_register(
Entry.GET, url_with_port, status=200, body="Hello!"
)
with self.assertRaises(requests.RequestException):
self.perform_request(url_with_port)
Expand Down Expand Up @@ -703,6 +711,7 @@ def test_remove_sensitive_params(self):
new_url = (
"http://username:password@mock/status/200?AWSAccessKeyId=secret"
)
Entry.single_register(Entry.GET, new_url, body="Hello!")
self.perform_request(new_url)
span = self.assert_span()

Expand Down Expand Up @@ -732,7 +741,7 @@ def test_custom_request_headers_captured(self):
"X-Another-Header": "another-value",
"X-Excluded-Header": "excluded-value",
}
httpretty.register_uri(httpretty.GET, self.URL, body="Hello!")
Entry.single_register(Entry.GET, self.URL, body="Hello!")
result = requests.get(self.URL, headers=headers, timeout=5)
self.assertEqual(result.text, "Hello!")

Expand Down Expand Up @@ -763,8 +772,9 @@ def test_custom_response_headers_captured(self):
"X-Another-Header": "another-value",
"X-Excluded-Header": "excluded-value",
}
httpretty.register_uri(
httpretty.GET, self.URL, body="Hello!", adding_headers=headers
Mocket.reset()
Entry.single_register(
Entry.GET, self.URL, body="Hello!", headers=headers
)
result = requests.get(self.URL, timeout=5)
self.assertEqual(result.text, "Hello!")
Expand All @@ -786,11 +796,12 @@ def test_custom_headers_not_captured_when_not_configured(self):
RequestsInstrumentor().uninstrument()
RequestsInstrumentor().instrument()
headers = {"X-Request-Header": "request-value"}
httpretty.register_uri(
httpretty.GET,
Mocket.reset()
Entry.single_register(
Entry.GET,
self.URL,
body="Hello!",
adding_headers={"X-Response-Header": "response-value"},
headers={"X-Response-Header": "response-value"},
)
result = requests.get(self.URL, headers=headers, timeout=5)
self.assertEqual(result.text, "Hello!")
Expand Down Expand Up @@ -824,11 +835,12 @@ def test_sensitive_headers_sanitized(self):
"Set-Cookie": "session=abc123",
"X-Secret": "secret",
}
httpretty.register_uri(
httpretty.GET,
Mocket.reset()
Entry.single_register(
Entry.GET,
self.URL,
body="Hello!",
adding_headers=response_headers,
headers=response_headers,
)
result = requests.get(self.URL, headers=request_headers, timeout=5)
self.assertEqual(result.text, "Hello!")
Expand Down Expand Up @@ -872,11 +884,12 @@ def test_custom_headers_with_regex(self):
"X-Custom-Response-B": "value-B",
"X-Other-Response-Header": "other-value",
}
httpretty.register_uri(
httpretty.GET,
Mocket.reset()
Entry.single_register(
Entry.GET,
self.URL,
body="Hello!",
adding_headers=response_headers,
headers=response_headers,
)
result = requests.get(self.URL, headers=request_headers, timeout=5)
self.assertEqual(result.text, "Hello!")
Expand Down Expand Up @@ -918,11 +931,12 @@ def test_custom_headers_case_insensitive(self):
RequestsInstrumentor().instrument()
request_headers = {"X-ReQuESt-HeaDER": "custom-value"}
response_headers = {"X-ReSPoNse-HeaDER": "custom-value"}
httpretty.register_uri(
httpretty.GET,
Mocket.reset()
Entry.single_register(
Entry.GET,
self.URL,
body="Hello!",
adding_headers=response_headers,
headers=response_headers,
)
result = requests.get(self.URL, headers=request_headers, timeout=5)
self.assertEqual(result.text, "Hello!")
Expand Down Expand Up @@ -973,15 +987,16 @@ def setUp(self):
_OpenTelemetrySemanticConventionStability._initialized = False
RequestsInstrumentor().instrument(meter_provider=self.meter_provider)

httpretty.enable()
httpretty.register_uri(httpretty.GET, self.URL, body="Hello!")
self.mocketizer = Mocketizer(strict_mode=True)
self.mocketizer.enter()
Entry.single_register(Entry.GET, self.URL, body="Hello!")

def tearDown(self):
super().tearDown()
self.env_patch.stop()
_OpenTelemetrySemanticConventionStability._initialized = False
RequestsInstrumentor().uninstrument()
httpretty.disable()
self.mocketizer.exit()

@staticmethod
def perform_request(url: str) -> requests.Response:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@

from unittest import mock

import httpretty
import requests
from mocket import Mocketizer
from mocket.mocks.mockhttp import Entry

from opentelemetry.instrumentation.requests import RequestsInstrumentor
from opentelemetry.semconv._incubating.attributes.user_agent_attributes import (
Expand All @@ -21,13 +22,14 @@ class TestUserAgentSynthetic(TestBase):
def setUp(self):
super().setUp()
RequestsInstrumentor().instrument()
httpretty.enable()
httpretty.register_uri(httpretty.GET, self.URL, body="Hello!")
self.mocketizer = Mocketizer(strict_mode=True)
self.mocketizer.enter()
Entry.single_register(Entry.GET, self.URL, body="Hello!")

def tearDown(self):
super().tearDown()
RequestsInstrumentor().uninstrument()
httpretty.disable()
self.mocketizer.exit()

def assert_span(self, num_spans=1):
span_list = self.memory_exporter.get_finished_spans()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
asgiref==3.8.1
Deprecated==1.2.14
httpretty==1.1.4
mocket==3.14.1
iniconfig==2.0.0
packaging==24.0
pluggy==1.6.0
Expand Down
Loading
Loading