Skip to content

Commit 6730392

Browse files
Make the test suite connectivity-agnostic (#12095)
Co-authored-by: Adam Turner <[email protected]>
1 parent e1d5235 commit 6730392

File tree

5 files changed

+39
-64
lines changed

5 files changed

+39
-64
lines changed

sphinx/testing/fixtures.py

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import sys
88
from collections import namedtuple
99
from io import StringIO
10-
from typing import TYPE_CHECKING, Optional
10+
from typing import TYPE_CHECKING
1111

1212
import pytest
1313

@@ -236,52 +236,6 @@ def if_graphviz_found(app: SphinxTestApp) -> None: # NoQA: PT004
236236
pytest.skip('graphviz "dot" is not available')
237237

238238

239-
_HOST_ONLINE_ERROR = pytest.StashKey[Optional[str]]()
240-
241-
242-
def _query(address: tuple[str, int]) -> str | None:
243-
import socket
244-
245-
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
246-
try:
247-
sock.settimeout(5)
248-
sock.connect(address)
249-
except OSError as exc:
250-
# other type of errors are propagated
251-
return str(exc)
252-
return None
253-
254-
255-
@pytest.fixture(scope='session')
256-
def sphinx_remote_query_address() -> tuple[str, int]:
257-
"""Address to which a query is made to check that the host is online.
258-
259-
By default, onlineness is tested by querying the DNS server ``1.1.1.1``
260-
but users concerned about privacy might change it in ``conftest.py``.
261-
"""
262-
return ('1.1.1.1', 80)
263-
264-
265-
@pytest.fixture(scope='session')
266-
def if_online( # NoQA: PT004
267-
request: pytest.FixtureRequest,
268-
sphinx_remote_query_address: tuple[str, int],
269-
) -> None:
270-
"""Skip the test if the host has no connection.
271-
272-
Usage::
273-
274-
@pytest.mark.usefixtures('if_online')
275-
def test_if_host_is_online(): ...
276-
"""
277-
if _HOST_ONLINE_ERROR not in request.session.stash:
278-
# do not use setdefault() to avoid creating a socket connection
279-
lookup_error = _query(sphinx_remote_query_address)
280-
request.session.stash[_HOST_ONLINE_ERROR] = lookup_error
281-
if (error := request.session.stash[_HOST_ONLINE_ERROR]) is not None:
282-
pytest.skip('host appears to be offline (%s)' % error)
283-
284-
285239
@pytest.fixture(scope='session')
286240
def sphinx_test_tempdir(tmp_path_factory: Any) -> Path:
287241
"""Temporary directory."""

tests/roots/test-images/index.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ test-image
2323
:target: https://www.python.org/
2424

2525
.. a remote image
26-
.. image:: https://www.python.org/static/img/python-logo.png
26+
.. image:: http://localhost:7777/sphinx.png
2727

2828
.. non-exist remote image
29-
.. image:: https://www.google.com/NOT_EXIST.PNG
29+
.. image:: http://localhost:7777/NOT_EXIST.PNG

tests/roots/test-root/images.txt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ Sphinx image handling
1212
.. an image with unspecified extension
1313
.. image:: img.*
1414

15-
.. a non-local image URI
16-
.. image:: https://www.python.org/static/img/python-logo.png
17-
1815
.. an image with subdir and unspecified extension
1916
.. image:: subdir/simg.*
2017

tests/test_builders/test_build_html_image.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
import pytest
66

77

8-
@pytest.mark.usefixtures('if_online')
98
@pytest.mark.sphinx('html', testroot='images')
109
def test_html_remote_images(app, status, warning):
1110
app.build(force_all=True)
1211

1312
result = (app.outdir / 'index.html').read_text(encoding='utf8')
14-
assert ('<img alt="https://www.python.org/static/img/python-logo.png" '
15-
'src="https://www.python.org/static/img/python-logo.png" />' in result)
16-
assert not (app.outdir / 'python-logo.png').exists()
13+
assert ('<img alt="http://localhost:7777/sphinx.png" '
14+
'src="http://localhost:7777/sphinx.png" />' in result)
15+
assert not (app.outdir / 'sphinx.png').exists()
1716

1817

1918
@pytest.mark.sphinx('html', testroot='image-escape')
@@ -25,7 +24,6 @@ def test_html_encoded_image(app, status, warning):
2524
assert (app.outdir / '_images/img_#1.png').exists()
2625

2726

28-
@pytest.mark.usefixtures('if_online')
2927
@pytest.mark.sphinx('html', testroot='remote-logo')
3028
def test_html_remote_logo(app, status, warning):
3129
app.build(force_all=True)

tests/test_builders/test_build_latex.py

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Test the build process with LaTeX builder with the test root."""
22

3+
import http.server
34
import os
45
import re
56
import subprocess
@@ -17,6 +18,8 @@
1718
from sphinx.util.osutil import ensuredir
1819
from sphinx.writers.latex import LaTeXTranslator
1920

21+
from tests.utils import http_server
22+
2023
try:
2124
from contextlib import chdir
2225
except ImportError:
@@ -79,6 +82,28 @@ def skip_if_stylefiles_notfound(testfunc):
7982
return testfunc
8083

8184

85+
class RemoteImageHandler(http.server.BaseHTTPRequestHandler):
86+
protocol_version = "HTTP/1.1"
87+
88+
def do_GET(self):
89+
content, content_type = None, None
90+
if self.path == "/sphinx.png":
91+
with open("tests/roots/test-local-logo/images/img.png", "rb") as f:
92+
content = f.read()
93+
content_type = "image/png"
94+
95+
if content:
96+
self.send_response(200, "OK")
97+
self.send_header("Content-Length", str(len(content)))
98+
self.send_header("Content-Type", content_type)
99+
self.end_headers()
100+
self.wfile.write(content)
101+
else:
102+
self.send_response(404, "Not Found")
103+
self.send_header("Content-Length", "0")
104+
self.end_headers()
105+
106+
82107
@skip_if_requested
83108
@skip_if_stylefiles_notfound
84109
@pytest.mark.parametrize(
@@ -112,7 +137,8 @@ def test_build_latex_doc(app, engine, docclass, python_maximum_signature_line_le
112137
load_mappings(app)
113138
app.builder.init()
114139
LaTeXTranslator.ignore_missing_images = True
115-
app.build(force_all=True)
140+
with http_server(RemoteImageHandler):
141+
app.build(force_all=True)
116142

117143
# file from latex_additional_files
118144
assert (app.outdir / 'svgimg.svg').is_file()
@@ -1398,21 +1424,21 @@ def test_latex_raw_directive(app, status, warning):
13981424
assert 'LaTeX: abc def ghi' in result
13991425

14001426

1401-
@pytest.mark.usefixtures('if_online')
14021427
@pytest.mark.sphinx('latex', testroot='images')
14031428
def test_latex_images(app, status, warning):
1404-
app.build(force_all=True)
1429+
with http_server(RemoteImageHandler, port=7777):
1430+
app.build(force_all=True)
14051431

14061432
result = (app.outdir / 'python.tex').read_text(encoding='utf8')
14071433

14081434
# images are copied
1409-
assert '\\sphinxincludegraphics{{python-logo}.png}' in result
1410-
assert (app.outdir / 'python-logo.png').exists()
1435+
assert '\\sphinxincludegraphics{{sphinx}.png}' in result
1436+
assert (app.outdir / 'sphinx.png').exists()
14111437

14121438
# not found images
14131439
assert '\\sphinxincludegraphics{{NOT_EXIST}.PNG}' not in result
14141440
assert ('WARNING: Could not fetch remote image: '
1415-
'https://www.google.com/NOT_EXIST.PNG [404]' in warning.getvalue())
1441+
'http://localhost:7777/NOT_EXIST.PNG [404]' in warning.getvalue())
14161442

14171443
# an image having target
14181444
assert ('\\sphinxhref{https://www.sphinx-doc.org/}'
@@ -1682,7 +1708,7 @@ def test_copy_images(app, status, warning):
16821708
image.name for image in test_dir.rglob('*')
16831709
if image.suffix in {'.gif', '.pdf', '.png', '.svg'}
16841710
}
1685-
images.discard('python-logo.png')
1711+
images.discard('sphinx.png')
16861712
assert images == {
16871713
'img.pdf',
16881714
'rimg.png',

0 commit comments

Comments
 (0)