mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Make the test suite connectivity-agnostic (#12095)
Co-authored-by: Adam Turner <9087854+aa-turner@users.noreply.github.com>
This commit is contained in:
@@ -7,7 +7,7 @@ import subprocess
|
||||
import sys
|
||||
from collections import namedtuple
|
||||
from io import StringIO
|
||||
from typing import TYPE_CHECKING, Optional
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
|
||||
@@ -236,52 +236,6 @@ def if_graphviz_found(app: SphinxTestApp) -> None: # NoQA: PT004
|
||||
pytest.skip('graphviz "dot" is not available')
|
||||
|
||||
|
||||
_HOST_ONLINE_ERROR = pytest.StashKey[Optional[str]]()
|
||||
|
||||
|
||||
def _query(address: tuple[str, int]) -> str | None:
|
||||
import socket
|
||||
|
||||
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
|
||||
try:
|
||||
sock.settimeout(5)
|
||||
sock.connect(address)
|
||||
except OSError as exc:
|
||||
# other type of errors are propagated
|
||||
return str(exc)
|
||||
return None
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def sphinx_remote_query_address() -> tuple[str, int]:
|
||||
"""Address to which a query is made to check that the host is online.
|
||||
|
||||
By default, onlineness is tested by querying the DNS server ``1.1.1.1``
|
||||
but users concerned about privacy might change it in ``conftest.py``.
|
||||
"""
|
||||
return ('1.1.1.1', 80)
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def if_online( # NoQA: PT004
|
||||
request: pytest.FixtureRequest,
|
||||
sphinx_remote_query_address: tuple[str, int],
|
||||
) -> None:
|
||||
"""Skip the test if the host has no connection.
|
||||
|
||||
Usage::
|
||||
|
||||
@pytest.mark.usefixtures('if_online')
|
||||
def test_if_host_is_online(): ...
|
||||
"""
|
||||
if _HOST_ONLINE_ERROR not in request.session.stash:
|
||||
# do not use setdefault() to avoid creating a socket connection
|
||||
lookup_error = _query(sphinx_remote_query_address)
|
||||
request.session.stash[_HOST_ONLINE_ERROR] = lookup_error
|
||||
if (error := request.session.stash[_HOST_ONLINE_ERROR]) is not None:
|
||||
pytest.skip('host appears to be offline (%s)' % error)
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def sphinx_test_tempdir(tmp_path_factory: Any) -> Path:
|
||||
"""Temporary directory."""
|
||||
|
||||
@@ -23,7 +23,7 @@ test-image
|
||||
:target: https://www.python.org/
|
||||
|
||||
.. a remote image
|
||||
.. image:: https://www.python.org/static/img/python-logo.png
|
||||
.. image:: http://localhost:7777/sphinx.png
|
||||
|
||||
.. non-exist remote image
|
||||
.. image:: https://www.google.com/NOT_EXIST.PNG
|
||||
.. image:: http://localhost:7777/NOT_EXIST.PNG
|
||||
|
||||
@@ -12,9 +12,6 @@ Sphinx image handling
|
||||
.. an image with unspecified extension
|
||||
.. image:: img.*
|
||||
|
||||
.. a non-local image URI
|
||||
.. image:: https://www.python.org/static/img/python-logo.png
|
||||
|
||||
.. an image with subdir and unspecified extension
|
||||
.. image:: subdir/simg.*
|
||||
|
||||
|
||||
@@ -5,15 +5,14 @@ import docutils
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('if_online')
|
||||
@pytest.mark.sphinx('html', testroot='images')
|
||||
def test_html_remote_images(app, status, warning):
|
||||
app.build(force_all=True)
|
||||
|
||||
result = (app.outdir / 'index.html').read_text(encoding='utf8')
|
||||
assert ('<img alt="https://www.python.org/static/img/python-logo.png" '
|
||||
'src="https://www.python.org/static/img/python-logo.png" />' in result)
|
||||
assert not (app.outdir / 'python-logo.png').exists()
|
||||
assert ('<img alt="http://localhost:7777/sphinx.png" '
|
||||
'src="http://localhost:7777/sphinx.png" />' in result)
|
||||
assert not (app.outdir / 'sphinx.png').exists()
|
||||
|
||||
|
||||
@pytest.mark.sphinx('html', testroot='image-escape')
|
||||
@@ -25,7 +24,6 @@ def test_html_encoded_image(app, status, warning):
|
||||
assert (app.outdir / '_images/img_#1.png').exists()
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('if_online')
|
||||
@pytest.mark.sphinx('html', testroot='remote-logo')
|
||||
def test_html_remote_logo(app, status, warning):
|
||||
app.build(force_all=True)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"""Test the build process with LaTeX builder with the test root."""
|
||||
|
||||
import http.server
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
@@ -17,6 +18,8 @@ from sphinx.ext.intersphinx import setup as intersphinx_setup
|
||||
from sphinx.util.osutil import ensuredir
|
||||
from sphinx.writers.latex import LaTeXTranslator
|
||||
|
||||
from tests.utils import http_server
|
||||
|
||||
try:
|
||||
from contextlib import chdir
|
||||
except ImportError:
|
||||
@@ -79,6 +82,28 @@ def skip_if_stylefiles_notfound(testfunc):
|
||||
return testfunc
|
||||
|
||||
|
||||
class RemoteImageHandler(http.server.BaseHTTPRequestHandler):
|
||||
protocol_version = "HTTP/1.1"
|
||||
|
||||
def do_GET(self):
|
||||
content, content_type = None, None
|
||||
if self.path == "/sphinx.png":
|
||||
with open("tests/roots/test-local-logo/images/img.png", "rb") as f:
|
||||
content = f.read()
|
||||
content_type = "image/png"
|
||||
|
||||
if content:
|
||||
self.send_response(200, "OK")
|
||||
self.send_header("Content-Length", str(len(content)))
|
||||
self.send_header("Content-Type", content_type)
|
||||
self.end_headers()
|
||||
self.wfile.write(content)
|
||||
else:
|
||||
self.send_response(404, "Not Found")
|
||||
self.send_header("Content-Length", "0")
|
||||
self.end_headers()
|
||||
|
||||
|
||||
@skip_if_requested
|
||||
@skip_if_stylefiles_notfound
|
||||
@pytest.mark.parametrize(
|
||||
@@ -112,7 +137,8 @@ def test_build_latex_doc(app, engine, docclass, python_maximum_signature_line_le
|
||||
load_mappings(app)
|
||||
app.builder.init()
|
||||
LaTeXTranslator.ignore_missing_images = True
|
||||
app.build(force_all=True)
|
||||
with http_server(RemoteImageHandler):
|
||||
app.build(force_all=True)
|
||||
|
||||
# file from latex_additional_files
|
||||
assert (app.outdir / 'svgimg.svg').is_file()
|
||||
@@ -1398,21 +1424,21 @@ def test_latex_raw_directive(app, status, warning):
|
||||
assert 'LaTeX: abc def ghi' in result
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('if_online')
|
||||
@pytest.mark.sphinx('latex', testroot='images')
|
||||
def test_latex_images(app, status, warning):
|
||||
app.build(force_all=True)
|
||||
with http_server(RemoteImageHandler, port=7777):
|
||||
app.build(force_all=True)
|
||||
|
||||
result = (app.outdir / 'python.tex').read_text(encoding='utf8')
|
||||
|
||||
# images are copied
|
||||
assert '\\sphinxincludegraphics{{python-logo}.png}' in result
|
||||
assert (app.outdir / 'python-logo.png').exists()
|
||||
assert '\\sphinxincludegraphics{{sphinx}.png}' in result
|
||||
assert (app.outdir / 'sphinx.png').exists()
|
||||
|
||||
# not found images
|
||||
assert '\\sphinxincludegraphics{{NOT_EXIST}.PNG}' not in result
|
||||
assert ('WARNING: Could not fetch remote image: '
|
||||
'https://www.google.com/NOT_EXIST.PNG [404]' in warning.getvalue())
|
||||
'http://localhost:7777/NOT_EXIST.PNG [404]' in warning.getvalue())
|
||||
|
||||
# an image having target
|
||||
assert ('\\sphinxhref{https://www.sphinx-doc.org/}'
|
||||
@@ -1682,7 +1708,7 @@ def test_copy_images(app, status, warning):
|
||||
image.name for image in test_dir.rglob('*')
|
||||
if image.suffix in {'.gif', '.pdf', '.png', '.svg'}
|
||||
}
|
||||
images.discard('python-logo.png')
|
||||
images.discard('sphinx.png')
|
||||
assert images == {
|
||||
'img.pdf',
|
||||
'rimg.png',
|
||||
|
||||
Reference in New Issue
Block a user