mirror of
https://github.com/ArchiveBox/ArchiveBox.git
synced 2026-09-12 19:50:57 +05:00
275 lines
9.4 KiB
Python
275 lines
9.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Tests for archivebox version command.
|
|
Verify version output and system information reporting.
|
|
"""
|
|
|
|
import os
|
|
import re
|
|
import tempfile
|
|
from pathlib import Path
|
|
from archivebox.config.paths import tmp_dir_socket_path_is_short_enough
|
|
from archivebox.cli.archivebox_version import _binary_row_dedupe_key
|
|
from archivebox.tests.conftest import cli_env, run_archivebox_cmd
|
|
|
|
|
|
def _make_deep_collection_dir(tmp_path: Path) -> Path:
|
|
deep_dir = tmp_path / "deep-collection"
|
|
for idx in range(6):
|
|
deep_dir /= f"segment-{idx}-1234567890abcdef"
|
|
deep_dir.mkdir(parents=True)
|
|
return deep_dir
|
|
|
|
|
|
def _extract_location_path(output: str, key: str) -> Path:
|
|
for line in output.splitlines():
|
|
if key not in line:
|
|
continue
|
|
columns = [column for column in re.split(r"\s{2,}", line.strip()) if column]
|
|
if len(columns) >= 5 and columns[1] == key:
|
|
return Path(os.path.expanduser(columns[-1]))
|
|
raise AssertionError(f"Did not find a {key} location line in output:\n{output}")
|
|
|
|
|
|
def test_binary_row_dedupe_key_keeps_distinct_paths_visible(tmp_path):
|
|
first_path = tmp_path / "lib" / "env" / "bin" / "node"
|
|
second_path = tmp_path / "other" / "bin" / "node"
|
|
first_path.parent.mkdir(parents=True)
|
|
second_path.parent.mkdir(parents=True)
|
|
|
|
first = _binary_row_dedupe_key(
|
|
display_name="node",
|
|
valid=True,
|
|
version="26.0.0",
|
|
provider="env",
|
|
abspath=str(first_path),
|
|
)
|
|
repeat = _binary_row_dedupe_key(
|
|
display_name="node",
|
|
valid=True,
|
|
version="26.0.0",
|
|
provider="env",
|
|
abspath=str(first_path),
|
|
)
|
|
different_path = _binary_row_dedupe_key(
|
|
display_name="node",
|
|
valid=True,
|
|
version="26.0.0",
|
|
provider="env",
|
|
abspath=str(second_path),
|
|
)
|
|
|
|
assert repeat == first
|
|
assert different_path != first
|
|
|
|
|
|
def test_binary_row_dedupe_key_collapses_enabled_and_disabled_plugin_references(tmp_path):
|
|
binary_path = tmp_path / "bin" / "node"
|
|
binary_path.parent.mkdir(parents=True)
|
|
|
|
enabled_reference = _binary_row_dedupe_key(
|
|
display_name="node",
|
|
valid=True,
|
|
version="26.0.0",
|
|
provider="env",
|
|
abspath=str(binary_path),
|
|
)
|
|
disabled_reference = _binary_row_dedupe_key(
|
|
display_name="node",
|
|
valid=True,
|
|
version="26.0.0",
|
|
provider="env",
|
|
abspath=str(binary_path),
|
|
)
|
|
|
|
assert disabled_reference == enabled_reference
|
|
|
|
|
|
def test_version_quiet_outputs_version_number(tmp_path):
|
|
"""Test that version --quiet outputs just the version number."""
|
|
result = run_archivebox_cmd(["version", "--quiet"])
|
|
|
|
assert result.returncode == 0
|
|
version = result.stdout.strip()
|
|
assert version
|
|
# Version should be semver-ish format (e.g., 0.8.0)
|
|
parts = version.split(".")
|
|
assert len(parts) >= 2
|
|
|
|
|
|
def test_version_flag_outputs_version_number(tmp_path):
|
|
"""Test that top-level --version reports the package version."""
|
|
result = run_archivebox_cmd(["--version"])
|
|
|
|
assert result.returncode == 0
|
|
version = result.stdout.strip()
|
|
assert version
|
|
assert len(version.split(".")) >= 2
|
|
|
|
|
|
def test_version_shows_system_info_in_initialized_dir(tmp_path, initialized_archive):
|
|
"""Test that version shows system metadata in initialized directory."""
|
|
result = run_archivebox_cmd(["version", "--binaries=curl"])
|
|
|
|
output = result.stdout
|
|
assert "ArchiveBox" in output
|
|
# Should show system info
|
|
assert any(x in output for x in ["ARCH=", "OS=", "PYTHON="])
|
|
|
|
|
|
def test_version_shows_binaries_after_init(tmp_path, initialized_archive):
|
|
"""Test that version shows binary dependencies in initialized directory."""
|
|
result = run_archivebox_cmd(["version"])
|
|
|
|
output = result.stdout
|
|
# Should show binary section
|
|
assert "Binary" in output or "Dependencies" in output
|
|
|
|
|
|
def test_version_skips_disabled_plugin_binary_resolution(tmp_path):
|
|
"""Disabled plugins should not trigger live binary detection during version."""
|
|
data_dir = tmp_path / "no-plugins"
|
|
data_dir.mkdir()
|
|
env = cli_env(PLUGINS="__archivebox_test_no_plugins__", SEARCH_BACKEND_ENGINE="")
|
|
|
|
init_result = run_archivebox_cmd(["init"], cwd=data_dir, env=env)
|
|
assert init_result.returncode == 0, init_result.stderr
|
|
|
|
version_result = run_archivebox_cmd(["version"], cwd=data_dir, env=env)
|
|
output = version_result.stdout + version_result.stderr
|
|
|
|
assert version_result.returncode == 0, output
|
|
assert "No required binaries declared for discovered plugins" in output
|
|
assert "not installed" not in output
|
|
|
|
|
|
def test_version_honors_legacy_save_aliases_when_disabling_extractors(tmp_path):
|
|
"""Legacy SAVE_* aliases should disable their canonical plugin flags."""
|
|
data_dir = tmp_path / "legacy-save-disabled"
|
|
data_dir.mkdir()
|
|
env = {"PLUGINS": "wget,title", "SEARCH_BACKEND_ENGINE": ""}
|
|
|
|
init_result = run_archivebox_cmd(["init"], cwd=data_dir, env=env, default_cli_env=True, disable_extractors=True, timeout=120)
|
|
assert init_result.returncode == 0, init_result.stderr or init_result.stdout
|
|
|
|
config_result = run_archivebox_cmd(
|
|
["config", "--get", "WGET_ENABLED", "TITLE_ENABLED", "CHROME_ENABLED"],
|
|
cwd=data_dir,
|
|
env=env,
|
|
default_cli_env=True,
|
|
disable_extractors=True,
|
|
)
|
|
config_output = config_result.stdout + config_result.stderr
|
|
assert config_result.returncode == 0, config_output
|
|
assert "WGET_ENABLED = false" in config_output
|
|
assert "TITLE_ENABLED = false" in config_output
|
|
assert "CHROME_ENABLED = false" in config_output
|
|
|
|
version_result = run_archivebox_cmd(
|
|
["version"],
|
|
cwd=data_dir,
|
|
env=env,
|
|
default_cli_env=True,
|
|
disable_extractors=True,
|
|
timeout=60,
|
|
)
|
|
output = version_result.stdout + version_result.stderr
|
|
|
|
assert version_result.returncode == 0, output
|
|
assert "not installed" not in output
|
|
|
|
|
|
def test_plugins_selection_includes_required_plugins_via_config_cli(tmp_path):
|
|
"""PLUGINS selection should include transitive plugin dependencies exactly once."""
|
|
data_dir = tmp_path / "plugin-dependencies"
|
|
data_dir.mkdir()
|
|
env = {"PLUGINS": "wget,screenshot"}
|
|
|
|
init_result = run_archivebox_cmd(["init"], cwd=data_dir, env=env, default_cli_env=True, timeout=120)
|
|
assert init_result.returncode == 0, init_result.stderr or init_result.stdout
|
|
|
|
config_result = run_archivebox_cmd(
|
|
["config", "--get", "WGET_ENABLED", "SCREENSHOT_ENABLED", "CHROME_ENABLED", "YTDLP_ENABLED"],
|
|
cwd=data_dir,
|
|
env=env,
|
|
default_cli_env=True,
|
|
)
|
|
config_output = config_result.stdout + config_result.stderr
|
|
|
|
assert config_result.returncode == 0, config_output
|
|
assert "WGET_ENABLED = true" in config_output
|
|
assert "SCREENSHOT_ENABLED = true" in config_output
|
|
assert "CHROME_ENABLED = true" in config_output
|
|
assert "YTDLP_ENABLED = false" in config_output
|
|
|
|
|
|
def test_version_shows_data_locations(tmp_path, initialized_archive):
|
|
"""Test that version shows data directory locations."""
|
|
result = run_archivebox_cmd(["version"])
|
|
|
|
output = result.stdout
|
|
# Should show paths
|
|
assert any(x in output for x in ["Data", "Code", "location"])
|
|
|
|
|
|
def test_version_in_uninitialized_dir_still_works(tmp_path):
|
|
"""Test that version command works even without initialized data dir."""
|
|
empty_dir = tmp_path / "empty"
|
|
empty_dir.mkdir()
|
|
|
|
result = run_archivebox_cmd(["version", "--quiet"], cwd=empty_dir)
|
|
|
|
# Should still output version
|
|
assert result.returncode == 0
|
|
assert len(result.stdout.strip()) > 0
|
|
|
|
|
|
def test_version_auto_selects_short_tmp_dir_for_deep_collection_path(tmp_path):
|
|
"""Test the real CLI init/version flow auto-selects a short TMP_DIR outside deep collections."""
|
|
data_dir = _make_deep_collection_dir(tmp_path)
|
|
default_tmp_dir = data_dir / "tmp"
|
|
extra_env = {"ARCHIVEBOX_ALLOW_NO_UNIX_SOCKETS": "true"}
|
|
|
|
with tempfile.TemporaryDirectory(prefix="abx-home-") as home_tmp:
|
|
home_dir = Path(home_tmp)
|
|
env = {
|
|
"HOME": str(home_dir),
|
|
"USE_COLOR": "False",
|
|
"SHOW_PROGRESS": "False",
|
|
**extra_env,
|
|
}
|
|
|
|
init_result = run_archivebox_cmd(["init", "--quick"], cwd=data_dir, env=env, timeout=180)
|
|
assert init_result.returncode == 0, init_result.stdout + init_result.stderr
|
|
|
|
version_result = run_archivebox_cmd(["version"], cwd=data_dir, env=env, timeout=180)
|
|
output = version_result.stdout + version_result.stderr
|
|
|
|
assert version_result.returncode == 0, output
|
|
assert "ArchiveBox" in output
|
|
assert "TMP_DIR" in output
|
|
assert "Error with configured TMP_DIR" not in output
|
|
|
|
reported_tmp_dir = _extract_location_path(output, "TMP_DIR")
|
|
if not reported_tmp_dir.is_absolute():
|
|
reported_tmp_dir = (data_dir / reported_tmp_dir).resolve()
|
|
|
|
assert reported_tmp_dir.exists()
|
|
assert not reported_tmp_dir.is_relative_to(default_tmp_dir)
|
|
assert tmp_dir_socket_path_is_short_enough(reported_tmp_dir)
|
|
|
|
|
|
def test_version_help_lists_quiet_flag(tmp_path):
|
|
"""Test that version --help documents the quiet output mode."""
|
|
result = run_archivebox_cmd(["version", "--help"])
|
|
|
|
assert result.returncode == 0
|
|
assert "--quiet" in result.stdout or "-q" in result.stdout
|
|
|
|
|
|
def test_version_invalid_option_fails(tmp_path):
|
|
"""Test that invalid version options fail cleanly."""
|
|
result = run_archivebox_cmd(["version", "--invalid-option"])
|
|
|
|
assert result.returncode != 0
|