Spaces:
Sleeping
Sleeping
File size: 2,763 Bytes
5a90820 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | 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")
|