cleanup: remove dead archive_auditor module
archive_auditor.py not imported or used by main.py since archive metrics were removed from the monitoring loop. Remove the dead module along with its 10 tests and dead imports (ModelsMonitoringConfig, AppConfig, ArchiveEntry). Tests: 59 -> 48 (all pass)
This commit is contained in:
@@ -20,8 +20,6 @@ import pytest
|
||||
import yaml
|
||||
|
||||
from ses_monitor.config import (
|
||||
AppConfig,
|
||||
ModelsMonitoringConfig,
|
||||
ScenarioConfig,
|
||||
ScenarioStep,
|
||||
load_scenarios,
|
||||
@@ -562,419 +560,6 @@ class TestAggregateScenarioResults:
|
||||
assert agg["max_time"] == 11 # round(10.6) = 11
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# Тесты: archive_auditor.py
|
||||
# =============================================================================
|
||||
|
||||
class TestArchiveAuditor:
|
||||
"""Тесты анализа архива диалогов."""
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_audit_normal_dialogs(self):
|
||||
"""Проверяет анализ нормальных диалогов без ошибок."""
|
||||
from ses_monitor.archive_auditor import ArchiveAuditor
|
||||
|
||||
auditor = ArchiveAuditor(lookback_minutes=5)
|
||||
mock_client = AsyncMock()
|
||||
# Возвращаем пустой список — нет данных
|
||||
mock_client.get_archive.return_value = []
|
||||
|
||||
result = await auditor.audit(mock_client)
|
||||
assert result.total_dialogs == 0
|
||||
assert result.unknown_count == 0
|
||||
assert result.not_found_count == 0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_audit_with_errors(self):
|
||||
"""Проверяет анализ диалогов с ошибками."""
|
||||
from ses_monitor.archive_auditor import ArchiveAuditor
|
||||
from ses_monitor.session_client import ArchiveEntry
|
||||
|
||||
auditor = ArchiveAuditor(lookback_minutes=5)
|
||||
|
||||
# Создаём тестовые записи архива
|
||||
entries = [
|
||||
ArchiveEntry(
|
||||
id="1", session="s1", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=True, closed=None,
|
||||
endpoint=None, answered=False, conversion=False,
|
||||
models=[], events=["not found"],
|
||||
request_message="тест", last_reply="ответ",
|
||||
raw={},
|
||||
),
|
||||
ArchiveEntry(
|
||||
id="2", session="s2", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=False, closed="2026-01-01",
|
||||
endpoint=None, answered=True, conversion=True,
|
||||
models=[], events=["no data"],
|
||||
request_message="тест2", last_reply="ответ2",
|
||||
raw={},
|
||||
),
|
||||
ArchiveEntry(
|
||||
id="3", session="s3", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=False, closed=None,
|
||||
endpoint=None, answered=True, conversion=True,
|
||||
models=[], events=[],
|
||||
request_message="тест3", last_reply="ответ3",
|
||||
raw={},
|
||||
),
|
||||
]
|
||||
|
||||
mock_client = AsyncMock()
|
||||
mock_client.get_archive.return_value = entries
|
||||
|
||||
result = await auditor.audit(mock_client)
|
||||
assert result.total_dialogs == 3
|
||||
assert result.unknown_count == 1
|
||||
assert result.not_found_count == 1
|
||||
assert result.no_data_count == 1
|
||||
assert result.closed_count == 1
|
||||
assert result.answered_count == 2
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_audit_see_model_confidence(self):
|
||||
"""Проверяет мониторинг SEE: уверенность распознавания."""
|
||||
from ses_monitor.archive_auditor import ArchiveAuditor
|
||||
from ses_monitor.session_client import ArchiveEntry
|
||||
|
||||
config = ModelsMonitoringConfig(
|
||||
enabled=True,
|
||||
see_confidence_threshold=0.5,
|
||||
)
|
||||
auditor = ArchiveAuditor(lookback_minutes=5, models_config=config)
|
||||
|
||||
# Запись с высокой уверенностью SEE
|
||||
entry_high = ArchiveEntry(
|
||||
id="1", session="s1", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=False, closed=None,
|
||||
endpoint=None, answered=True, conversion=True,
|
||||
models=["see:fio"],
|
||||
events=[], request_message="тест", last_reply="ответ",
|
||||
raw={
|
||||
"request": {
|
||||
"data": [
|
||||
{
|
||||
"type": "see",
|
||||
"model": "fio",
|
||||
"reply": {"confidence": 0.95},
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
# Запись с низкой уверенностью SEE
|
||||
entry_low = ArchiveEntry(
|
||||
id="2", session="s2", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=False, closed=None,
|
||||
endpoint=None, answered=True, conversion=True,
|
||||
models=["see:fio"],
|
||||
events=[], request_message="тест2", last_reply="ответ2",
|
||||
raw={
|
||||
"request": {
|
||||
"data": [
|
||||
{
|
||||
"type": "see",
|
||||
"model": "fio",
|
||||
"reply": {"confidence": 0.3},
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
mock_client = AsyncMock()
|
||||
mock_client.get_archive.return_value = [entry_high, entry_low]
|
||||
|
||||
result = await auditor.audit(mock_client)
|
||||
assert result.see_total == 2
|
||||
assert result.see_low_confidence == 1 # Только вторая запись
|
||||
assert result.see_avg_confidence == pytest.approx(0.625, abs=0.01)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_audit_smc_model_confidence(self):
|
||||
"""Проверяет мониторинг SMC: уверенность классификации."""
|
||||
from ses_monitor.archive_auditor import ArchiveAuditor
|
||||
from ses_monitor.session_client import ArchiveEntry
|
||||
|
||||
config = ModelsMonitoringConfig(
|
||||
enabled=True,
|
||||
smc_confidence_threshold=0.7,
|
||||
)
|
||||
auditor = ArchiveAuditor(lookback_minutes=5, models_config=config)
|
||||
|
||||
entry = ArchiveEntry(
|
||||
id="1", session="s1", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=False, closed=None,
|
||||
endpoint=None, answered=True, conversion=True,
|
||||
models=["smc:test_classifier"],
|
||||
events=[], request_message="тест", last_reply="ответ",
|
||||
raw={
|
||||
"request": {
|
||||
"data": [
|
||||
{
|
||||
"type": "smc",
|
||||
"model": "test_classifier",
|
||||
"reply": {"confidence": 0.65, "class": "test"},
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
mock_client = AsyncMock()
|
||||
mock_client.get_archive.return_value = [entry]
|
||||
|
||||
result = await auditor.audit(mock_client)
|
||||
assert result.smc_total == 1
|
||||
assert result.smc_low_confidence == 1 # 0.65 < 0.7
|
||||
assert result.smc_avg_confidence == 0.65
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_audit_tts_voice_detection(self):
|
||||
"""Проверяет мониторинг TTS: наличие голосовых ответов."""
|
||||
from ses_monitor.archive_auditor import ArchiveAuditor
|
||||
from ses_monitor.session_client import ArchiveEntry
|
||||
|
||||
config = ModelsMonitoringConfig(enabled=True, tts_enabled=True)
|
||||
auditor = ArchiveAuditor(lookback_minutes=5, models_config=config)
|
||||
|
||||
entry = ArchiveEntry(
|
||||
id="1", session="s1", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=False, closed=None,
|
||||
endpoint=None, answered=True, conversion=True,
|
||||
models=[], events=[], request_message="тест", last_reply="ответ",
|
||||
raw={
|
||||
"reply": {
|
||||
"answers": [
|
||||
{"messages": ["здравствуйте"], "voice": "Коля"},
|
||||
{"messages": ["до свидания"], "voice": ""},
|
||||
]
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
mock_client = AsyncMock()
|
||||
mock_client.get_archive.return_value = [entry]
|
||||
|
||||
result = await auditor.audit(mock_client)
|
||||
assert result.tts_voice_present == 1
|
||||
assert result.tts_voice_missing == 1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_audit_qas_emptiness(self):
|
||||
"""Проверяет мониторинг QAS: пустые ответы."""
|
||||
from ses_monitor.archive_auditor import ArchiveAuditor
|
||||
from ses_monitor.session_client import ArchiveEntry
|
||||
|
||||
config = ModelsMonitoringConfig(enabled=True, qas_enabled=True)
|
||||
auditor = ArchiveAuditor(lookback_minutes=5, models_config=config)
|
||||
|
||||
entry_empty = ArchiveEntry(
|
||||
id="1", session="s1", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=False, closed=None,
|
||||
endpoint=None, answered=True, conversion=True,
|
||||
models=[], events=[], request_message="тест", last_reply="ответ",
|
||||
raw={"current": {"qas": ""}},
|
||||
)
|
||||
entry_filled = ArchiveEntry(
|
||||
id="2", session="s2", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=False, closed=None,
|
||||
endpoint=None, answered=True, conversion=True,
|
||||
models=[], events=[], request_message="тест2", last_reply="ответ2",
|
||||
raw={"current": {"qas": "какой-то ответ QAS"}},
|
||||
)
|
||||
|
||||
mock_client = AsyncMock()
|
||||
mock_client.get_archive.return_value = [entry_empty, entry_filled]
|
||||
|
||||
result = await auditor.audit(mock_client)
|
||||
assert result.qas_total == 2
|
||||
assert result.qas_empty == 1
|
||||
assert result.qas_filled == 1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_audit_spr_reports(self):
|
||||
"""Проверяет мониторинг SPR: наполненность reports."""
|
||||
from ses_monitor.archive_auditor import ArchiveAuditor
|
||||
from ses_monitor.session_client import ArchiveEntry
|
||||
|
||||
config = ModelsMonitoringConfig(enabled=True, spr_enabled=True)
|
||||
auditor = ArchiveAuditor(lookback_minutes=5, models_config=config)
|
||||
|
||||
entry_filled = ArchiveEntry(
|
||||
id="1", session="s1", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=False, closed=None,
|
||||
endpoint=None, answered=True, conversion=True,
|
||||
models=[], events=[], request_message="тест", last_reply="ответ",
|
||||
raw={"reports": {"recognition": "текст расшифровки"}},
|
||||
)
|
||||
entry_empty = ArchiveEntry(
|
||||
id="2", session="s2", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=False, closed=None,
|
||||
endpoint=None, answered=True, conversion=True,
|
||||
models=[], events=[], request_message="тест2", last_reply="ответ2",
|
||||
raw={"reports": {}},
|
||||
)
|
||||
|
||||
mock_client = AsyncMock()
|
||||
mock_client.get_archive.return_value = [entry_filled, entry_empty]
|
||||
|
||||
result = await auditor.audit(mock_client)
|
||||
assert result.spr_total == 2
|
||||
assert result.spr_filled == 1
|
||||
assert result.spr_empty == 1
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_audit_models_disabled(self):
|
||||
"""Проверяет что при отключённом model_monitoring метрики нулевые."""
|
||||
from ses_monitor.archive_auditor import ArchiveAuditor
|
||||
from ses_monitor.session_client import ArchiveEntry
|
||||
|
||||
config = ModelsMonitoringConfig(enabled=False)
|
||||
auditor = ArchiveAuditor(lookback_minutes=5, models_config=config)
|
||||
|
||||
entry = ArchiveEntry(
|
||||
id="1", session="s1", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=False, closed=None,
|
||||
endpoint=None, answered=True, conversion=True,
|
||||
models=["see:fio"],
|
||||
events=[], request_message="тест", last_reply="ответ",
|
||||
raw={
|
||||
"request": {
|
||||
"data": [
|
||||
{"type": "see", "model": "fio", "reply": {"confidence": 0.3}}
|
||||
]
|
||||
},
|
||||
"reply": {"answers": [{"voice": "Коля"}]},
|
||||
"current": {"qas": "ответ"},
|
||||
"reports": {"rec": "текст"},
|
||||
},
|
||||
)
|
||||
|
||||
mock_client = AsyncMock()
|
||||
mock_client.get_archive.return_value = [entry]
|
||||
|
||||
result = await auditor.audit(mock_client)
|
||||
# Все model-метрики должны быть нулевыми
|
||||
assert result.see_total == 0
|
||||
assert result.smc_total == 0
|
||||
assert result.tts_voice_present == 0
|
||||
assert result.qas_total == 0
|
||||
assert result.spr_total == 0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_audit_step_time_normal(self):
|
||||
"""Проверяет расчёт времени шага диалога из архива."""
|
||||
from ses_monitor.archive_auditor import ArchiveAuditor
|
||||
from ses_monitor.session_client import ArchiveEntry
|
||||
|
||||
auditor = ArchiveAuditor(lookback_minutes=5, step_time_enabled=True)
|
||||
|
||||
entry1 = ArchiveEntry(
|
||||
id="1", session="s-fast", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=False, closed=None,
|
||||
endpoint=None, answered=True, conversion=True,
|
||||
models=[], events=[], request_message="быстрый запрос",
|
||||
last_reply="быстрый ответ",
|
||||
raw={
|
||||
"request": {"datetime": "2026-06-19 10:00:00"},
|
||||
"reply": {"datetime": "2026-06-19 10:00:01"},
|
||||
},
|
||||
)
|
||||
entry2 = ArchiveEntry(
|
||||
id="2", session="s-slow", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=False, closed=None,
|
||||
endpoint=None, answered=True, conversion=True,
|
||||
models=[], events=[], request_message="медленный запрос",
|
||||
last_reply="медленный ответ",
|
||||
raw={
|
||||
"request": {"datetime": "2026-06-19 10:00:00"},
|
||||
"reply": {"datetime": "2026-06-19 10:00:03"},
|
||||
},
|
||||
)
|
||||
|
||||
mock_client = AsyncMock()
|
||||
mock_client.get_archive.return_value = [entry1, entry2]
|
||||
|
||||
result = await auditor.audit(mock_client)
|
||||
assert result._step_time_count == 2
|
||||
assert result.max_step_time_ms == 3000.0 # 3 секунды
|
||||
assert result.avg_step_time_ms == 2000.0 # (1000 + 3000) / 2
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_audit_step_time_missing_dates(self):
|
||||
"""Проверяет что записи без datetime не ломают расчёт."""
|
||||
from ses_monitor.archive_auditor import ArchiveAuditor
|
||||
from ses_monitor.session_client import ArchiveEntry
|
||||
|
||||
auditor = ArchiveAuditor(lookback_minutes=5, step_time_enabled=True)
|
||||
|
||||
entry_no_dates = ArchiveEntry(
|
||||
id="1", session="s-nodate", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=False, closed=None,
|
||||
endpoint=None, answered=True, conversion=True,
|
||||
models=[], events=[], request_message="тест", last_reply="ответ",
|
||||
raw={},
|
||||
)
|
||||
entry_partial = ArchiveEntry(
|
||||
id="2", session="s-partial", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=False, closed=None,
|
||||
endpoint=None, answered=True, conversion=True,
|
||||
models=[], events=[], request_message="тест2", last_reply="ответ2",
|
||||
raw={
|
||||
"request": {"datetime": "2026-06-19 10:00:00"},
|
||||
# Нет reply.datetime
|
||||
},
|
||||
)
|
||||
entry_bad_format = ArchiveEntry(
|
||||
id="3", session="s-bad", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=False, closed=None,
|
||||
endpoint=None, answered=True, conversion=True,
|
||||
models=[], events=[], request_message="тест3", last_reply="ответ3",
|
||||
raw={
|
||||
"request": {"datetime": "неправильный формат"},
|
||||
"reply": {"datetime": "2026-06-19 10:00:01"},
|
||||
},
|
||||
)
|
||||
|
||||
mock_client = AsyncMock()
|
||||
mock_client.get_archive.return_value = [entry_no_dates, entry_partial, entry_bad_format]
|
||||
|
||||
result = await auditor.audit(mock_client)
|
||||
# Ни одна запись не дала времени — всё пропущено
|
||||
assert result._step_time_count == 0
|
||||
assert result.max_step_time_ms == 0.0
|
||||
assert result.avg_step_time_ms == 0.0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_audit_step_time_disabled(self):
|
||||
"""Проверяет что при отключённом step_time метрики нулевые."""
|
||||
from ses_monitor.archive_auditor import ArchiveAuditor
|
||||
from ses_monitor.session_client import ArchiveEntry
|
||||
|
||||
auditor = ArchiveAuditor(lookback_minutes=5, step_time_enabled=False)
|
||||
|
||||
entry = ArchiveEntry(
|
||||
id="1", session="s1", robot="test-bot", hostname="test",
|
||||
channel="telegram", unknown=False, closed=None,
|
||||
endpoint=None, answered=True, conversion=True,
|
||||
models=[], events=[], request_message="тест", last_reply="ответ",
|
||||
raw={
|
||||
"request": {"datetime": "2026-06-19 10:00:00"},
|
||||
"reply": {"datetime": "2026-06-19 10:00:05"},
|
||||
},
|
||||
)
|
||||
|
||||
mock_client = AsyncMock()
|
||||
mock_client.get_archive.return_value = [entry]
|
||||
|
||||
result = await auditor.audit(mock_client)
|
||||
assert result._step_time_count == 0
|
||||
assert result.max_step_time_ms == 0.0
|
||||
assert result.avg_step_time_ms == 0.0
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
class TestUserParameterWriter:
|
||||
"""Тесты для UserParameterWriter."""
|
||||
|
||||
Reference in New Issue
Block a user