Skip to content

Add HTTP-agnostic protocol, shared exceptions, and mock fixtures to base#24544

Closed
mwdd146980 wants to merge 2 commits into
masterfrom
mwdd146980/agnostic-http-foundation
Closed

Add HTTP-agnostic protocol, shared exceptions, and mock fixtures to base#24544
mwdd146980 wants to merge 2 commits into
masterfrom
mwdd146980/agnostic-http-foundation

Conversation

@mwdd146980

@mwdd146980 mwdd146980 commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Lands the backend-neutral HTTP foundation on master, decoupled from the feature branch, so integrations and tests can build against an HTTP-agnostic surface. It adds:

  • HTTP-agnostic protocol types: HTTPClientProtocol and HTTPResponseProtocol (http_protocol.py).
  • A shared, backend-neutral exception hierarchy (http_exceptions.py).
  • A MockHTTPResponse test double (http_testing.py) plus new mock_http, mock_openmetrics_http, and mock_prometheus_http dev fixtures.
  • New capabilities on RequestsWrapper: trust_env, close, get_cookie, get_header, set_header.
  • A create_http_client factory seam on AgentCheck so the backing HTTP client is overridable.

The change is purely additive. self.http still raises requests exceptions, the existing mock_response fixtures are unchanged, and no integration catch sites are touched, so there is no behavior change.

Motivation

We want to migrate the shipped Agent off requests behind an HTTP-agnostic surface. This PR moves the non-breaking foundation (proto, shared exception types, mock fixtures, wrapper capabilities, and the factory seam) to master first, so we can adopt the surface incrementally.

Verification

  • http.py diff vs master is additive only: 46 insertions, 0 removals, and zero references to the exception-translation machinery (_translate_*, http_exceptions, requests_exceptions). The verbs, raise_for_status, and ResponseWrapper are byte-identical to master, so self.http behavior is unchanged.
  • Base HTTP test suite: 170 passed, including the new test_capabilities.py and test_http_testing.py, the appended get_header/set_header tests, and the create_http_client factory tests. The remaining errors/failures are pre-existing environmental gaps (jwt, requests_kerberos, socks proxy) that fail identically on master.
  • Lint and formatting pass through ddev test --lint datadog_checks_base datadog_checks_dev (ruff format and ruff check: all checks passed).

Review checklist (to be filled by reviewers)

  • Feature or bugfix MUST have appropriate tests (unit, integration, e2e)
  • Add qa/required if this PR needs QA validation, or qa/skip-qa if it does not. Exactly one of the two is required. (qa/skip-qa: additive surface, no shipped check uses it yet, self.http behavior unchanged.)
  • If you need to backport this PR to another branch, you can add the backport/<branch-name> label to the PR and it will automatically open a backport PR once this one is merged

Introduce the backend-neutral HTTP foundation so checks and tests can
depend on an HTTP-agnostic surface instead of requests-specific APIs:

- HTTPClientProtocol / HTTPResponseProtocol (http_protocol.py)
- A shared, backend-neutral exception hierarchy (http_exceptions.py)
- A MockHTTPResponse test double (http_testing.py) plus the mock_http,
  mock_openmetrics_http, and mock_prometheus_http dev fixtures
- trust_env, close, get_cookie, get_header, set_header on RequestsWrapper
- A create_http_client factory seam on AgentCheck

Purely additive. self.http still raises requests exceptions, and the
existing mock_response fixtures are unchanged, so there is no behavior
change and no integration catch sites need updating.
@dd-octo-sts

dd-octo-sts Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Validation Report

All 21 validations passed.

Show details
Validation Description Status
agent-reqs Verify check versions match the Agent requirements file
ci Validate CI configuration and code coverage settings
codeowners Validate every integration has a CODEOWNERS entry
config Validate default configuration files against spec.yaml
dep Verify dependency pins are consistent and Agent-compatible
http Validate integrations use the HTTP wrapper correctly
imports Validate check imports do not use deprecated modules
integration-style Validate check code style conventions
jmx-metrics Validate JMX metrics definition files and config
labeler Validate PR labeler config matches integration directories
legacy-signature Validate no integration uses the legacy Agent check signature
license-headers Validate Python files have proper license headers
licenses Validate third-party license attribution list
metadata Validate metadata.csv metric definitions
models Validate configuration data models match spec.yaml
openmetrics Validate OpenMetrics integrations disable the metric limit
package Validate Python package metadata and naming
qa-label Validate the pull request declares whether it needs QA for the next Agent release
readmes Validate README files have required sections
saved-views Validate saved view JSON file structure and fields
version Validate version consistency between package and changelog

View full run

@datadog-datadog-prod-us1-2

datadog-datadog-prod-us1-2 Bot commented Jul 14, 2026

Copy link
Copy Markdown

Pipelines  Tests  Code Coverage

Fix all issues with BitsAI

⚠️ Warnings

🚦 3 Pipeline jobs failed

PR All | test / j06ca546 / SNMP   View in Datadog   GitHub Actions

PR All | test / j44368ad (py3.13-17.0-C) / Postgres-py3.13-17.0-C   View in Datadog   GitHub Actions

PR All | test / jaee58c5 / Kong   View in Datadog   GitHub Actions

🧪 2 Tests failed in 1 job

PR All | run   GitHub Actions

test_e2e_discovery_all_candidates from test_integration_e2e.py   View in Datadog
Container logs matched &#39;error&#39; after probing candidate #1: &#39;error&#39;
❄️ Known flaky: test_e2e_snmp_listener from test_e2e_snmp_listener.py   View in Datadog
Needed at least 1 candidates for &#39;datadog.snmp.check_duration&#39;, got 0
Expected:
        MetricStub(name=&#39;datadog.snmp.check_duration&#39;, type=0, value=None, tags=[&#39;autodiscovery_subnet:172.18.0.0/28&#39;, &#39;device_vendor:apc&#39;, &#39;firmware_version:2.0.3-test&#39;, &#39;loader:python&#39;, &#39;model:APC Smart-UPS 600&#39;, &#39;serial_num:test_serial&#39;, &#39;snmp_device:172.18.0.1&#39;, &#39;snmp_profile:apc_ups&#39;, &#39;ups_name:testIdentName&#39;], hostname=None, device=None, flush_first_value=None)
Difference to closest:
        Expected tag snmp_device:172.18.0.1
        Found snmp_device:172.18.0.2

Similar submitted:
Score   Most similar
1.00    MetricStub(name=&#39;datadog.snmp.check_duration&#39;, type=0, value=0.13117408752441406, tags=[&#39;autodiscovery_subnet:172.18.0.0/28&#39;, &#39;device_vendor:apc&#39;, &#39;firmware_version:2.0.3-test&#39;, &#39;loader:python&#39;, &#39;model:APC Smart-UPS 600&#39;, &#39;serial_num:test_serial&#39;, &#39;snmp_device:172.18.0.2&#39;, &#39;snmp_profile:apc_ups&#39;, &#39;ups_name:testIdentName&#39;], hostname=&#39;runnervmos4r4&#39;, device=None, flush_first_value=False)
...

Not introduced in this PR.

ℹ️ Info

No other issues found (see more)

❄️ No new flaky tests detected

🎯 Code Coverage (details)
Patch Coverage: 90.17%
Overall Coverage: 88.38% (+0.10%)

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 01ef7ea | Docs | Datadog PR Page | Give us feedback!

@mwdd146980 mwdd146980 self-assigned this Jul 14, 2026
@mwdd146980 mwdd146980 closed this Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant