Phase 5a: adversarial test — отключение источника

Live-validated сценарий: stop cuframes-pub-back_yard, наблюдение
через ZMQ /health.

Timeline:
  t=0s:   4 active, 0 stale, 0 dead    baseline
  t+2s:   3 active, 1 stale            STALE через 500мс threshold
  t+10s:  3 active, 1 dead              DEAD через 5000мс threshold
                                        FPS = 25.0 СТАБИЛЬНО
                                        ячейка → blackout
  restart pub:
  t+~13s: 4 active, 0 stale, 0 dead    auto-reconnect отработал

Главный threat model подтверждён: отключение источника не валит
композитор, остальные 3 ячейки продолжают работу, RTSP не прерывается.

Полный отчёт в docs/ADVERSARIAL-TEST-PHASE-5a.md.

Phase 5b/5c (multi-source disconnect, mediamtx restart, 24h memory
test, 16-source load test) — отдельные сессии.
This commit is contained in:
2026-06-03 06:24:43 +01:00
parent 636b70b64c
commit 4efaea8268
+57
View File
@@ -0,0 +1,57 @@
# Phase 5a — Adversarial: отключение источника
Дата: 2026-06-03 Хост: R9-88.23 (RTX 5090) Поток: `rtsp://192.168.88.23:554/cfc-grid`
## Сценарий
Композитор `cfc-grid-live` подключён к 4 cuframes-publisher'ам:
parking, back_yard, front_yard, gate_lpr. Layout 2×2 1080p @ 25 fps.
Останавливаем `docker stop cuframes-pub-back_yard` (имитация физического
обесточивания камеры), наблюдаем через ZMQ control plane (`/health`).
## Результат
```
t=0s: {active:4, stale:0, dead:0} (baseline)
t+2s: {active:3, stale:1, dead:0} ← STALE по threshold 500мс
t+10s: {active:3, stale:0, dead:1} ← DEAD по threshold 5000мс
Композитор: 25.0 fps, ячейка → blackout
restart pub:
t+~13s: {active:4, stale:0, dead:0} ← auto-reconnect через exp backoff
```
## Что доказано
1. **Graceful degradation**: отключение источника не валит композитор
и не влияет на остальные 3 ячейки.
2. **Visible blackout** вместо crash (NVENC продолжает кодировать
чёрный квадрат BT.709 — фон background fill).
3. **Health-сигнал** через ZMQ корректно отражает переход состояний
(ACTIVE → STALE → DEAD → ACTIVE при reconnect'е).
4. **Auto-reconnect** через exp backoff (1с → 30с) восстанавливает
соединение когда publisher возвращается. В тесте — ~3с от restart'а
до active state.
5. **FPS не падает** — 25.0 стабильно на всём протяжении эксперимента.
## Threat model coverage
Это покрывает основной adversarial scenario:
> Злоумышленники физически обесточивают камеры/PoE перед проникновением.
> Композитор должен продолжать работать на оставшихся источниках —
> SLA-контракт штрафует за полный простой системы.
Достигнуто: композитор показывает 3/4 видеопотоков + blackout для
отключённой камеры. Запись в RTSP не прерывается. Health-сенсор в MQTT
отдаёт `dead=1` — операторам и автоматике видна потеря (могут
сработать алерты Home Assistant'а через MQTT discovery sensors).
## Что не покрыто (Phase 5b, 5c)
- Сценарий: одновременное отключение нескольких источников (>50%).
- Сценарий: восстановление publisher'а с другим CUDA-контекстом
(после reboot хоста camera-publisher'а).
- Сценарий: mediamtx restart (ffmpeg pipe должен переподключиться).
- Memory leak test: сутки непрерывной работы + monitoring VRAM/RAM.
- Load test: 16 источников 1080p25 на RTX 5090.