Spaces:
Sleeping
Sleeping
| import io | |
| import json | |
| import sys | |
| import tempfile | |
| from pathlib import Path | |
| sys.path.insert(0, str(Path(__file__).resolve().parents[1])) | |
| import numpy as np | |
| import soundfile as sf | |
| from fastapi.testclient import TestClient | |
| import pipeline_runner as runner | |
| from app import app | |
| def make_wav_buffer() -> io.BytesIO: | |
| sr = 22050 | |
| y = np.zeros(sr, dtype=np.float32) | |
| for pos in [0, sr // 4, sr // 2, 3 * sr // 4]: | |
| n = min(1600, len(y) - pos) | |
| t = np.arange(n) / sr | |
| y[pos:pos + n] += 0.7 * np.exp(-t * 42) * np.sin(2 * np.pi * 90 * t) | |
| buf = io.BytesIO() | |
| sf.write(buf, y, sr, format="WAV") | |
| buf.seek(0) | |
| return buf | |
| def test_config_exposes_runtime_diagnostics() -> None: | |
| client = TestClient(app) | |
| payload = client.get("/api/config").json() | |
| assert "runtime" in payload | |
| assert payload["runtime"]["backends"]["none"]["available"] is True | |
| assert payload["defaults"]["separation_backend"] == "spleeter" | |
| def test_invalid_upload_extension_is_actionable() -> None: | |
| client = TestClient(app) | |
| response = client.post( | |
| "/api/jobs", | |
| files={"file": ("not-audio.txt", b"hello", "text/plain")}, | |
| data={"params": json.dumps({})}, | |
| ) | |
| assert response.status_code == 400 | |
| assert "Unsupported audio file extension" in response.json()["detail"] | |
| def test_spleeter_falls_back_to_full_mix_without_demucs() -> None: | |
| original_spleeter = runner._extract_spleeter_separation | |
| original_demucs = runner._extract_demucs_separation | |
| runner._extract_spleeter_separation = lambda *args, **kwargs: (_ for _ in ()).throw(RuntimeError("synthetic spleeter failure")) | |
| runner._extract_demucs_separation = lambda *args, **kwargs: (_ for _ in ()).throw(RuntimeError("demucs should not be used for Spleeter fallback")) | |
| try: | |
| with tempfile.TemporaryDirectory() as tmp: | |
| wav_path = Path(tmp) / "input.wav" | |
| wav_path.write_bytes(make_wav_buffer().getvalue()) | |
| params = runner.PipelineParams(separation_backend="spleeter", stem="drums", use_disk_cache=False, allow_backend_fallback=True) | |
| audio, sr, detail, context = runner._load_or_extract_separation(wav_path, params) | |
| assert sr == 44100 | |
| assert audio.size > 0 | |
| assert context is None | |
| assert "fallback full mix" in detail | |
| assert "Spleeter failed" in detail | |
| finally: | |
| runner._extract_spleeter_separation = original_spleeter | |
| runner._extract_demucs_separation = original_demucs | |
| if __name__ == "__main__": | |
| test_config_exposes_runtime_diagnostics() | |
| test_invalid_upload_extension_is_actionable() | |
| test_spleeter_falls_back_to_full_mix_without_demucs() | |
| print("upload/error/fallback contract passed") | |