Инфраструктурный тест 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_app→han_app;bitrix_local_app→bitrix_local;bitrix_sync_user→bitrix_sync;message_safety_app→message_safety;keycloak_user→keycloak.
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; wildcardx-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