diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ddbc8a17a9..3a58a92c1e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -43,6 +43,22 @@ jobs: nox-session: [''] include: - experimental: false + # integration + # 3.8 and 3.9 have a known issue with large SSL requests that we work around: + # https://github.com/urllib3/urllib3/pull/3181#issuecomment-1794830698 + - python-version: "3.8" + os: ubuntu-latest + experimental: false + nox-session: test_integration + - python-version: "3.9" + os: ubuntu-latest + experimental: false + nox-session: test_integration + - python-version: "3.12" + os: ubuntu-latest + experimental: false + nox-session: test_integration + # pypy - python-version: "pypy-3.8" os: ubuntu-latest experimental: false @@ -56,6 +72,7 @@ jobs: experimental: false nox-session: test-pypy - python-version: "3.x" + # brotli os: ubuntu-latest experimental: false nox-session: test_brotlipy diff --git a/changelog/3181.feature.rst b/changelog/3181.feature.rst new file mode 100644 index 0000000000..82d6af24ba --- /dev/null +++ b/changelog/3181.feature.rst @@ -0,0 +1,4 @@ +Note to redistributors: the urllib3 test suite has been separated in +two. To run integration tests, you now need to run the tests a second +time with the `--integration` pytest flag, as in this example: `nox +-rs test-3.12 -- --integration`. diff --git a/noxfile.py b/noxfile.py index c0b0b9f0e6..907d82cdd4 100644 --- a/noxfile.py +++ b/noxfile.py @@ -11,6 +11,7 @@ def tests_impl( session: nox.Session, extras: str = "socks,brotli,zstd", byte_string_comparisons: bool = True, + integration: bool = False, ) -> None: # Install deps and the package itself. session.install("-r", "dev-requirements.txt") @@ -44,6 +45,7 @@ def tests_impl( *("--memray", "--hide-memray-summary") if memray_supported else (), "-v", "-ra", + *(("--integration",) if integration else ()), f"--color={'yes' if 'GITHUB_ACTIONS' in os.environ else 'auto'}", "--tb=native", "--durations=10", @@ -59,7 +61,13 @@ def test(session: nox.Session) -> None: tests_impl(session) -@nox.session(python=["3"]) +@nox.session(python="3") +def test_integration(session: nox.Session) -> None: + """Run integration tests""" + tests_impl(session, integration=True) + + +@nox.session(python="3") def test_brotlipy(session: nox.Session) -> None: """Check that if 'brotlipy' is installed instead of 'brotli' or 'brotlicffi' that we still don't blow up. diff --git a/pyproject.toml b/pyproject.toml index bb11c6d0cb..6b850412a1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -77,6 +77,7 @@ python_classes = ["Test", "*TestCase"] markers = [ "limit_memory: Limit memory with memray", "requires_network: This test needs access to the Internet", + "integration: Slow integrations tests not run by default", ] log_level = "DEBUG" filterwarnings = [ diff --git a/test/conftest.py b/test/conftest.py index 9aafdacfac..f464f704c3 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -20,6 +20,32 @@ from .tz_stub import stub_timezone_ctx +def pytest_addoption(parser: pytest.Parser) -> None: + parser.addoption( + "--integration", + action="store_true", + default=False, + help="run integration tests only", + ) + + +def pytest_collection_modifyitems( + config: pytest.Config, items: list[pytest.Item] +) -> None: + integration_mode = bool(config.getoption("--integration")) + skip_integration = pytest.mark.skip( + reason="skipping, need --integration option to run" + ) + skip_normal = pytest.mark.skip( + reason="skipping non integration tests in --integration mode" + ) + for item in items: + if "integration" in item.keywords and not integration_mode: + item.add_marker(skip_integration) + elif integration_mode and "integration" not in item.keywords: + item.add_marker(skip_normal) + + class ServerConfig(typing.NamedTuple): scheme: str host: str diff --git a/test/with_dummyserver/test_socketlevel.py b/test/with_dummyserver/test_socketlevel.py index 5935888330..c0701fe00a 100644 --- a/test/with_dummyserver/test_socketlevel.py +++ b/test/with_dummyserver/test_socketlevel.py @@ -11,7 +11,6 @@ import shutil import socket import ssl -import sys import tempfile import time import typing @@ -1584,10 +1583,7 @@ def socket_handler(listener: socket.socket) -> None: pool.request("GET", "/", retries=False, timeout=LONG_TIMEOUT) assert server_closed.wait(LONG_TIMEOUT), "The socket was not terminated" - @pytest.mark.skipif( - os.environ.get("CI") == "true" and sys.implementation.name == "pypy", - reason="too slow to run in CI", - ) + @pytest.mark.integration @pytest.mark.parametrize( "preload_content,read_amt", [(True, None), (False, None), (False, 2**31)] )