|
1 | 1 | import logging
|
2 | 2 | import os
|
| 3 | +from http.server import HTTPServer |
3 | 4 | from pathlib import Path
|
4 |
| -from typing import Any, List, Optional |
| 5 | +from typing import Any, Iterator, List, Optional |
5 | 6 | from urllib.parse import urlparse
|
6 | 7 | from urllib.request import getproxies
|
7 | 8 |
|
8 | 9 | import pytest
|
9 | 10 | from pip._vendor import requests
|
10 | 11 |
|
11 | 12 | from pip import __version__
|
| 13 | +from pip._internal.exceptions import DiagnosticPipError |
12 | 14 | from pip._internal.models.link import Link
|
13 | 15 | from pip._internal.network.session import (
|
14 | 16 | CI_ENVIRONMENT_VARIABLES,
|
15 | 17 | PipSession,
|
16 | 18 | user_agent,
|
17 | 19 | )
|
| 20 | +from pip._internal.utils.logging import VERBOSE |
| 21 | +from tests.lib.server import InstantCloseHTTPHandler, server_running |
18 | 22 |
|
19 | 23 |
|
20 | 24 | def get_user_agent() -> str:
|
@@ -281,3 +285,63 @@ def test_proxy(self, proxy: Optional[str]) -> None:
|
281 | 285 | f"Invalid proxy {proxy} or session.proxies: "
|
282 | 286 | f"{session.proxies} is not correctly passed to session.request."
|
283 | 287 | )
|
| 288 | + |
| 289 | + |
| 290 | +@pytest.mark.network |
| 291 | +class TestRetryWarningRewriting: |
| 292 | + @pytest.fixture(autouse=True) |
| 293 | + def setup_caplog_level(self, caplog: pytest.LogCaptureFixture) -> Iterator[None]: |
| 294 | + with caplog.at_level(logging.WARNING): |
| 295 | + yield |
| 296 | + |
| 297 | + @pytest.mark.parametrize( |
| 298 | + "url, expected_message", |
| 299 | + [ |
| 300 | + ( |
| 301 | + "https://404.example.com", |
| 302 | + "failed to connect to 404.example.com via HTTPS", |
| 303 | + ), |
| 304 | + ("http://404.example.com", "failed to connect to 404.example.com via HTTP"), |
| 305 | + ("https://expired.badssl.com", "SSL verification failed"), |
| 306 | + ], |
| 307 | + ) |
| 308 | + def test_simple_urls( |
| 309 | + self, caplog: pytest.LogCaptureFixture, url: str, expected_message: str |
| 310 | + ) -> None: |
| 311 | + with PipSession(retries=1) as session: |
| 312 | + with pytest.raises(DiagnosticPipError): |
| 313 | + session.get(url) |
| 314 | + assert caplog.messages == [f"{expected_message}, retrying 1 last time"] |
| 315 | + |
| 316 | + def test_timeout(self, caplog: pytest.LogCaptureFixture) -> None: |
| 317 | + with PipSession(retries=1) as session: |
| 318 | + with pytest.raises(DiagnosticPipError): |
| 319 | + session.get("https://httpstat.us/200?sleep=400", timeout=0.2) |
| 320 | + assert caplog.messages == [ |
| 321 | + "server didn't respond within 0.2 seconds, retrying 1 last time" |
| 322 | + ] |
| 323 | + |
| 324 | + def test_connection_aborted(self, caplog: pytest.LogCaptureFixture) -> None: |
| 325 | + with HTTPServer(("localhost", 0), InstantCloseHTTPHandler) as server: |
| 326 | + with server_running(server), PipSession(retries=1) as session: |
| 327 | + with pytest.raises(DiagnosticPipError): |
| 328 | + session.get(f"http://{server.server_name}:{server.server_port}/") |
| 329 | + assert caplog.messages == [ |
| 330 | + "the connection was closed unexpectedly, retrying 1 last time" |
| 331 | + ] |
| 332 | + |
| 333 | + def test_proxy(self, caplog: pytest.LogCaptureFixture) -> None: |
| 334 | + with PipSession(retries=1) as session: |
| 335 | + session.proxies = {"https": "https://404.example.com"} |
| 336 | + with pytest.raises(DiagnosticPipError): |
| 337 | + session.get("https://pypi.org") |
| 338 | + assert caplog.messages == ["failed to connect to proxy, retrying 1 last time"] |
| 339 | + |
| 340 | + def test_verbose(self, caplog: pytest.LogCaptureFixture) -> None: |
| 341 | + caplog.set_level(VERBOSE) |
| 342 | + with PipSession(retries=1) as session: |
| 343 | + with pytest.raises(DiagnosticPipError): |
| 344 | + session.get("https://404.example.org") |
| 345 | + warnings = [r.message for r in caplog.records if r.levelno == logging.WARNING] |
| 346 | + assert len(warnings) == 1 |
| 347 | + assert not warnings[0].endswith("retrying 1 last time") |
0 commit comments