-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Expand file tree
/
Copy pathconftest.py
More file actions
57 lines (43 loc) · 1.71 KB
/
conftest.py
File metadata and controls
57 lines (43 loc) · 1.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import os
import time
from functools import wraps
import requests
def _get_env_number(name, default, cast):
value = os.environ.get(name)
if value is None:
return default
try:
return cast(value)
except ValueError:
return default
def pytest_configure(config):
if not getattr(config.option, "check_links", False):
return
timeout = _get_env_number("CHECK_LINKS_TIMEOUT", 10.0, float)
max_retries = max(0, _get_env_number("CHECK_LINKS_RETRIES", 2, int))
retry_backoff = max(0.0, _get_env_number("CHECK_LINKS_RETRY_BACKOFF", 1.0, float))
current_request = requests.sessions.Session.request
if getattr(current_request, "_check_links_wrapped", False):
return
retryable_methods = {"GET", "HEAD"}
retryable_errors = (
requests.exceptions.Timeout,
requests.exceptions.ConnectionError,
)
@wraps(current_request)
def request_with_timeout(self, method, url, **kwargs):
if kwargs.get("timeout") is None:
kwargs["timeout"] = timeout
method_name = (method or "").upper()
for attempt in range(max_retries + 1):
try:
return current_request(self, method, url, **kwargs)
except retryable_errors:
should_retry = method_name in retryable_methods and attempt < max_retries
if not should_retry:
raise
# Retries smooth over transient CI/network blips without masking real 4xx/5xx failures.
if retry_backoff:
time.sleep(retry_backoff * (attempt + 1))
request_with_timeout._check_links_wrapped = True
requests.sessions.Session.request = request_with_timeout