Files
talkscore-asr/tests/test_launcher.py
T
Vladimir BryzgalovandClaude Opus 5 b1b09664b9 Сервис сам докачивает недостающие мелкие модели
Обновление возит только папку app, поэтому переход на детектор речи
потребовал файла, которого на машине нет - и сервис узнал об этом на
первой же задаче: отказ выглядел сбоем обработки, хотя это незаконченная
установка. Причём download_models.py лежит вне app и тоже был старым,
так что штатный способ докачки не помог бы.

Список моделей и адреса переехали в app/models.py. Мелкие докачиваются
при запуске, крупная модель распознавания - нет: сотни мегабайт без спроса
тянуть нельзя. Нехватка видна в /health полем missing_models.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-17 15:42:54 +05:00

119 lines
5.7 KiB
Python

"""Проверки генерации Caddyfile и запуска."""
from app.launcher import MARK, ensure_caddyfile, render_caddyfile
class TestRender:
def test_domains_go_into_site_block(self):
text = render_caddyfile("a.example.com, b.example.com", 8756, 500)
assert "a.example.com, b.example.com {" in text
def test_extra_spaces_and_empty_entries_are_dropped(self):
text = render_caddyfile(" a.example.com ,, b.example.com ,", 8756, 500)
assert "a.example.com, b.example.com {" in text
def test_port_and_limit_come_from_settings(self):
text = render_caddyfile("a.example.com", 9000, 250)
assert "reverse_proxy 127.0.0.1:9000" in text
assert "max_size 250MB" in text
def test_xff_is_left_to_caddy_default(self):
"""Caddy сам игнорирует X-Forwarded-For от клиента и ставит реальный адрес.
Свой header_up был лишним - Caddy предупреждал об этом при каждом
запуске. Важнее обратное: trusted_proxies появляться не должен, иначе
Caddy начнёт верить заголовку клиента и адрес станет подделываемым.
"""
# Комментарии не в счёт: в них эти слова упомянуты как предостережение.
directives = "\n".join(
line for line in render_caddyfile("a.example.com", 8756, 500).splitlines()
if not line.strip().startswith("#"))
assert "header_up" not in directives
assert "trusted_proxies" not in directives
def test_caddy_log_goes_to_file(self):
"""Иначе Caddy забивает консоль сообщениями про сертификаты."""
text = render_caddyfile("a.example.com", 8756, 500)
assert "output file logs/caddy.log" in text
def test_generated_file_is_marked(self):
assert render_caddyfile("a.example.com", 8756, 500).startswith(MARK)
def test_no_blank_line_before_global_block(self):
"""caddy fmt считает такой файл неформатированным и ругается при запуске."""
lines = render_caddyfile("a.example.com", 8756, 500).splitlines()
assert lines[lines.index("{") - 1].strip() != ""
class TestEnsure:
def test_creates_file_when_missing(self, tmp_path):
content = render_caddyfile("a.example.com", 8756, 500)
written = ensure_caddyfile(tmp_path, content)
assert written == tmp_path / "Caddyfile"
assert written.read_text(encoding="utf-8") == content
def test_overwrites_own_previous_version(self, tmp_path):
ensure_caddyfile(tmp_path, render_caddyfile("old.example.com", 8756, 500))
fresh = render_caddyfile("new.example.com", 8756, 500)
ensure_caddyfile(tmp_path, fresh)
assert (tmp_path / "Caddyfile").read_text(encoding="utf-8") == fresh
assert not (tmp_path / "Caddyfile.new").exists()
def test_keeps_hand_written_file(self, tmp_path):
"""Чужой файл не трогаем: молча стереть настройку хуже, чем оставить старую."""
handmade = "site.example.com {\n\treverse_proxy 127.0.0.1:1234\n}\n"
(tmp_path / "Caddyfile").write_text(handmade, encoding="utf-8")
written = ensure_caddyfile(tmp_path, render_caddyfile("a.example.com", 8756, 500))
assert (tmp_path / "Caddyfile").read_text(encoding="utf-8") == handmade
assert written == tmp_path / "Caddyfile.new"
assert MARK in written.read_text(encoding="utf-8")
def test_no_rewrite_when_nothing_changed(self, tmp_path):
content = render_caddyfile("a.example.com", 8756, 500)
ensure_caddyfile(tmp_path, content)
before = (tmp_path / "Caddyfile").stat().st_mtime_ns
assert ensure_caddyfile(tmp_path, content) is None
assert (tmp_path / "Caddyfile").stat().st_mtime_ns == before
class TestStartupOrder:
def test_updater_runs_before_service(self, tmp_path, monkeypatch):
"""Обновиться нужно до запуска, иначе обновление бессмысленно."""
import app.launcher as launcher
calls: list[str] = []
class FakeSettings:
base_dir = tmp_path
models_dir = tmp_path / "models"
diarize = False
port = 8756
max_upload_mb = 500
https_domains = ""
monkeypatch.setattr("app.config.load_settings", lambda: FakeSettings())
monkeypatch.setattr("app.updater.main", lambda: calls.append("updater"))
monkeypatch.setattr("app.models.ensure_models", lambda *a: [])
monkeypatch.setitem(
__import__("sys").modules, "app.main",
type("M", (), {"run": staticmethod(lambda: calls.append("run"))}))
assert launcher.main([]) == 0
assert calls == ["updater", "run"]
def test_https_without_domains_stops_with_explanation(self, tmp_path, monkeypatch):
"""Пустые домены - это ошибка настройки, а не повод падать внутри Caddy."""
import app.launcher as launcher
class FakeSettings:
base_dir = tmp_path
models_dir = tmp_path / "models"
diarize = False
port = 8756
max_upload_mb = 500
https_domains = " "
monkeypatch.setattr("app.config.load_settings", lambda: FakeSettings())
monkeypatch.setattr("app.updater.main", lambda: None)
monkeypatch.setattr("app.models.ensure_models", lambda *a: [])
assert launcher.main(["https"]) == 1