Skip to content

Commit

Permalink
Check _has_route *within* the test function (#3187)
Browse files Browse the repository at this point in the history
Test selection occurs after collection, so if we're in an environment
where we don't want to make outbound network connections, defer the
check to after selection.

This was the aim of #3166, but it wasn't tested in an environment where
ConnectionError is raised.
  • Loading branch information
stefanor committed Nov 12, 2023
1 parent f7cd7f3 commit e601a0e
Showing 1 changed file with 17 additions and 14 deletions.
31 changes: 17 additions & 14 deletions test/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import typing
import warnings
from collections.abc import Sequence
from functools import wraps
from importlib.abc import Loader, MetaPathFinder
from importlib.machinery import ModuleSpec
from types import ModuleType, TracebackType
Expand All @@ -29,8 +30,6 @@
except ImportError:
zstd = None

import functools

from urllib3 import util
from urllib3.connectionpool import ConnectionPool
from urllib3.exceptions import HTTPWarning
Expand Down Expand Up @@ -181,6 +180,20 @@ def _has_route() -> bool:
else:
raise

def _skip_if_no_route(f: _TestFuncT) -> _TestFuncT:
"""Skip test exuction if network is unreachable"""

@wraps(f)
def wrapper(*args: typing.Any, **kwargs: typing.Any) -> typing.Any:
global _requires_network_has_route
if _requires_network_has_route is None:
_requires_network_has_route = _has_route()
if not _requires_network_has_route:
pytest.skip("Can't run the test because the network is unreachable")
return f(*args, **kwargs)

return typing.cast(_TestFuncT, wrapper)

def _decorator_requires_internet(
decorator: typing.Callable[[_TestFuncT], _TestFuncT]
) -> typing.Callable[[_TestFuncT], _TestFuncT]:
Expand All @@ -191,17 +204,7 @@ def wrapper(f: _TestFuncT) -> typing.Any:

return wrapper

global _requires_network_has_route

if _requires_network_has_route is None:
_requires_network_has_route = _has_route()

return _decorator_requires_internet(
pytest.mark.skipif(
not _requires_network_has_route,
reason="Can't run the test because the network is unreachable",
)
)
return _decorator_requires_internet(_skip_if_no_route)


def resolvesLocalhostFQDN() -> typing.Callable[[_TestFuncT], _TestFuncT]:
Expand All @@ -213,7 +216,7 @@ def resolvesLocalhostFQDN() -> typing.Callable[[_TestFuncT], _TestFuncT]:


def withPyOpenSSL(test: typing.Callable[..., _RT]) -> typing.Callable[..., _RT]:
@functools.wraps(test)
@wraps(test)
def wrapper(*args: typing.Any, **kwargs: typing.Any) -> _RT:
if not pyopenssl:
pytest.skip("pyopenssl not available, skipping test.")
Expand Down

0 comments on commit e601a0e

Please sign in to comment.