144 lines
6.1 KiB
Markdown
144 lines
6.1 KiB
Markdown
|
|
# E2E тесты
|
|||
|
|
|
|||
|
|
Автоматические e2e-тесты проверяют реальную связку `Caddy + Souin + Otter + NutsDB + imgproxy` через Docker Compose.
|
|||
|
|
|
|||
|
|
## Запуск Локально
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
./scripts/test-e2e.sh
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
На хосте нужны только Docker и Docker Compose. Bun устанавливать не нужно: тесты запускаются внутри контейнера `oven/bun:1`.
|
|||
|
|
|
|||
|
|
Тестовый стек не публикует порты на хост, поэтому он не конфликтует с dev-стеком на `8888` и `2019`.
|
|||
|
|
|
|||
|
|
## Что Проверяется
|
|||
|
|
|
|||
|
|
- Caddy собирается с Souin, Otter и NutsDB storage modules.
|
|||
|
|
- Souin не падает обратно на default in-memory storage.
|
|||
|
|
- Первый запрос дает `Cache-Status: Souin; fwd=uri-miss; stored`.
|
|||
|
|
- Повторный запрос отдается из L1 in-memory кеша: `detail=OTTER`.
|
|||
|
|
- После `docker compose restart caddy` кеш сохраняется и читается из L2 disk storage: `detail=NUTS`.
|
|||
|
|
- `PURGE /souin-api/souin/flush` возвращает `204`.
|
|||
|
|
- После purge новые записи в кеш продолжают работать.
|
|||
|
|
- В логах Caddy нет `NUTS-INSERTION-ERROR`.
|
|||
|
|
|
|||
|
|
## Почему Не Используется Внешний Источник
|
|||
|
|
|
|||
|
|
Тесты не ходят в `picsum.photos` или другие внешние сервисы. Вместо этого отдельный `fixture`-сервис внутри Docker network отдает статичную PNG-картинку.
|
|||
|
|
|
|||
|
|
Это делает тесты стабильными:
|
|||
|
|
|
|||
|
|
- нет зависимости от интернета;
|
|||
|
|
- нет случайной смены изображения или `ETag`;
|
|||
|
|
- нет внешних rate limits;
|
|||
|
|
- одинаковое поведение локально и в CI.
|
|||
|
|
|
|||
|
|
## Состав Тестового Стека
|
|||
|
|
|
|||
|
|
Файл: `docker-compose.test.yml`.
|
|||
|
|
|
|||
|
|
Сервисы:
|
|||
|
|
|
|||
|
|
| Сервис | Назначение |
|
|||
|
|
|---|---|
|
|||
|
|
| `fixture` | HTTP-сервис со статичной картинкой `/image.png` |
|
|||
|
|
| `imgproxy` | Обрабатывает изображение из `fixture` |
|
|||
|
|
| `caddy` | Gateway с Souin cache, Otter L1 и NutsDB L2 |
|
|||
|
|
| `tester` | Контейнер `oven/bun:1`, запускает `bun test` |
|
|||
|
|
|
|||
|
|
Тесты обращаются к сервисам по внутренним Docker DNS именам:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
http://caddy:8888
|
|||
|
|
http://caddy:2019
|
|||
|
|
http://fixture:8080/image.png
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Структура Файлов
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
scripts/test-e2e.sh Entry point для локального запуска и CI
|
|||
|
|
docker-compose.test.yml Изолированный Docker Compose стек для тестов
|
|||
|
|
tests/fixture/server.js Fixture HTTP server на Bun
|
|||
|
|
tests/e2e/helpers.js Общие HTTP helpers и assertions
|
|||
|
|
tests/e2e/cache-prime.test.js MISS -> stored, HIT -> OTTER
|
|||
|
|
tests/e2e/cache-persistence.test.js restart caddy -> HIT -> NUTS
|
|||
|
|
tests/e2e/cache-purge.test.js flush -> новые записи продолжают работать
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Как Работает Скрипт
|
|||
|
|
|
|||
|
|
`scripts/test-e2e.sh` выполняет полный lifecycle:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
docker compose -p <project> -f docker-compose.test.yml down -v --remove-orphans
|
|||
|
|
docker compose -p <project> -f docker-compose.test.yml up -d --build caddy imgproxy fixture
|
|||
|
|
docker compose -p <project> -f docker-compose.test.yml run --rm tester bun test tests/e2e/cache-prime.test.js
|
|||
|
|
docker compose -p <project> -f docker-compose.test.yml restart caddy
|
|||
|
|
docker compose -p <project> -f docker-compose.test.yml run --rm tester bun test tests/e2e/cache-persistence.test.js
|
|||
|
|
docker compose -p <project> -f docker-compose.test.yml run --rm tester bun test tests/e2e/cache-purge.test.js
|
|||
|
|
docker compose -p <project> -f docker-compose.test.yml down -v --remove-orphans
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
При ошибке скрипт печатает логи compose-стека и затем удаляет контейнеры и volumes.
|
|||
|
|
|
|||
|
|
## Compose Project Name
|
|||
|
|
|
|||
|
|
По умолчанию используется project name:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
image-gateway-test-local
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
В CI скрипт автоматически учитывает `CI_JOB_ID` или `GITHUB_RUN_ID`, если они есть.
|
|||
|
|
|
|||
|
|
Можно задать имя явно:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
COMPOSE_PROJECT_NAME=image-gateway-test ./scripts/test-e2e.sh
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Это полезно для параллельных запусков или отладки нескольких test stack одновременно.
|
|||
|
|
|
|||
|
|
## Подключение В CI
|
|||
|
|
|
|||
|
|
CI job должен запускать тот же entrypoint:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
./scripts/test-e2e.sh
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Требования к runner:
|
|||
|
|
|
|||
|
|
- Docker;
|
|||
|
|
- Docker Compose plugin;
|
|||
|
|
- доступ к Docker daemon;
|
|||
|
|
- возможность собирать Docker images.
|
|||
|
|
|
|||
|
|
Bun, Node.js и npm на runner не нужны.
|
|||
|
|
|
|||
|
|
## Отладка
|
|||
|
|
|
|||
|
|
Если тест упал, сначала смотрите вывод `scripts/test-e2e.sh`: он печатает логи всех сервисов перед cleanup.
|
|||
|
|
|
|||
|
|
Для ручной отладки можно поднять стек без скрипта:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
docker compose -p image-gateway-debug -f docker-compose.test.yml up -d --build caddy imgproxy fixture
|
|||
|
|
docker compose -p image-gateway-debug -f docker-compose.test.yml run --rm tester bun test tests/e2e/cache-prime.test.js
|
|||
|
|
docker compose -p image-gateway-debug -f docker-compose.test.yml logs caddy
|
|||
|
|
docker compose -p image-gateway-debug -f docker-compose.test.yml down -v --remove-orphans
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Когда Расширять Набор
|
|||
|
|
|
|||
|
|
Текущий набор покрывает критичные регрессии кеша. Следующие полезные сценарии:
|
|||
|
|
|
|||
|
|
- purge по regex;
|
|||
|
|
- разные resize-параметры создают разные cache keys;
|
|||
|
|
- разные source URL не конфликтуют;
|
|||
|
|
- невалидный upstream не кешируется;
|
|||
|
|
- `docker compose down` без `-v` сохраняет volume;
|
|||
|
|
- `docker compose down -v` удаляет кеш.
|