|
1 | 1 | from __future__ import annotations |
2 | 2 |
|
| 3 | +import ssl |
| 4 | +from collections.abc import Iterator |
| 5 | + |
3 | 6 | import httpx |
4 | 7 | import pytest |
5 | 8 |
|
6 | | -from cognite.client._http_client import AsyncHTTPClientWithRetryConfig, RetryTracker |
| 9 | +from cognite.client._http_client import ( |
| 10 | + AsyncHTTPClientWithRetryConfig, |
| 11 | + NoCookiesPlease, |
| 12 | + RetryTracker, |
| 13 | + _global_async_httpx_clients, |
| 14 | + get_global_async_httpx_client, |
| 15 | +) |
| 16 | +from cognite.client.config import global_config |
7 | 17 |
|
8 | 18 |
|
9 | 19 | @pytest.fixture |
@@ -107,3 +117,57 @@ def test_is_auto_retryable(self, default_config: AsyncHTTPClientWithRetryConfig) |
107 | 117 | # 409 is not in the list of status codes to retry, but we set is_auto_retryable=True, which should override it |
108 | 118 | assert rt.should_retry_status_code(make_http_status_error(409), is_auto_retryable=True) is True |
109 | 119 | assert rt.should_retry_status_code(make_http_status_error(409), is_auto_retryable=False) is False |
| 120 | + |
| 121 | + |
| 122 | +@pytest.fixture |
| 123 | +def _clean_global_httpx_clients() -> Iterator[None]: |
| 124 | + _global_async_httpx_clients.clear() |
| 125 | + yield |
| 126 | + _global_async_httpx_clients.clear() |
| 127 | + |
| 128 | + |
| 129 | +@pytest.mark.usefixtures("_clean_global_httpx_clients") |
| 130 | +class TestGetGlobalAsyncHttpxClient: |
| 131 | + async def test_no_proxy_when_env_unset_and_config_unset(self, monkeypatch: pytest.MonkeyPatch) -> None: |
| 132 | + # Ensure test env does not randomly have these set: |
| 133 | + monkeypatch.delenv("HTTPS_PROXY", raising=False) |
| 134 | + monkeypatch.delenv("HTTP_PROXY", raising=False) |
| 135 | + |
| 136 | + client = get_global_async_httpx_client() |
| 137 | + |
| 138 | + assert not client._mounts |
| 139 | + |
| 140 | + async def test_env_proxy_is_respected(self, monkeypatch: pytest.MonkeyPatch) -> None: |
| 141 | + monkeypatch.setenv("HTTPS_PROXY", "http://magicenvproxy:666") |
| 142 | + |
| 143 | + client = get_global_async_httpx_client() |
| 144 | + |
| 145 | + assert len(client._mounts) == 1 |
| 146 | + |
| 147 | + # If the below asserts fail due to httpx/httpcore private API changes, just keep the assert above. |
| 148 | + (transport,) = client._mounts.values() |
| 149 | + assert transport._pool._proxy_url.host == b"magicenvproxy" # type: ignore[union-attr] |
| 150 | + assert transport._pool._proxy_url.port == 666 # type: ignore[union-attr] |
| 151 | + |
| 152 | + async def test_explicit_proxy_config_still_works(self, monkeypatch: pytest.MonkeyPatch) -> None: |
| 153 | + monkeypatch.setattr(global_config, "proxy", "http://explicit:1234") |
| 154 | + |
| 155 | + client = get_global_async_httpx_client() |
| 156 | + |
| 157 | + assert client._mounts |
| 158 | + |
| 159 | + async def test_client_settings_match_global_config(self, monkeypatch: pytest.MonkeyPatch) -> None: |
| 160 | + """Verify pool limits, SSL, redirect, and cookie settings are forwarded correctly.""" |
| 161 | + monkeypatch.setattr(global_config, "max_connection_pool_size", 42) |
| 162 | + monkeypatch.setattr(global_config, "disable_ssl", True) |
| 163 | + monkeypatch.setattr(global_config, "follow_redirects", True) |
| 164 | + client = get_global_async_httpx_client() |
| 165 | + |
| 166 | + assert client.follow_redirects is True |
| 167 | + assert isinstance(client._cookies.jar, NoCookiesPlease) |
| 168 | + |
| 169 | + pool = client._transport._pool # type: ignore[attr-defined] |
| 170 | + assert pool._max_connections == 42 |
| 171 | + assert pool._keepalive_expiry == 5 |
| 172 | + assert pool._ssl_context.verify_mode == ssl.CERT_NONE # disable_ssl should cause this |
| 173 | + assert pool._ssl_context.check_hostname is False |
0 commit comments