Files
clickstream-data-platform/docs/architecture/testing.md
T
ddadminandClaude Opus 5 bbbe17cfb0 refactor(smoke): цели проверки по назначению — смоук, ClickHouse, службы
- Зачем:
  - смоук перестал быть быстрым: 42 секунды из 48 съедали шесть проверок,
    которые ждут службу — запуск DAG, вход в Superset, Kafka с машины.
  - имена целей врали: смоуком звались и глубокая проверка кластера, и
    интеграционные проверки; префикс достался им от общего происхождения.
  - нигде не было записано, зачем в репозитории каждая цель и куда класть
    новую проверку, — без записи скрипт дорастёт снова.
- Что:
  - ось деления — кого спрашивают, а не сколько стоит: make smoke (стенд
    собран), make check-clickhouse (спрашивают у ClickHouse), новая
    make check-services (службы работают).
  - шесть тяжёлых проверок переехали в scripts/stand-services.sh; общее —
    счёт, обращение к Compose, зависимости машины и check_containers_survived
    — вынесено в scripts/stand-common.sh, копипасты нет.
  - smoke-cluster переименована в check-clickhouse; имя файла скрипта не
    тронуто (в него встраивается проверка договора со схемой), расхождение
    названо в карте.
  - смоук и check-services печатают своё время в строке ИТОГ; порога по
    времени нет — по доводу ADR 0004.
  - docs/architecture/testing.md: карта всех семи целей, правило быстрого
    смоука словами, лесенка по частоте и правило про краснеющую проверку,
    переехавшее из README; указатель из AGENTS.md.
  - README: описания целей сокращены, карта не дублируется; быстрый старт
    показывает работающий стенд, а не только собранный.
  - планка приёмки этапа в спеке названа поимённо: три цели вместо
    «smoke-проверки».
- Проверка:
  - make config-test, make smoke (19 проверок, 6 с), make check-clickhouse
    (8 проверок, 7 с), make check-services (7 проверок, 44 с) — зелёные.
  - 19 + 7 = 25 разных проверок, как и до деления: check_containers_survived
    считается дважды намеренно.
  - краснеют обе разделённые цели: со снятым prometheus смоук дал три ошибки,
    с подменённым UUID подключения Superset покраснел check-services.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 14:34:02 +03:00

12 KiB
Raw Blame History

Проверки: карта целей

Документ отвечает на два вопроса. Первый: что именно утверждает каждая цель make и сколько стоит её прогон. Второй, ради которого документ и заведён: куда положить новую проверку — так, чтобы это решалось по карте, а не чтением скриптов.

Зона ответственности у документа одна — проверки. Что именно они стерегут, описано в других местах: устройство хранилища — в storage.md, замысел стенда — в спеке «Боевой реализм стенда (v2)».

Ось: кого спрашивают

Цели различаются не ценой, а тем, к кому обращён вопрос. ClickHouse отвечает сам и за миллисекунды. Airflow отвечает через такт планировщика. Superset — через сессию и обход метаданных. Быстрота выходит следствием этого различия, а не критерием деления.

Совпадение цены и назначения здесь побочное, и это видно по дырам, которые каждая цель оставляет соседке. make smoke не заметит перепутанных местами макросов shard: обе ноды здоровы и порты отвечают. make check-clickhouse не заметит потерянного подключения Superset: он про ClickHouse и только.

Отсюда правило для новой проверки: спроси, кого она спрашивает. Договор со схемой событий — вопрос к ClickHouse, значит дом ему в check-clickhouse, даже если по цене он подошёл бы смоуку. Счётчики против манифеста — тоже вопрос к ClickHouse: строки в ods.event считает сам сервер и отвечает сразу.

Карта целей

Стенд нужен трём целям из семи. Цена — замер 6 августа 2026 года, см. «Что проверено».

Цель Что утверждает Стенд Цена
make lint Код генератора отформатирован и проходит ruff не нужен 0,4 с
make typecheck Типы генератора сходятся (ty) не нужен 0,5 с
make test Генератор делает то, что обещает; схема события остаётся объявленным контрактом, а собранное из неё описание выгрузки — свежим не нужен 40 с
make config-test Compose разбирается, Bash и Python синтаксически целы, в diff нет пробельных ошибок. О работоспособности не говорит ничего не нужен 1 с
make smoke Стенд собран: службы живы, порты отвечают, подключения настроены друг на друга. Вширь и по касательной к каждой службе. Единственная цель, которая здесь правда смоук нужен 6 с
make check-clickhouse Всё, что спрашивают у ClickHouse и он отвечает сам: макросы, шарды, реплики, путь в keeper, ключ шардирования, очередь распределённых DDL нужен 7 с
make check-services Службы работают: DAG запускается и доходит, топик создаётся и удаляется, Superset логинится и ходит в базу нужен 44 с

Правило: смоук обязан оставаться быстрым

make smoke — быстрая проверка для регулярного прогона: её гоняют не задумываясь, и потому она обязана укладываться в секунды. Тяжёлые проверки в неё включать не следует: тяжёлая — та, из-за которой смоук перестаёт быть быстрым. Поодиночке это единицы и десятки секунд, вместе — минуты. Такие проверки живут в make check-services.

На практике дорого обходится не работа, а ожидание службы: такт планировщика Airflow, сессия Superset. make check-clickhouse создаёт таблицы, вставляет строки и гоняет распределённые DDL — и укладывается в семь секунд, потому что ClickHouse отвечает сразу.

Первый абзац — правило, второй — наблюдение, по которому тяжёлую проверку узнают заранее, не замеряя.

Какую проверку когда запускать

Деление целей ценно ровно до тех пор, пока оно не превратилось в «гонять всегда всё».

Когда Что гонять
Правка в работе make config-test и make smoke
PR или задача плюс цели, которых правка касалась: DAG-и, Superset или Kafka — check-services; DDL, кластер или данные — check-clickhouse
Приёмка этапа make up с нуля и все три цели на стенде

Правки генератора добавляют к этому make lint, make typecheck и make test: стенд им не нужен, а make test из них самая дорогая.

Порогов по времени здесь нет

Цена в таблице — замеренное число с датой замера, а не назначенный порог. Автоматической проверки времени в репозитории нет и заводить её не следует. Число, вписанное в проверку, становится законом, которого никто не выбирал: ADR 0004 разбирает ровно этот случай — оценка из спеки попала жёстким порогом в make smoke, make smoke стал критерием приёмки каждого этапа, и дальше решения сверялись уже с порогом, а не с исходным доводом. Спека генератора формулирует ту же позицию прямо: «наблюдаемость без порогов».

Смотрит на время человек. make smoke и make check-services печатают его сами — последней строкой ИТОГ: пройдено N, ошибок M, время T с. Замер при приёмке делается руками и называется в теле PR.

Проверка, которая не умеет краснеть, бесполезна

Правило, которое стоит держать в голове, правя любую проверку. Проверка, никогда не видевшая своей поломки, доказывает только то, что она умеет печатать «ЗЕЛЁНО». Убедиться дешевле всего руками: сломайте то, что она стережёт — остановите prometheus, удалите служебную таблицу пробника на второй ноде, — и посмотрите, покраснеет ли прогон и назовёт ли виновника. Не покраснел — проверка не работает, и чинить надо её, а не стенд.

Устройство скриптов

Цель Скрипт
make config-test scripts/config-test.sh
make smoke scripts/stand-smoke.sh
make check-services scripts/stand-services.sh
make check-clickhouse scripts/clickhouse-smoke.sh

Имя clickhouse-smoke.sh осталось от прежнего имени цели — smoke-cluster. Файл переименуют при следующем касании: сейчас в него встраивается проверка договора со схемой, и переименование устроило бы конфликт на ровном месте.

Общее у смоука и check-services — счёт проверок, обращение к Compose и две проверки — вынесено в scripts/stand-common.sh; сам он не запускается. Оттуда же приходят два решения, которые видно по счёту прогонов:

  • check_containers_survived стоит в конце обеих целей. Убитый за память контейнер Docker поднимает сам, и проверка здоровья об этом промолчит (ADR 0004). Стенд нагружает check-services, а увидеть последствия нужно и тому, кто гонял один смоук. Это единственная проверка, которая считается дважды: 19 у смоука плюс 7 у check-services — это 25 разных проверок.
  • Зависимости машины считает только смоук. «На машине есть Docker, curl и jq» — вопрос к машине, а не к службам, и на оси он стоит рядом с «стенд собран». Для check-services это условие запуска: без них он не начнёт работу и громко скажет об этом, но ЗЕЛЁНО за это не печатает.

Вход в Airflow check-services выполняет заново — общих переменных у двух скриптов нет. Отдельной проверкой этот вход тоже не считается: то же самое утверждает смоук.

Что проверено

Замеры 6 августа 2026 года, стенд поднят заранее; время make up в цену целей не входит. Время взято по time и совпадает с тем, что цель печатает сама. Оно плавает от прогона к прогону: смоук дал 5 и 6 секунд, check-services — 43 и 44. В таблице стоит большее из замеренных.

До деления scripts/stand-smoke.sh шёл 48 секунд на 25 проверок, из них 42 секунды съедали шесть: Kafka с машины, два запуска пробников Airflow и три проверки Superset. После деления те же 25 проверок разошлись по двум целям: 19 в смоуке и 6 в check-services. Содержание ни одной из них не менялось.

Что обе разделённые цели умеют краснеть, проверено руками в тот же день: со снятым prometheus смоук дал три ошибки и ненулевой код возврата; с подменённым ожидаемым UUID подключения Superset так же покраснел check-services. Обе краснеют и когда на машине не хватает команды из списка зависимостей.

Семантика счётчиков Docker OOMKilled и RestartCount, на которой держится check_containers_survived, снята отдельными контейнерами и записана в ADR 0004, раздел «Что проверено».