"""Preloading must leave ggml's runtime-selected CPU variants to ggml (#44).""" from pathlib import Path from unittest.mock import patch from vocalinux.utils import pywhispercpp_loader def _preload_names(tmp_path: Path, *names: str) -> list[str]: """Run the preloader over ``names`` in one directory and return what it dlopens.""" for name in names: (tmp_path / name).write_bytes(b"") loaded: list[str] = [] def record(path: str, mode: int = 0) -> object: loaded.append(Path(path).name) return object() with ( patch.object(pywhispercpp_loader, "find_shared_library_dirs", return_value=[str(tmp_path)]), patch.object(pywhispercpp_loader, "_PRELOADED_LIBS", []), patch.object(pywhispercpp_loader.ctypes, "CDLL", side_effect=record), ): pywhispercpp_loader.preload_shared_libraries() return loaded def test_preload_leaves_runtime_cpu_variants_to_ggml(tmp_path: Path) -> None: """Variants share one symbol table; preloading them RTLD_GLOBAL would interpose them.""" loaded = _preload_names( tmp_path, "libggml.so.0", "libggml-base.so.0", "libggml-cpu-x64.so", "libggml-cpu-haswell.so", "libggml-vulkan.so", "libwhisper.so.1", ) assert not [name for name in loaded if name.startswith("libggml-cpu-")] assert {"libggml.so.0", "libggml-base.so.0", "libggml-vulkan.so", "libwhisper.so.1"} <= set( loaded ) def test_preload_keeps_the_single_cpu_library_of_a_non_variant_build(tmp_path: Path) -> None: """Without GGML_CPU_ALL_VARIANTS the CPU backend is a dependency and must be preloaded.""" loaded = _preload_names(tmp_path, "libggml.so.0", "libggml-cpu.so") assert "libggml-cpu.so" in loaded