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