Files
han-app/archive/infratest

Инфраструктурный тест HAN Chat

Автономный тест запускается непосредственно на ВМ и проверяет managed PostgreSQL и три приватных Selectel S3-бакета в соответствии с контрактами HAN Chat. Для запуска приложение и Docker Compose не требуются.

Тест не создаёт постоянных данных:

  • PostgreSQL DDL/DML выполняются в транзакции и завершаются ROLLBACK;
  • S3-объекты создаются только под уникальным префиксом infratest/<uuid>/;
  • все S3-объекты удаляются в блоке очистки даже при ошибке одной из проверок.

Что проверяется

PostgreSQL

  • подключение пяти сервисных ролей с TLS verify-full;
  • current_user, search_path, наличие своей схемы и отсутствие USAGE на четыре чужие схемы;
  • CREATE TABLE, INSERT, SELECT и фактическое отсутствие таблицы после ROLLBACK;
  • расширение pgcrypto;
  • опционально — ключевые таблицы и Alembic revision после миграций.

Проверяются роли:

  • han_apphan_app;
  • bitrix_local_appbitrix_local;
  • bitrix_sync_userbitrix_sync;
  • message_safety_appmessage_safety;
  • keycloak_userkeycloak.

S3

  • HeadBucket для quarantine, attachments и documents;
  • прямые PutObject, HeadObject, GetObject, ListObjectsV2 с ВМ;
  • presigned PUT и GET с побайтовой проверкой содержимого;
  • проектный переход CopyObject из quarantine в attachments с удалением исходного объекта;
  • запрет анонимного GET;
  • CORS preflight для точного PUBLIC_WEB_URL;
  • отдельный ключ message-safety: чтение/list только quarantine, запрет записи, удаления и доступа к attachments/documents.

Multipart API не проверяется: текущая реализация HAN Chat использует single PUT. Прикладные сценарии авторизации, создания диалога и отправки сообщения также не входят в этот инструмент — это E2E приложения, а не проверка инфраструктуры.

Подготовка на ВМ

Рекомендуется скопировать всю папку в отдельный каталог:

mkdir -p /opt/han-chat/infratest
cd /opt/han-chat/infratest

Установите Python 3.10+ и создайте изолированное окружение:

python3 -m venv .venv
. .venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install -r requirements.txt

Создайте настройки:

cp .env.example .env
chmod 600 .env
nano .env

В .env нужны сервисные пароли PostgreSQL, основной S3 RW-ключ и отдельный quarantine read-only ключ. Административный пароль PostgreSQL не используется. HAN_PG_SSLROOTCERT должен указывать на CA-файл по пути, доступному из процесса на ВМ, а не на контейнерный путь /run/secrets/pg-ca.pem.

Не передавайте секреты аргументами командной строки и не прикладывайте .env к отчётам. Файл исключён через .gitignore.

Запуск

Полная самочищающаяся проверка:

cd /opt/han-chat/infratest
. .venv/bin/activate
python3 infratest.py --mode full

Проверка без DDL и записи в S3:

python3 infratest.py --mode readonly

Другой файл настроек и JSON-отчёт:

python3 infratest.py \
  --env-file /secure/path/infratest.env \
  --mode full \
  --json-report report.json

Скрипт возвращает:

  • 0 — нет проваленных проверок;
  • 1 — одна или несколько инфраструктурных проверок завершились ошибкой;
  • 2 — неверная конфигурация или отсутствуют Python-зависимости.

В консоль и JSON не выводятся пароли, access keys и query-параметры presigned URL.

Запуск до и после миграций

До запуска Alembic оставьте:

INFRATEST_CHECK_MIGRATIONS=false

После успешного deployment/scripts/migrate.sh измените значение на:

INFRATEST_CHECK_MIGRATIONS=true

В этом режиме дополнительно проверяются ключевые таблицы схем han_app, bitrix_local, bitrix_sync и ожидаемая revision 0001_initial для han_app.

Ожидаемая IAM-модель

Основной SELECTEL_S3_ACCESS_KEY должен иметь:

  • RW на quarantine, attachments и documents;
  • ListBucket, GetBucketLocation, PutObject, GetObject, DeleteObject;
  • CopyObject обеспечивается правами чтения источника и записи назначения.

Ключ SELECTEL_S3_QUARANTINE_READ_ACCESS_KEY должен иметь только:

  • ListBucket, GetBucketLocation, GetObject для quarantine;
  • никаких прав на Put/Delete;
  • никаких прав на attachments и documents.

Если IAM-политика ограничивает основной ключ другими object prefixes, разрешите служебный префикс infratest/* либо запускайте только --mode readonly.

CORS

При INFRATEST_CHECK_CORS=true quarantine должен отвечать на preflight по vHosted URL (<bucket>.<s3_domain>). У Selectel CORS не работает на path-style адресации, даже если presigned PUT с сервера проходит.

Требования к правилу CORS на han-chat-quarantine:

  • бакет с включённой Virtual-Hosted адресацией;
  • origin — точное значение PUBLIC_WEB_URL, без wildcard;
  • method — PUT (можно также GET, HEAD, POST);
  • headers — минимум content-type; wildcard x-amz-* в панели Selectel обычно не работает, надёжнее указать * или перечислить заголовки явно.

Чтобы временно исключить CORS из диагностики:

INFRATEST_CHECK_CORS=false

Интерпретация результата

  • PASS — контракт подтверждён реальной операцией;
  • FAIL — контракт нарушен или ресурс недоступен;
  • SKIP — проверка отключена режимом или настройкой.

При FAIL сначала проверьте сетевые ACL ВМ, CA/hostname PostgreSQL, GRANT и search_path, затем IAM/CORS бакетов. После аварийного прерывания процесса можно найти остатки только под префиксом infratest/; удалять другие ключи не требуется.

Локальные unit-тесты

Они не обращаются к PostgreSQL или S3:

python3 -m unittest -v test_infratest.py