AI-RVC / tests /test_ffmpeg_runtime.py
mason369's picture
Release v1.2.1
a9536c4 verified
Raw
History Blame Contribute Delete
4.87 kB
import importlib.util
import os
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
from unittest import mock
REPO_ROOT = Path(__file__).resolve().parents[1]
def _load_ffmpeg_runtime_module():
module_path = REPO_ROOT / "lib" / "ffmpeg_runtime.py"
spec = importlib.util.spec_from_file_location("ffmpeg_runtime", module_path)
if spec is None or spec.loader is None:
raise ImportError(f"Unable to load module from {module_path}")
module = importlib.util.module_from_spec(spec)
sys.modules[spec.name] = module
spec.loader.exec_module(module)
return module
class FfmpegRuntimeTests(unittest.TestCase):
def test_bundled_ffmpeg_dir_is_preferred(self):
module = _load_ffmpeg_runtime_module()
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
bin_dir = root / "tools" / "ffmpeg" / "bin"
bin_dir.mkdir(parents=True, exist_ok=True)
(bin_dir / "ffmpeg.exe").write_bytes(b"exe")
resolved = module.get_ffmpeg_bin_dir(root_dir=root)
self.assertEqual(resolved, bin_dir)
def test_runtime_setup_prepends_bundled_ffmpeg_to_path(self):
module = _load_ffmpeg_runtime_module()
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
bin_dir = root / "tools" / "ffmpeg" / "bin"
bin_dir.mkdir(parents=True, exist_ok=True)
ffmpeg = bin_dir / "ffmpeg.exe"
ffmpeg.write_bytes(b"exe")
ffprobe = bin_dir / "ffprobe.exe"
ffprobe.write_bytes(b"exe")
env = {"PATH": r"C:\Windows\System32"}
with mock.patch.object(
module,
"_check_executable_runs",
return_value=None,
):
module.configure_ffmpeg_runtime(root_dir=root, env=env)
self.assertTrue(env["PATH"].startswith(str(bin_dir)))
self.assertEqual(env["FFMPEG_BINARY"], str(ffmpeg))
self.assertEqual(env["FFPROBE_BINARY"], str(ffprobe))
def test_runtime_rejects_broken_bundled_ffprobe(self):
module = _load_ffmpeg_runtime_module()
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
bin_dir = root / "tools" / "ffmpeg" / "bin"
bin_dir.mkdir(parents=True, exist_ok=True)
(bin_dir / "ffmpeg.exe").write_bytes(b"exe")
ffprobe = bin_dir / "ffprobe.exe"
ffprobe.write_bytes(b"broken")
def fake_run(command, **kwargs):
executable = Path(command[0]).name.lower()
if executable == "ffmpeg.exe":
return subprocess.CompletedProcess(command, 0, stdout="ffmpeg version", stderr="")
return subprocess.CompletedProcess(
command,
1,
stdout="Cannot find file at '..\\lib\\ffmpeg\\tools\\ffmpeg\\bin\\ffprobe.exe'",
stderr="",
)
with mock.patch.object(module.subprocess, "run", side_effect=fake_run):
with self.assertRaises(RuntimeError) as context:
module.configure_ffmpeg_runtime(root_dir=root, env={"PATH": ""})
message = str(context.exception)
self.assertIn(str(ffprobe), message)
self.assertIn("Cannot find file", message)
def test_uvr5_module_does_not_shell_out_to_ffprobe(self):
source = (REPO_ROOT / "infer" / "modules" / "uvr5" / "modules.py").read_text(encoding="utf-8")
self.assertNotIn('cmd="ffprobe"', source)
def test_run_configures_bundled_ffmpeg_runtime(self):
source = (REPO_ROOT / "run.py").read_text(encoding="utf-8")
self.assertIn("configure_ffmpeg_runtime()", source)
def test_workflow_packages_bundled_ffmpeg_directory(self):
workflow = (REPO_ROOT / ".github" / "workflows" / "build-executables.yml").read_text(encoding="utf-8")
self.assertIn("tools/ffmpeg", workflow)
def test_workflow_resolves_real_chocolatey_ffprobe_and_validates_bundle(self):
workflow = (REPO_ROOT / ".github" / "workflows" / "build-executables.yml").read_text(encoding="utf-8")
self.assertIn("ChocolateyInstall", workflow)
self.assertIn("ffprobe_dest", workflow)
self.assertIn("subprocess.run([str(ffprobe_dest), \"-version\"]", workflow)
def test_release_upload_uses_timeout_and_retry(self):
workflow = (REPO_ROOT / ".github" / "workflows" / "build-executables.yml").read_text(encoding="utf-8")
self.assertIn("upload_asset_with_retry", workflow)
self.assertIn("timeout 30m gh release upload", workflow)
if __name__ == "__main__":
unittest.main()