# Нагрузочные тесты IoT Контур: устройство → wss (EMQX) → бридж → SQS `iot-telemetry` → consumer → PG → API. ## Запуск ```bash cd loadtests python3 -m loadtests.run [опции] # или из корня репо: python3 -m loadtests.run [опции] ``` Требования: Python 3.10+, `paho-mqtt` (`pip install paho-mqtt`). Конфигурация через env (дефолты — прод): | Env | Дефолт | |---|---| | `IOT_API` | `https://iot.containerk8s.dev.nubes.ru` | | `IOT_WS` | `wss://exqx.containerk8s.dev.nubes.ru/mqtt` | | `IOT_NS_PREFIX` | `lt` | | `IOT_CLEANUP` | `1` (удалять созданные тестом устройства) | Тест сам регистрирует устройства через API (JWT структурный) в namespace `lt_` и удаляет их после прогона при `IOT_CLEANUP=1`. ## Сценарии | Сценарий | Что проверяет | |---|---| | `baseline` | Равномерная нагрузка: потери/дубли/задержка (p50/p95/p99) доставки в PG. | | `burst` | Всплеск xN: рост очереди и время восстановления (recovery). | | `large-payload` | Payload до ~900KB (лимит EMQX 1MB). | | `reconnect-storm` | Периодические разрывы соединений (эмуляция edge-разрывов ~150с), QoS1. | | `multitenant` | Много namespace: задержка первого сообщения (EnsureTenantDB). | | `acl-violation` | Публикация в чужой топик → EMQX должен рвать сессию. | | `auth-neg` | Неверный пароль → CONNACK 4, неизвестный юзер → CONNACK 5. | | `api-crud` | Нагрузка на CRUD устройств (POST/GET/DELETE). | | `telemetry-query` | Нагрузка на чтение телеметрии. | | `soak` | Длительный прогон с периодическими срезами sent/delivered. | Примеры: ```bash python3 -m loadtests.run baseline --devices 50 --rate 2 --duration 120 --qos 0 python3 -m loadtests.run burst --devices 100 --rate 1 --burst-mult 10 --duration 30 python3 -m loadtests.run reconnect-storm --devices 100 --rate 1 --reconnect-every 30 --duration 300 python3 -m loadtests.run multitenant --tenants 20 --devices-per-tenant 3 python3 -m loadtests.run api-crud --threads 10 --iterations 20 python3 -m loadtests.run telemetry-query --threads 10 --iterations 50 --query-limit 100 python3 -m loadtests.run soak --devices 50 --rate 1 --duration 3600 --slice-sec 300 ``` ## Ограничения - **SQS-лимит 256KB** на сообщение (shared-sqs отклоняет: `InvalidParameterValue message size exceeds the limit`) → payload устройств ≤ ~250KB с учётом envelope. Бридж дропает oversize с логом `payload too large for SQS`. EMQX пропускает до 1MB, но узким местом конвейера является SQS. - API отдаёт максимум **1000 строк** телеметрии на запрос; шлюз платформы рвёт ответы >~15КБ (баг MSS/MTU, тикет Nubes) → верификатор ходит страницами по 50 (`offset`). Большие страницы НЕ использовать. - Задержка = `ts(PG) - sent_at - skew`; skew калибруется первым сообщением (часы тест-машины и PG могут расходиться). - Consumer long-poll до ~20с → после публикаций нужна пауза перед сверкой (встроена в сценарии). ## Критерии успеха (базовые) - `baseline`: loss_rate = 0, duplicates = 0, p99 < 10с при ≤100 msg/s. - `burst`: recovery < 120с после конца пика. - `reconnect-storm`: loss_rate < 0.01 (QoS1), forced_reconnects > 0. - `acl-violation`: foreign_accepted = 0. - `auth-neg`: rc = 4 и rc = 5. - `soak`: delivered растёт монотонно, провалов нет. ## Тесты с отключением сервисов (вручную, нужен kubectl с ВМ) Снаружи отключить SQS/PG нельзя — их блокируют на кластере: 1. **SQS-outage** (обрыв бриджа): заблокировать egress монолита к shared-sqs network policy или `kubectl delete endpoints` — 3 минуты, затем восстановить; метрики: ошибки SendMessage в логах бриджа, время восстановления доставки. (Известная проблема: SendMessage в handler блокирует MQTT-поток — см. HISTORY секция 31, Sonnet-ревью, находка №1.) 2. **PG-outage**: `kubectl -n scale deployment postgresqlk8s --replicas=0` на 5 минут; метрики: глубина SQS (ApproximateNumberOfMessages), дубли после восстановления (visibility timeout 30с — см. находку №2 ревью). Оба теста — ТОЛЬКО на стенде, не на проде. ## Что гонять на проде Умеренно (безопасно): `baseline` (≤100 msg/s), `auth-neg`, `acl-violation`, `api-crud`, `telemetry-query`, `multitenant` (≤20 тенантов). Осторожно (off-peak): `burst` (x10 кратко), `reconnect-storm` (≤100 устройств), `large-payload` (≤5 устройств). Не на проде: SQS-outage, PG-outage, `soak` >1ч с высоким rate.