basyx commited on
Commit
1e00a68
·
verified ·
1 Parent(s): f410022

Add diarization API security and limit tests

Browse files
Files changed (1) hide show
  1. tests/test_diarization_api.py +95 -0
tests/test_diarization_api.py ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import asyncio
4
+ from pathlib import Path
5
+ from types import SimpleNamespace
6
+
7
+ import pytest
8
+ from fastapi import HTTPException
9
+ from starlette.requests import Request
10
+
11
+ from app.api import diarization
12
+
13
+
14
+ def _request(headers: dict[str, str] | None = None) -> Request:
15
+ raw_headers = [(key.lower().encode(), value.encode()) for key, value in (headers or {}).items()]
16
+ scope = {"type": "http", "method": "POST", "path": "/v1/diarization/diarize", "headers": raw_headers}
17
+ return Request(scope)
18
+
19
+
20
+ def test_authorize_rejects_missing_configuration(monkeypatch: pytest.MonkeyPatch) -> None:
21
+ monkeypatch.delenv("DIARIZATION_API_KEY", raising=False)
22
+ with pytest.raises(HTTPException) as exc:
23
+ diarization._authorize(_request())
24
+ assert exc.value.status_code == 503
25
+
26
+
27
+ def test_authorize_rejects_invalid_key(monkeypatch: pytest.MonkeyPatch) -> None:
28
+ monkeypatch.setenv("DIARIZATION_API_KEY", "expected")
29
+ with pytest.raises(HTTPException) as exc:
30
+ diarization._authorize(_request({"Authorization": "Bearer wrong"}))
31
+ assert exc.value.status_code == 401
32
+
33
+
34
+ def test_authorize_accepts_valid_key(monkeypatch: pytest.MonkeyPatch) -> None:
35
+ monkeypatch.setenv("DIARIZATION_API_KEY", "expected")
36
+ diarization._authorize(_request({"Authorization": "Bearer expected"}))
37
+
38
+
39
+ def test_max_input_bytes_rejects_invalid_configuration(monkeypatch: pytest.MonkeyPatch) -> None:
40
+ monkeypatch.setenv("DIARIZATION_MAX_INPUT_BYTES", "not-a-number")
41
+ with pytest.raises(HTTPException) as exc:
42
+ diarization._max_input_bytes()
43
+ assert exc.value.status_code == 500
44
+
45
+
46
+ def test_max_input_bytes_rejects_too_small_configuration(monkeypatch: pytest.MonkeyPatch) -> None:
47
+ monkeypatch.setenv("DIARIZATION_MAX_INPUT_BYTES", "1024")
48
+ with pytest.raises(HTTPException) as exc:
49
+ diarization._max_input_bytes()
50
+ assert exc.value.status_code == 500
51
+
52
+
53
+ def test_max_response_spans_rejects_invalid_configuration(monkeypatch: pytest.MonkeyPatch) -> None:
54
+ monkeypatch.setenv("DIARIZATION_MAX_RESPONSE_SPANS", "0")
55
+ with pytest.raises(HTTPException) as exc:
56
+ diarization._max_response_spans()
57
+ assert exc.value.status_code == 500
58
+
59
+
60
+ def test_save_body_rejects_declared_oversize(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
61
+ monkeypatch.setenv("DIARIZATION_MAX_INPUT_BYTES", "1048576")
62
+
63
+ class StreamRequest:
64
+ headers = {"content-length": "1048577"}
65
+
66
+ def stream(self):
67
+ raise AssertionError("body should not be read after declared-size rejection")
68
+
69
+ with pytest.raises(HTTPException) as exc:
70
+ asyncio.run(diarization._save_body(StreamRequest(), tmp_path / "input"))
71
+ assert exc.value.status_code == 413
72
+
73
+
74
+ def test_run_pipeline_forwards_speaker_bounds(tmp_path: Path) -> None:
75
+ captured: dict[str, object] = {}
76
+
77
+ class FakeDiarization:
78
+ def itertracks(self, yield_label=False):
79
+ assert yield_label is True
80
+ return iter([
81
+ (SimpleNamespace(start=0.0, end=1.0), None, "SPEAKER_00"),
82
+ (SimpleNamespace(start=1.0, end=2.0), None, "SPEAKER_01"),
83
+ ])
84
+
85
+ class FakePipeline:
86
+ def __call__(self, path, **kwargs):
87
+ captured["path"] = path
88
+ captured["kwargs"] = kwargs
89
+ return FakeDiarization()
90
+
91
+ result = diarization._run_pipeline(
92
+ FakePipeline(), tmp_path / "audio.wav", min_speakers=2, max_speakers=3
93
+ )
94
+ assert captured["kwargs"] == {"min_speakers": 2, "max_speakers": 3}
95
+ assert [item["speaker"] for item in result] == ["SPEAKER_00", "SPEAKER_01"]