ArchiveBox/archivebox/tests/test_dockerfiles.py
2026-06-05 00:18:11 -07:00

122 lines
3.8 KiB
Python

from __future__ import annotations
import re
from pathlib import Path
REPO_ROOT = Path(__file__).resolve().parents[2]
_REQUIRED_DOCKER_INSTALL_TARGETS = {
"archivewebpage",
"defuddle",
"forumdl",
"gallerydl",
"git",
"istilldontcareaboutcookies",
"liteparse",
"mercury",
"opencode",
"opendataloader",
"papersdl",
"parse_rss_urls",
"readability",
"search_backend_ripgrep",
"search_backend_sonic",
}
_REQUIRED_DOCKER_PREINSTALL_TARGETS = {
"archivewebpage",
"defuddle",
"forumdl",
"gallerydl",
"git",
"istilldontcareaboutcookies",
"liteparse",
"mercury",
"opendataloader",
"papersdl",
"parse_rss_urls",
"readability",
"search_backend_ripgrep",
"search_backend_sonic",
"ublock",
"wget",
"ytdlp",
}
_DOCKER_PREINSTALL_EXCLUDED_TARGETS = {
"twocaptcha",
}
def _archivebox_install_commands(dockerfile: Path) -> list[str]:
text = dockerfile.read_text()
return re.findall(r"archivebox install ([^\\\n]+)", text)
def _bare_archivebox_install_commands(dockerfile: Path) -> list[str]:
text = dockerfile.read_text()
return re.findall(r"archivebox install(?:\s+2>&1|\s*\\)", text)
def _abx_dl_plugin_install_targets(dockerfile: Path) -> set[str]:
text = dockerfile.read_text()
commands = re.findall(r"abx-dl plugins --install((?: \\\n|[^\n])*)", text)
targets: set[str] = set()
for command in commands:
command_text = command.replace("\\", " ")
targets.update(re.findall(r"\b[a-z][a-z0-9_]*\b", command_text))
return targets
def test_dockerfiles_install_binaries_required_by_version_validation() -> None:
for dockerfile_name in ("Dockerfile", "Dockerfile.multistage"):
commands = _archivebox_install_commands(REPO_ROOT / dockerfile_name)
target_command = max(commands, key=lambda command: len(command.split()))
targets = set(target_command.split())
assert _REQUIRED_DOCKER_INSTALL_TARGETS <= targets
def test_dockerfile_prewarms_stable_plugin_dependencies_without_optional_captcha() -> None:
text = (REPO_ROOT / "Dockerfile").read_text()
assert "archivebox/abx-dl:latest" in text
assert "archivebox/abxdl" not in text
assert _abx_dl_plugin_install_targets(REPO_ROOT / "Dockerfile") == set()
def test_dockerfile_build_installs_disable_release_age_gate() -> None:
for dockerfile_name in ("Dockerfile", "Dockerfile.multistage"):
text = (REPO_ROOT / dockerfile_name).read_text()
assert "ABXPKG_POSTINSTALL_SCRIPTS=True" in text
assert "ABXPKG_MIN_RELEASE_AGE=0" in text
def test_dockerfiles_do_not_queue_optional_binaries_during_validation() -> None:
for dockerfile_name in ("Dockerfile", "Dockerfile.multistage"):
assert _bare_archivebox_install_commands(REPO_ROOT / dockerfile_name) == []
def test_dockerfiles_clean_build_data_dir_before_init() -> None:
for dockerfile_name in ("Dockerfile", "Dockerfile.multistage"):
text = (REPO_ROOT / dockerfile_name).read_text()
assert 'find "$DATA_DIR" -mindepth 1 -maxdepth 1 -exec rm -rf {} +' in text
def test_dockerfiles_pin_project_binary_paths_for_validation() -> None:
for dockerfile_name in ("Dockerfile", "Dockerfile.multistage"):
text = (REPO_ROOT / dockerfile_name).read_text()
assert 'GIT_BINARY="$LIB_DIR/env/bin/git"' in text
assert 'GALLERYDL_BINARY="$LIB_DIR/env/bin/gallery-dl"' in text
assert 'FORUMDL_BINARY="$LIB_DIR/env/bin/forum-dl"' in text
def test_dockerfiles_use_setpriv_instead_of_gosu() -> None:
for dockerfile_name in ("Dockerfile", "Dockerfile.multistage"):
text = (REPO_ROOT / dockerfile_name).read_text()
assert "gosu" not in text
assert "setpriv" in text
entrypoint = (REPO_ROOT / "bin/docker_entrypoint.sh").read_text()
assert "gosu" not in entrypoint
assert "setpriv" in entrypoint