Files
mtusi2026lab3/tests

Публичные проверки

Python 3.9+, стандартная библиотека. Сервер уже должен быть запущен; проверки не создают готовое приложение и сами не управляют Docker. make check можно выполнить на исходном skeleton, make test — только после реализации API. Полная OpenAPI-валидация отдельно: make validate после установки requirements-dev.txt в venv.

make check
make test BASE_URL=http://localhost:8080
# без make:
python3 tests/smoke.py --base-url http://localhost:8080

smoke.py выполняет один сквозной сценарий, автоматически выбирая профиль из lab.json: health → три пользователя → вход с lab2 → чат → сообщения → пагинация → ошибки доступа → идемпотентность с lab3 → файл с lab4 → thumbnail с lab5 → logout. Он проверяет JSON по используемому подмножеству схемы, коды/headers, Unicode, SHA-256 оригинала и фактические JPEG-размеры thumbnail. Это публичный минимум, не полный fuzz/security/load suite.

Каждый запуск создаёт уникальных синтетических пользователей, чат и сообщения. Данные автоматически не удаляются: в API курса нет delete. Для чистого повтора используйте отдельный тестовый стенд/volume и осознанный сброс своего окружения. Session tokens хранятся только в памяти процесса и не печатаются/не сохраняются.

Проверка сохранности, lab2+

Скопируйте scripts/restart.example.sh в scripts/restart.sh, реализуйте перезапуск API и всех используемых хранилищ с сохранением volumes и задайте executable bit. Скрипт может опираться на ваш compose.yaml или stack.yaml. Он не должен удалять volumes, повторно seed-ить БД или менять тестовые данные.

chmod +x scripts/restart.sh
make test-persistence ACTION_SCRIPT=scripts/restart.sh

Тест создаёт данные и сессию, запускает указанный файл без shell interpolation, ожидает готовности и проверяет те же данные с прежним токеном. В lab4+ также проверяется исходный файл. Hook может работать до 90 секунд, готовность затем ожидается до 90 секунд. TTL сессии для этого теста — минимум 300 секунд. Успех не доказывает, что hook действительно перезапустил БД: приложите команды/состояния контейнеров до и после.

Проверка отказа, lab3+

Реализуйте scripts/stop-one.sh на основе примера. TARGET_INSTANCE_ID в окружении содержит alias обслужившей тест API-реплики: сопоставьте его своему контейнеру/Swarm task и остановите именно его. Скрипт должен быстро вернуть 0 и оставить эту реплику остановленной; восстановление выполняйте отдельно. Swarm может создать новую task с другим ID — это допустимо.

chmod +x scripts/stop-one.sh
make test-failover ACTION_SCRIPT=scripts/stop-one.sh

Перед отказом тест наблюдает ≥2 API-реплики; 15 секунд отправляет сообщения параллельно выполнению hook, повторяет неопределённый POST с тем же ключом, проверяет восстановление записи за ≤10 секунд, отсутствие остановленной реплики в последних ответах, сохранность подтверждённых сообщений и отсутствие дублей. Ошибки переходного периода учитываются. Затем восстановите реплику и повторите для другой. Скрипт — проверка одного отказа API, не гарантия HA БД/LB/host. Вывод hook скрыт, чтобы не утекли секреты; отлаживайте его отдельно с безопасным выводом.

Нагрузка

python3 tests/load.py --duration 30 --concurrency 4 --output evidence/load.json

Это простой closed-loop генератор POST сообщений; он ограничен производительностью клиента и страдает coordinated omission. Он выдаёт successful RPS, ошибки и p50/p95/p99 только успешных запросов. Во время нагрузки нет прозрачных retry; timeout мог скрыть совершённую запись, поэтому это throughput HTTP-подтверждений, не точный счётчик COMMIT. Изменение размера истории входит в профиль. Для серьёзного исследования используйте k6/Locust/wrk либо свой обоснованный генератор, а не выводите максимальную пропускную способность из одного запуска этого скрипта. Для нагрузки pipeline изображений нужен отдельный сценарий студента.

HTTPS, lab7

make test BASE_URL=https://localhost:8443 CA_FILE=/absolute/path/to/ca.crt
make test-security BASE_URL=https://localhost:8443 CA_FILE=/absolute/path/to/ca.crt

Все скрипты принимают --ca-file/CA_FILE и проверяют серверный сертификат и hostname. --insecure отсутствует. TLS-тест сначала проверяет рабочее доверенное соединение, затем намеренно пустой trust store и именно ошибку проверки сертификата; network timeout не засчитывается как правильный отказ. Внутреннее mTLS, identity/authorization, OpenBao policy и hardening проверяют отдельные тесты студента по trust matrix. Клиентский сертификат внешнему учебному REST-клиенту не требуется: mTLS находится на внутренних связях.

Что ещё остаётся доказать

Smoke не доказывает persistence, число реальных контейнеров, durability брокера, outbox, отсутствие утечек/уязвимостей, полноту telemetry или выполнение уровня 4/5. Конкурентные/нагрузочные/негативные проверки своего решения добавляйте отдельно. Список защиты текущей лабы находится в README.md. Проверки рассчитаны на localhost-стенд, не на production.