fix(acoustid): 测试函数独立检测本地 fpcalc 依赖而非仅校验网络

原先 test() 依赖 init_module() 一次性缓存的 self._fpcalc_path,初始化之后再安装或移除 fpcalc 都不会反映在测试结果中,导致 UI 测试可能错误显示为通过。

- 抽出静态方法 _resolve_fpcalc() 基于 shutil.which 定位可执行 fpcalc,init_module() 复用
- test() 每次自行重新定位 fpcalc,缺失则直接失败且不发起网络请求,并写回 self._fpcalc_path
- 新增 3 个回归用例覆盖本地依赖检测与独立于 init 缓存的行为
This commit is contained in:
jxxghp
2026-08-17 11:07:13 +08:00
parent 77b7960b7d
commit 23ca70fa37
2 changed files with 68 additions and 3 deletions
+18 -3
View File
@@ -34,9 +34,17 @@ class AcoustIdModule(_ModuleBase):
self._cache: OrderedDict[tuple[str, int, int], Optional[str]] = OrderedDict()
self._cache_lock = threading.Lock()
@staticmethod
def _resolve_fpcalc() -> Optional[str]:
"""在 PATH 中定位可执行的 fpcalc,返回其绝对路径,缺失则返回 None。
shutil.which 在 POSIX 上已校验文件可执行,足以判定本地依赖是否就绪。
"""
return shutil.which("fpcalc") or None
def init_module(self) -> None:
"""定位 fpcalc 工具并清空可能过期的文件识别缓存。"""
self._fpcalc_path = shutil.which("fpcalc")
self._fpcalc_path = self._resolve_fpcalc()
with self._cache_lock:
self._cache.clear()
if not self._fpcalc_path:
@@ -52,11 +60,18 @@ class AcoustIdModule(_ModuleBase):
self._cache.clear()
def test(self) -> Tuple[bool, str]:
"""检查 API Key、fpcalc AcoustID API 的基础连通性。"""
"""检查 API Key、本地 fpcalc 依赖与 AcoustID API 的基础连通性。
本地依赖检测独立于 init_module 的缓存快照,重新定位 fpcalc,确保即便
模块初始化早于 fpcalc 安装,或运行期依赖被移除,测试也能如实反映本地
依赖状态,而不是只校验网络连通性。
"""
if not str(settings.ACOUSTID_API_KEY or "").strip():
return False, "AcoustID API Key 未配置"
if not self._fpcalc_path:
fpcalc_path = self._resolve_fpcalc()
if not fpcalc_path:
return False, "未找到 fpcalc,请先安装 Chromaprint"
self._fpcalc_path = fpcalc_path
response = RequestUtils(
ua=settings.USER_AGENT,
proxies=settings.PROXY,