From 271f1afdb33a92d38879b81f37d80c5af665a2e7 Mon Sep 17 00:00:00 2001 From: Dmitry Dementev Date: Thu, 23 Jul 2026 18:41:09 +0300 Subject: [PATCH] =?UTF-8?q?test(generator):=20=D0=B2=D1=8B=D1=87=D0=B8?= =?UTF-8?q?=D1=89=D0=B5=D0=BD=D1=8B=20=D0=BF=D1=80=D0=BE=D0=B7=D0=B0=D0=B8?= =?UTF-8?q?=D1=87=D0=B5=D1=81=D0=BA=D0=B8=D0=B5=20=D1=82=D0=B5=D1=81=D1=82?= =?UTF-8?q?=D1=8B=20=D0=B8=D0=B7=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0?= =?UTF-8?q?=D0=BA=D1=82=D0=B0=20DAG?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Тесты на дословные фразы документов и комментариев удалены: прозу сторожит ревью, а не pytest. Оставлены структурные инварианты (порядок задач, монтирования, версии, живые перекрёстные ссылки). В шапке файла — критерий «инвариант должен переживать честную переписку текста». Co-Authored-By: Claude Fable 5 --- generator/tests/test_world_dags_contract.py | 38 ++++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/generator/tests/test_world_dags_contract.py b/generator/tests/test_world_dags_contract.py index 7be7f3b..84eb8ba 100644 --- a/generator/tests/test_world_dags_contract.py +++ b/generator/tests/test_world_dags_contract.py @@ -1,4 +1,16 @@ -"""Контракты DAG world_init и world_next_day без запуска Airflow.""" +"""Контракты DAG world_init и world_next_day без запуска Airflow. + +Что здесь контракт. Проверяем только структурные и поведенческие инварианты +стенда: идентификаторы DAG и задач, порядок задач, пути монтирования, синхронность +версий, живые перекрёстные ссылки между документами и реальные идентификаторы +(имена дашбордов, профилей, make-целей). Критерий: инвариант должен переживать +честную переписку текста — краснеть, только когда ломается само поведение или +структура, а не формулировка. + +Чего сюда не добавлять: дословные цитаты прозы из документов и комментариев +(«в README есть слово X», «в комментарии написано Y»). Прозу сторожит ревью, а не +pytest — такой тест зелёный до первой честной переписки и краснеет без дефекта. +""" import ast from pathlib import Path @@ -142,7 +154,6 @@ def test_world_dags_precheck_etl_dag_not_paused_before_waiting(): assert "session.query(DagModel)" in shared_tasks assert "DagModel.dag_id == dag_id" in shared_tasks assert "target_dag_trigger_error" in shared_tasks - assert "Airflow 2.10.5" in shared_tasks assert "fail_when_dag_is_paused" in shared_tasks assert 'return "check_etl_not_paused_before_backfill"' in text assert 'return "check_etl_not_paused_before_import"' in text @@ -175,22 +186,14 @@ def test_readme_quick_start_creates_schema_via_ddl_init_before_world_init(): """Быстрый старт: терминал — только make up, схему создаёт ddl_init до world_init.""" text = (REPO_ROOT / "README.md").read_text(encoding="utf-8") - assert "uv" in text - assert "Docker" in text - assert "docker compose" in text + # Ручного шага создания схемы в быстром старте быть не должно — её создаёт + # DAG ddl_init. Проверяем этот структурный факт и порядок ddl_init→world_init, + # а не наличие слов «uv»/«Docker» в тексте. assert "make ddl" not in text quick_start = text.split("## Быстрый старт", maxsplit=1)[1] assert quick_start.index("ddl_init") < quick_start.index("world_init") -def test_course_readme_lists_uv_before_first_command(): - """Курс называет uv до первой команды.""" - text = (REPO_ROOT / "docs" / "course" / "README.md").read_text(encoding="utf-8") - - assert "uv" in text - assert text.index("uv") < text.index("make clean") - - def test_course_canonical_setup_unpauses_dags_before_world_init(): """Канонический блок называет три DAG, снятие паузы и порядок etl→world_init.""" # Прозаические формулировки не проверяем — их сторожит ревью, не pytest. @@ -229,15 +232,16 @@ def test_monitoring_lesson_links_to_canonical_reset(): assert "../README.md#подготовка-и-канонический-сброс" in text -def test_startup_history_runbook_warns_about_daily_wave_idle_gap(): - """Runbook предупреждает о дыре модельного времени при простое daily-wave.""" +def test_startup_history_runbook_references_daily_wave_reset_and_import(): + """Runbook ссылается на реальные идентификаторы восстановления стенда.""" + # Не пиним формулировку предупреждения о дыре модельного времени — её + # сторожит ревью. Держим ссылки на реальные идентификаторы: профиль, + # make-цель сброса и якорь импорта. text = (REPO_ROOT / "docs" / "runbooks" / "startup-history.md").read_text( encoding="utf-8" ) assert "daily-wave" in text - assert "прост" in text - assert "дыр" in text assert "make generator-reset" in text assert "startup-history-import" in text