fix(readiness): роль на резерве считается работающей
Со скриншота владельца: заголовок «Ролей в строю: 0/6», а ниже шесть предупреждений «роль работает через резервный аккаунт». Пять ролей исправно отвечали, интерфейс сообщал, что не работает ни одна. roles_ready считал только роли со здоровым ОСНОВНЫМ профилем. Роль, обслуживаемая резервом, попадала в degraded_roles, но не в ready. Ошибка в худшую сторону: отказ показывался там, где всё работает — а переключение на резерв это ровно то, ради чего продукт и создан. Теперь роль с живым резервом считается работающей и одновременно помечается деградировавшей: оба состояния остаются различимыми. Попутно склонение: «Есть 1 ролей без рабочего маршрута» заменено на согласованное с числом — 1 роль, 2 роли, 5 ролей. Проверено на живых данных: 6/6 в строю, состояние «деградация», а не «критическое». Тесты: 375 passed, ruff чисто. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
bca88a56a6
commit
03d73f8d0b
2 changed files with 62 additions and 2 deletions
|
|
@ -170,6 +170,17 @@ class ProviderSummary:
|
|||
last_refresh_at: str
|
||||
|
||||
|
||||
def _plural_roles(n: int) -> str:
|
||||
"""Согласовать число со словом «роль»: 1 роль, 2 роли, 5 ролей."""
|
||||
tail = n % 100
|
||||
if 11 <= tail <= 14:
|
||||
word = "ролей"
|
||||
else:
|
||||
last = n % 10
|
||||
word = "роль" if last == 1 else "роли" if 2 <= last <= 4 else "ролей"
|
||||
return f"{n} {word}"
|
||||
|
||||
|
||||
@dataclass
|
||||
class SystemReadiness:
|
||||
state: str # HEALTHY | LIMITED | DEGRADED | CRITICAL
|
||||
|
|
@ -567,6 +578,12 @@ class UnifiedHealthService:
|
|||
break
|
||||
|
||||
if has_working_fallback:
|
||||
# Роль, обслуживаемая резервом, РАБОТАЕТ — она просто
|
||||
# деградировала. Раньше она не попадала в roles_ready, и
|
||||
# интерфейс писал «Ролей в строю: 0/6», пока пять ролей
|
||||
# исправно отвечали. Это вводит в заблуждение в худшую
|
||||
# сторону: пользователь видит отказ там, где всё работает.
|
||||
roles_ready += 1
|
||||
degraded_roles += 1
|
||||
warnings.append(f"Роль '{rname}' работает через резервный аккаунт (Primary недоступен).")
|
||||
else:
|
||||
|
|
@ -577,11 +594,11 @@ class UnifiedHealthService:
|
|||
if dead_roles > 0:
|
||||
state = READINESS_CRITICAL
|
||||
title_ru = "Критическое состояние"
|
||||
summary_ru = f"Есть {dead_roles} ролей без рабочего маршрута!"
|
||||
summary_ru = f"Без рабочего маршрута: {_plural_roles(dead_roles)}."
|
||||
elif degraded_roles > 0:
|
||||
state = READINESS_DEGRADED
|
||||
title_ru = "Деградация маршрутов"
|
||||
summary_ru = f"{degraded_roles} ролей работают через резерв."
|
||||
summary_ru = f"Через резерв работают: {_plural_roles(degraded_roles)}."
|
||||
elif connected_accounts < total_accounts:
|
||||
state = READINESS_LIMITED
|
||||
title_ru = "Ограниченная готовность"
|
||||
|
|
|
|||
43
tests/test_readiness_counting.py
Normal file
43
tests/test_readiness_counting.py
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
"""Роль на резерве считается работающей.
|
||||
|
||||
Дефект со скриншота владельца: заголовок «Ролей в строю: 0/6», а ниже
|
||||
шесть предупреждений вида «роль работает через резервный аккаунт». Пять
|
||||
ролей исправно отвечали, а интерфейс сообщал, что не работает ни одна.
|
||||
|
||||
roles_ready считал только роли со здоровым ОСНОВНЫМ профилем. Роль,
|
||||
обслуживаемая резервом, попадала в degraded, но не в ready. Это ошибка в
|
||||
худшую сторону: пользователь видит отказ там, где всё работает.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from antigravity_provider.router.unified_health import _plural_roles
|
||||
|
||||
|
||||
def test_role_on_fallback_counts_as_ready():
|
||||
"""Роль, у которой жив резерв, обязана попадать в «в строю»."""
|
||||
import inspect
|
||||
|
||||
from antigravity_provider.router import unified_health
|
||||
|
||||
src = inspect.getsource(unified_health.UnifiedHealthService.get_system_readiness)
|
||||
marker = "if has_working_fallback:"
|
||||
assert marker in src
|
||||
tail = src.split(marker, 1)[1].split("else:", 1)[0]
|
||||
assert "roles_ready += 1" in tail, (
|
||||
"роль на резерве снова не засчитывается как работающая"
|
||||
)
|
||||
assert "degraded_roles += 1" in tail, (
|
||||
"признак деградации потерян — состояние должно оставаться отличимым"
|
||||
)
|
||||
|
||||
|
||||
def test_plural_roles_agrees_with_number():
|
||||
"""«Есть 1 ролей» — так по-русски не пишут."""
|
||||
assert _plural_roles(1) == "1 роль"
|
||||
assert _plural_roles(2) == "2 роли"
|
||||
assert _plural_roles(4) == "4 роли"
|
||||
assert _plural_roles(5) == "5 ролей"
|
||||
assert _plural_roles(11) == "11 ролей"
|
||||
assert _plural_roles(21) == "21 роль"
|
||||
assert _plural_roles(112) == "112 ролей"
|
||||
Loading…
Reference in a new issue