Files
MoviePilot/tests/test_native_dependency_activation.py
DDSRem 2de976f6b3 Merge pull request #7050 from DDSRem-Dev/codex-comment-migration
docs: 统一全项目中文注释和结构化契约说明
2026-10-17 19:26:29 +08:00

134 lines
4.2 KiB
Python

"""
已加载原生发行包的磁盘替换检测。
"""
from pathlib import Path
import app.runtime.dependencies.native as native_dependencies
class _Distribution:
"""
提供 importlib.metadata.Distribution 的最小文件契约。
"""
def __init__(self, root: Path, *, version: str) -> None:
self.root = root
self.version = version
self.metadata = {"Name": "Native_Demo"}
self.files = (
Path("native_demo/__init__.py"),
Path("native_demo/extension.cpython-314-darwin.so"),
Path("native_demo/.libs/libdemo.2.dylib"),
)
def locate_file(self, path: Path) -> Path:
"""
把发行包相对路径定位到测试根目录。
"""
return self.root / path
def _write_distribution(root: Path) -> tuple[Path, Path]:
"""
创建一个扩展模块及其旁加载本地库。
"""
extension = root / "native_demo/extension.cpython-314-darwin.so"
library = root / "native_demo/.libs/libdemo.2.dylib"
extension.parent.mkdir(parents=True)
library.parent.mkdir(parents=True)
(root / "native_demo/__init__.py").write_text("", encoding="utf-8")
extension.write_bytes(b"extension-v1")
library.write_bytes(b"library-v1")
return extension, library
def test_detects_changed_sibling_library_for_loaded_extension(tmp_path, monkeypatch):
"""
扩展已加载时,同发行包旁加载库被替换也必须要求新进程激活。
"""
extension, library = _write_distribution(tmp_path)
baseline_distribution = _Distribution(tmp_path, version="1.0.0")
monkeypatch.setattr(
native_dependencies,
"_iter_installed_distributions",
lambda: (baseline_distribution,),
)
monkeypatch.setattr(
native_dependencies,
"_loaded_native_paths",
lambda: {native_dependencies._path_key(extension)},
)
baseline = native_dependencies.capture_loaded_native_dependencies()
library.write_bytes(b"library-version-two")
current_distribution = _Distribution(tmp_path, version="2.0.0")
monkeypatch.setattr(
native_dependencies,
"distribution",
lambda _name: current_distribution,
)
changes = native_dependencies.detect_changed_native_dependencies(baseline)
assert len(changes) == 1
assert changes[0].distribution == "native-demo"
assert changes[0].previous_version == "1.0.0"
assert changes[0].current_version == "2.0.0"
assert changes[0].artifacts == ("libdemo.2.dylib",)
def test_ignores_native_distribution_that_is_not_loaded(tmp_path, monkeypatch):
"""
尚未加载的原生包首次安装或更新不需要提示重启。
"""
_write_distribution(tmp_path)
installed_distribution = _Distribution(tmp_path, version="1.0.0")
monkeypatch.setattr(
native_dependencies,
"_iter_installed_distributions",
lambda: (installed_distribution,),
)
monkeypatch.setattr(native_dependencies, "_loaded_native_paths", set)
baseline = native_dependencies.capture_loaded_native_dependencies()
assert baseline.distributions == ()
def test_unchanged_loaded_native_distribution_does_not_require_restart(
tmp_path,
monkeypatch,
):
"""
依赖安装未改变原生文件时不得产生误报。
"""
extension, _ = _write_distribution(tmp_path)
installed_distribution = _Distribution(tmp_path, version="1.0.0")
monkeypatch.setattr(
native_dependencies,
"_iter_installed_distributions",
lambda: (installed_distribution,),
)
monkeypatch.setattr(
native_dependencies,
"_loaded_native_paths",
lambda: {native_dependencies._path_key(extension)},
)
monkeypatch.setattr(
native_dependencies,
"distribution",
lambda _name: installed_distribution,
)
baseline = native_dependencies.capture_loaded_native_dependencies()
assert native_dependencies.detect_changed_native_dependencies(baseline) == ()
def test_recognizes_versioned_shared_object_names():
"""
Linux 常见的 libname.so.N 旁加载库属于原生载荷。
"""
assert native_dependencies._is_native_file("/venv/site-packages/demo/libdemo.so.3")