fix(generator): усилены проверки startup-history

- Зачем:
  - коммит-гейт не запускал корневые контрактные тесты, а часть подтверждённых обходов могла снова смешать разные миры генератора.
- Что:
  - добавлены цели make test, make lint и contract-test с тихим pytest-выводом через Docker.
  - закрыты обходы через generator-reset, неизвестную версию state и fail-open проверку DM-витрин.
  - усилены поведенческие контракты CHECK_LIVE_SEAM, профиля manifest и pause-check etl_pipeline; обновлены документы и issue 19.
- Проверка:
  - make test; make lint; git diff --check.
This commit is contained in:
2026-07-05 22:46:53 +03:00
parent 0faa5cc219
commit 9b0b063fed
18 changed files with 346 additions and 59 deletions
+27 -7
View File
@@ -432,6 +432,22 @@ class TestGeneratorStateValidation:
with pytest.raises(UnsupportedStateVersionError, match="2.0.*3.0"):
GeneratorState.from_dict(data)
def test_from_dict_rejects_future_state_version_loudly(self):
"""Любая неизвестная версия state требует решения оператора."""
data = _make_valid_state_data()
data["version"] = "4.0"
with pytest.raises(UnsupportedStateVersionError, match="4.0.*3.0"):
GeneratorState.from_dict(data)
def test_from_dict_safe_does_not_hide_old_state_version(self):
"""Безопасная загрузка не превращает старый state в тихий fresh-start."""
data = _make_valid_state_data()
data["version"] = "2.0"
with pytest.raises(UnsupportedStateVersionError, match="2.0.*3.0"):
GeneratorState.from_dict_safe(data)
class TestKafkaStateManager:
"""Тесты менеджера состояния."""
@@ -536,10 +552,14 @@ class TestKafkaStateManager:
mock_producer_class = MagicMock()
mock_import.return_value = (mock_producer_class, None)
# Мокаем consumer с невалидным сообщением
# Мокаем consumer с невалидным сообщением текущей версии.
mock_message = MagicMock()
mock_message.key = b"default"
mock_message.value = {"tick": 42, "rng_state": "invalid"}
mock_message.value = {
"tick": 42,
"rng_state": "invalid",
"version": "3.0",
}
mock_consumer = MagicMock()
mock_consumer.__iter__ = MagicMock(return_value=iter([mock_message]))
@@ -749,8 +769,8 @@ class TestKafkaStateManager:
assert result is None
assert "Invalid state" in caplog.text
def test_load_version_1_state_returns_none_with_warning(self, caplog):
"""Старое state v1 не восстанавливается и даёт чистый старт."""
def test_load_version_1_state_fails_loudly(self, caplog):
"""Старое state v1 не скрывается за чистым стартом."""
with patch("generator._import_kafka") as mock_import, \
patch("kafka.KafkaConsumer") as mock_consumer_class:
@@ -774,10 +794,10 @@ class TestKafkaStateManager:
mock_consumer_class.return_value = mock_consumer
manager = KafkaStateManager("kafka:29092")
with caplog.at_level(logging.WARNING, logger="generator"):
result = manager.load()
with caplog.at_level(logging.ERROR, logger="generator"):
with pytest.raises(UnsupportedStateVersionError, match="1.0.*3.0"):
manager.load()
assert result is None
assert "version" in caplog.text
def test_load_ignores_wrong_key(self):