Files
unshackle/tests/conftest.py
T
imSp4rky 3027592e31 fix: drop null vault keys, cap snapshot restore size, isolate test globals
Vaults.add_keys and kv add skip null content keys instead of failing the batch; is_null_key moves to core.vault. A manifest snapshot restore has one 32 MiB inflate budget. Tests reset the speed limiter and config between runs.
2026-11-02 22:01:02 -07:00

94 lines
3.5 KiB
Python

"""Suite-wide test setup."""
from __future__ import annotations
import importlib
import socket
import socketserver
from pathlib import Path
from typing import Any, Callable, Optional
import pytest
from unshackle.core import binaries
from unshackle.core.config import config
from unshackle.core.proxies.proxy import CATALOGUES
from unshackle.core.update_checker import UpdateChecker
requests_downloader = importlib.import_module("unshackle.core.downloaders.requests")
# shutdown() blocks until the serve loop polls again, and the 0.5s default is paid by every
# test server at teardown. The default changes for the whole process, servers in core included.
socketserver.BaseServer.serve_forever.__defaults__ = (0.01,)
@pytest.fixture(autouse=True)
def loopback_only(request: pytest.FixtureRequest, monkeypatch: pytest.MonkeyPatch) -> None:
"""Fail a name lookup for any host but loopback, so a stray request cannot hang a unit test."""
if request.node.get_closest_marker("live") or request.node.get_closest_marker("slow"):
return
resolve = socket.getaddrinfo
def offline(host: Any, *args: Any, **kwargs: Any) -> Any:
if host not in (None, "", "localhost", "127.0.0.1", "::1"):
raise socket.gaierror(socket.EAI_NONAME, f"unit tests are offline: {host!r} is not loopback")
return resolve(host, *args, **kwargs)
monkeypatch.setattr(socket, "getaddrinfo", offline)
@pytest.fixture(autouse=True)
def no_update_check(monkeypatch: pytest.MonkeyPatch) -> None:
"""Keep the release lookup of the health route off the network."""
monkeypatch.setattr(UpdateChecker, "check_for_updates_sync", lambda *args, **kwargs: None)
@pytest.fixture(autouse=True)
def fresh_proxy_catalogues() -> None:
"""Fetch each proxy provider catalogue again, so one test's stub never answers another test."""
CATALOGUES.clear()
@pytest.fixture(autouse=True)
def default_muxing(monkeypatch: pytest.MonkeyPatch) -> None:
"""Mux with the default options, whatever the muxing block of the local unshackle.yaml sets."""
monkeypatch.setattr(config, "muxing", {})
@pytest.fixture(autouse=True)
def default_codec_names(monkeypatch: pytest.MonkeyPatch) -> None:
"""Name codecs with the built-in labels, whatever codec_names the local unshackle.yaml sets."""
monkeypatch.setattr(config, "codec_names", {})
@pytest.fixture(autouse=True)
def no_speed_limit(monkeypatch: pytest.MonkeyPatch) -> None:
"""Start with no speed limit, so a limit that an earlier test locked cannot block a later one."""
monkeypatch.setattr(requests_downloader, "speed_limiter", None)
monkeypatch.setattr(requests_downloader, "speed_limit_locked", False)
@pytest.fixture
def mux_args(monkeypatch: pytest.MonkeyPatch) -> Callable[..., list[str]]:
"""Run Tracks.mux up to mkvmerge and return its arguments; ``ids`` is what the track ID probe reports."""
class Stop(Exception):
pass
def run(tracks: Any, ids: Optional[dict[str, int]] = None, **kwargs: Any) -> list[str]:
captured: list[list[str]] = []
def fake_popen(args: list[str], **_: object) -> None:
captured.append(args)
raise Stop
monkeypatch.setattr("unshackle.core.tracks.tracks.subprocess.Popen", fake_popen)
monkeypatch.setattr("unshackle.core.tracks.tracks.file_track_ids", lambda path: ids or {"video": 0})
monkeypatch.setattr(binaries, "MKVToolNix", Path("mkvmerge"))
with pytest.raises(Stop):
tracks.mux("Title", delete=False, **kwargs)
return captured[0]
return run