fix: валидация настроек обмена PositiveInt/NonNegativeInt (M-4)
OUTBOX_POLL_SECONDS и ACK_TIMEOUT_SECONDS — PositiveInt, OUTBOX_MAX_REPUBLISH — NonNegativeInt: 0 и отрицательные значения периода и таймаута, отрицательное число повторов отвергаются при старте. Значения по умолчанию прежние. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
parent
3d31c1eac5
commit
7a6a7fb36b
@ -1,5 +1,6 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
|
from pydantic import NonNegativeInt, PositiveInt
|
||||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||||
|
|
||||||
|
|
||||||
@ -68,9 +69,12 @@ class Settings(BaseSettings):
|
|||||||
|
|
||||||
# NATS и outbox/inbox обмена recognition_job
|
# NATS и outbox/inbox обмена recognition_job
|
||||||
NATS_ENABLED: bool = False
|
NATS_ENABLED: bool = False
|
||||||
OUTBOX_POLL_SECONDS: int = 5 # период опроса outbox
|
# 0 и отрицательные значения отвергаются при старте: период 0 — горячий цикл, ack-таймаут 0 — повтор каждый проход
|
||||||
ACK_TIMEOUT_SECONDS: int = 30 # ожидание ack сервиса распознавания до повторной публикации
|
OUTBOX_POLL_SECONDS: PositiveInt = 5 # период опроса outbox
|
||||||
OUTBOX_MAX_REPUBLISH: int = 3 # число повторных публикаций до перевода в dlq
|
ACK_TIMEOUT_SECONDS: PositiveInt = 30 # ожидание ack сервиса распознавания до повторной публикации
|
||||||
|
OUTBOX_MAX_REPUBLISH: NonNegativeInt = (
|
||||||
|
3 # число повторных публикаций до перевода в dlq (0 — сразу dlq без повторов)
|
||||||
|
)
|
||||||
|
|
||||||
model_config = SettingsConfigDict(
|
model_config = SettingsConfigDict(
|
||||||
extra="ignore",
|
extra="ignore",
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import os
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from pydantic import ValidationError
|
||||||
|
|
||||||
from src.core.config import Settings
|
from src.core.config import Settings
|
||||||
|
|
||||||
@ -67,3 +68,40 @@ def test_empty_nats_seed_and_jwt_allowed(clean_env: pytest.MonkeyPatch) -> None:
|
|||||||
assert s.OPENBAO.NATS.NATS_JWT == ""
|
assert s.OPENBAO.NATS.NATS_JWT == ""
|
||||||
assert s.NATS_ENABLED is True
|
assert s.NATS_ENABLED is True
|
||||||
assert s.OPENBAO.SMB.SMB_HOST == ""
|
assert s.OPENBAO.SMB.SMB_HOST == ""
|
||||||
|
|
||||||
|
|
||||||
|
REQUIRED_ENV = {
|
||||||
|
"OPENBAO__DATABASE__DATABASE_URL": "postgresql+asyncpg://u:p@localhost:5432/d",
|
||||||
|
"OPENBAO__MINIO__MINIO_URL": "localhost:9000",
|
||||||
|
"OPENBAO__MINIO__MINIO_ADMIN_LOGIN": "login",
|
||||||
|
"OPENBAO__MINIO__MINIO_ADMIN_PASSWORD": "password",
|
||||||
|
"OPENBAO__MINIO__MINIO_BUCKET": "bucket",
|
||||||
|
"OPENBAO__NATS__NATS_URL": "nats://localhost:4222",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("key", "value"),
|
||||||
|
[
|
||||||
|
("OUTBOX_POLL_SECONDS", "0"),
|
||||||
|
("OUTBOX_POLL_SECONDS", "-1"),
|
||||||
|
("ACK_TIMEOUT_SECONDS", "0"),
|
||||||
|
("ACK_TIMEOUT_SECONDS", "-5"),
|
||||||
|
("OUTBOX_MAX_REPUBLISH", "-1"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_exchange_settings_reject_invalid(clean_env: pytest.MonkeyPatch, key: str, value: str) -> None:
|
||||||
|
"""Период опроса и ack-таймаут — строго положительные, число повторов — неотрицательное (финальное ревью M-4)."""
|
||||||
|
for name, required in REQUIRED_ENV.items():
|
||||||
|
clean_env.setenv(name, required)
|
||||||
|
clean_env.setenv(key, value)
|
||||||
|
with pytest.raises(ValidationError, match=key):
|
||||||
|
Settings(_env_file=None) # type: ignore[call-arg]
|
||||||
|
|
||||||
|
|
||||||
|
def test_zero_republish_allowed(clean_env: pytest.MonkeyPatch) -> None:
|
||||||
|
"""OUTBOX_MAX_REPUBLISH=0 допустим: без повторов, сразу dlq после ack-таймаута."""
|
||||||
|
for name, required in REQUIRED_ENV.items():
|
||||||
|
clean_env.setenv(name, required)
|
||||||
|
clean_env.setenv("OUTBOX_MAX_REPUBLISH", "0")
|
||||||
|
assert Settings(_env_file=None).OUTBOX_MAX_REPUBLISH == 0 # type: ignore[call-arg]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user