Зафиксированы очередь job, семантика метрик, лимиты бандла и исходящих запросов, а также чеклист продакшена для пула соединений. Co-authored-by: Cursor <cursoragent@cursor.com>
102 lines
20 KiB
Markdown
102 lines
20 KiB
Markdown
# Backend: исходные измерения и воспроизведение проблем
|
||
|
||
Материалы этапа 0 [плана развития](backend-improvement-plan.md). Сборщик ниже выполняет только чтение Docker; он не запускает, не останавливает и не обновляет сервисы, не вызывает refresh/apply и не подключается к production автоматически.
|
||
|
||
## Ресурсный snapshot
|
||
|
||
На машине с Docker daemon и PowerShell выполните из корня репозитория:
|
||
|
||
```powershell
|
||
./scripts/collect-backend-baseline.ps1 -ComposeFile @('deploy/compose/docker-compose.yaml', 'deploy/compose/docker-compose.microvps-full.yaml') -Profile microvps-full -Samples 3 -IntervalSeconds 15
|
||
```
|
||
|
||
Укажите те же Compose-файлы, profile и при необходимости `-ProjectName`, с которыми запущен исследуемый стек. Относительные Compose-пути разрешаются от корня репозитория. Для другого окружения передайте его файлы явно. Скрипт работает с **текущим Docker context**; перед запуском проверьте, что выбран нужный хост.
|
||
|
||
Результат по умолчанию записывается в игнорируемый Git каталог `artifacts/backend-baseline/`; другой путь задаётся `-OutputPath`. Код выхода `0` означает собранные snapshots работающих контейнеров, `2` — неполный результат или недоступную среду. Статусы `partial/unavailable` нельзя считать успешным замером. `configured_services` содержит определения из effective config (включая другие profiles, если их возвращает Compose), а `containers` — фактически найденные контейнеры выбранного проекта. Нельзя суммировать всю конфигурацию как реально запущенный workload.
|
||
|
||
Сохраняются только разрешённые поля: commit, image references/IDs, Docker version, CPU/RAM хоста, настроенные/фактические resource limits, OOM/restart counters и результаты `docker stats`. Raw Compose config разбирается только в памяти. Environment, commands, labels, mount paths, логи и текст ошибок Docker не записываются. Сам отчёт всё равно содержит инфраструктурные метаданные; перед публикацией его нужно проверить.
|
||
|
||
Это точечные значения CPU/memory и накопительные IO counters, а не p95/p99, peak RSS или нагрузочный benchmark. Отдельно зафиксируйте dataset (число модулей/префиксов/узлов), workload, длительность, BGP-сессии, API latency, DB waits, PSI и cgroup events по D00. Для delta IO сравнивайте один и тот же container ID без restart; новое значение counters после пересоздания не означает снижение нагрузки. Объём образа/слоёв, pull/build time и 24h soak пока собираются отдельно.
|
||
|
||
## Регрессионные проверки достоверности live-status
|
||
|
||
```powershell
|
||
go test ./internal/httpapi -run '^TestStage0Repro' -count=1 -v
|
||
```
|
||
|
||
После исправления S01 build tag удалён: эти тесты входят в обычный обязательный набор. Проверяются сохранённый Established при timeout/отсутствующей сессии/collector и ложный healthy у неопрошенного master. Дополнительные проверки в `peers_live_test.go` подтверждают, что успешный опрос постороннего speaker не превращает неизвестное состояние назначенного speaker в `absent` или `ok`. Это локальные регрессии HTTP-слоя; они не заменяют стенд с реальными агентами.
|
||
|
||
## Статус фактической проверки этапа 0
|
||
|
||
### Дополнение: legacy 2.56.2 и durable jobs
|
||
|
||
Обязательная версия удалённых speakers уточнена пользователем: **2.56.2**. Тег `v2.56.2` разрешён в commit `924f111e4871e1d6d47c9916d7da1b9051718f1c`. На Windows собраны исторические node/agent без изменения их исходников. Node прошёл pull/auth/signature против текущего HTTP API, включая отказ на неверном ключе подписи; agent serve прошёл dispatch/ACK/health/protocols с текущим подписанным bundle и fake BIRD. Дополнительный CLI v1.0.0 также прошёл проверку. Это source-built executables, не опубликованные Docker images и не настоящий BIRD/TLS стенд.
|
||
|
||
CI-скрипт `scripts/ci/legacy-node-compatibility.sh` закрепляет commits и проверяет отсутствие skips нужных binary tests. `scripts/tests/mirror-base-images.test.sh` локально прошёл восемь offline сценариев; он не измеряет загрузку или сборку Docker.
|
||
|
||
Тест отчёта jobs подтверждает чтение durable speaker progress новым Registry, собственный результат recovery вместо старого результата родителя и изоляцию tenant. PostgreSQL-проверки lease/generation/restart и fresh seed добавлены в обязательный CI gate; локально без DSN результат остаётся неподтверждённым.
|
||
|
||
После добавления отчёта выполнены `go test ./... -count=1`, `go vet ./...`, `scripts/lint-go.ps1`, OpenAPI lint/codegen и frontend typecheck/lint/build — exit 0. После финального исправления порядка health observations повторены тесты затронутых пакетов и legacy binaries 2.56.2 — exit 0. Astra завершила проверку очереди, fencing, health token, отчёта и fixture pruning без оставшихся блокирующих замечаний. Реальный SQL/race gate не выполнен локально; обязательных CI DB/repository tests теперь 17.
|
||
|
||
### Дополнение: разделение внешних HTTP pools
|
||
|
||
Восстановление прежнего доступа к настроенным private DoH/RIPE явно разрешено пользователем после первоначального отказа автоматической проверки. Политика и границы описаны в [outbound-policy-decision.md](outbound-policy-decision.md). Тест actual bootstrap DOMAINS refresh с локальным DoH прошёл; CDN через paired client сохраняет public-only guard. Три последовательных TLS CDN-запроса используют одно соединение.
|
||
|
||
До начала S02 полный Go test, lint-go и legacy 2.56.2 binary smoke прошли. Astra независимо прогнала RIPE/DoH/CDN/breaker тесты четырёх пакетов. Bounded breaker cache проверен на capacity1024, active/open retention, metric cleanup и 253-символьный hostname с завершающей точкой. Production DNS/network policy и реальные ресурсы хоста не проверялись.
|
||
|
||
### Дополнение: HTTP admission и квоты
|
||
|
||
После добавления общего 8 MiB body preflight, четырёх body slots и tenant/global квот preview/lookup выполнены OpenAPI lint/codegen, frontend typecheck/lint/build, `scripts/lint-go.ps1` и повторный полный `go test ./... -count=1` — exit 0. Legacy node/agent 2.56.2 повторно прошли HTTP/dispatch compatibility tests. Astra независимо проверила auth-first, отмену без преждевременного освобождения слота, Retry-After/CORS, ограниченный CDN error-body и отсутствие изменений legacy GET/SSE.
|
||
|
||
Первый полный прогон выявил нестабильность очереди при равном CreatedAt. Исправлен tie-breaker RequestSequence/ID; детерминированная regression с одинаковым временем прошла 50 повторов у Astra, jobs/store — 20 у Sol. После исправления полный прогон и lint прошли. Реальный PostgreSQL/race и нагрузочные RSS/CPU измерения этим не заменяются.
|
||
|
||
### Дополнение: B05 CSV и bundle limits
|
||
|
||
CSV byte/row/field preflight, отсутствие записи при превышении и отмена прошли focused tests и независимую проверку Astra. Полный `go test ./... -count=1`, Go lint и frontend gates прошли после добавления CSV/bundle limits; после финальных sparse/retry-body исправлений повторены bundle/nodecli/httpclient/pipeline tests и проверка старых node/agent 2.56.2 — exit 0. OpenAPI lint/codegen также успешны.
|
||
|
||
Windows-проверка extraction выполнила hard-link часть, затем получила `SKIP` при создании symlink из-за отсутствия привилегии. Это не подтверждение symlink runtime safety: на Linux тест не допускает такой skip и должен пройти в обычном CI `go test -race`. Конфигурация из миллиона повторяющихся IPv6 route-строк проверяет допустимый размер bundle, а не BIRD или производительность реального миллиона уникальных маршрутов.
|
||
|
||
В локальной среде 26.10.2026 доступны Go 1.26.1 и golangci-lint; Docker/psql и C-компилятор в PATH не найдены, `CGO_ENABLED=0`. Поэтому production-ресурсы, реальный PostgreSQL integration и Go race detector здесь не подтверждены. CI использует проектную версию Go; результаты локального более нового Go не заменяют этот прогон. Конкретные выполненные проверки и оставшиеся gates фиксируются в [статусе плана](backend-improvement-plan.md).
|
||
|
||
| Проверка 26.10.2026 | Результат |
|
||
|---|---|
|
||
| `go test ./... -count=1` | Exit 0; повторный полный прогон после добавления тестов. DB-тесты без DSN пропущены. Для тестовых localhost-серверов потребовался запуск вне sandbox |
|
||
| `go vet ./...` | Exit 0 |
|
||
| `pwsh -NoProfile -File scripts/lint-go.ps1` | Exit 0 после исправления области поиска файлов и замечаний errcheck в новых тестах; выполняет gofmt check, vet и golangci-lint |
|
||
| `pwsh -NoProfile -File scripts/tests/collect-backend-baseline.test.ps1` | Exit 0; offline mock, проверены несколько контейнеров, whitelist без секретов и partial/exit 2 при отсутствии stats |
|
||
| JSON guard PostgreSQL CI | На синтетических событиях: полный pass принят; skip, пропущенный обязательный тест и подмена subtest отклонены. Сам PostgreSQL job локально не запускался |
|
||
| `go test ./internal/httpapi -run '^TestStage0Repro' -count=1 -v` | После S01 включён в основной набор; ожидается exit 0. Первоначально opt-in тесты воспроизводили дефекты, теперь закрепляют исправленное поведение |
|
||
| `go test ./... -race -count=1` | Не выполнен: race требует CGO и отсутствующий C toolchain. Проверка остаётся обязательной в CI |
|
||
| Resource collector без Docker | Сформирован `status=unavailable`, причина `docker-cli-unavailable`; никаких чисел VPS из этого запуска не получено |
|
||
| Повторная проверка Astra | Замечания к guard обязательных DB-тестов и полноте stats исправлены; оставшихся блокирующих замечаний в проверенном diff нет |
|
||
|
||
### Runtime-итерация B01/B02/S01
|
||
|
||
- Полный `go test ./... -count=1` после первой runtime-итерации: exit 0 вне sandbox для localhost-тестов. PostgreSQL без DSN по-прежнему пропускается.
|
||
- После замечаний Astra повторный `go test ./internal/birddeploy ./internal/jobs ./internal/nodedispatch ./internal/httpapi -count=1`: exit 0. Проверены исправления include scanner, отмена dispatch и старый пустой ответ 204.
|
||
- Повторный review Astra не выявил блокирующих замечаний в исправлениях B01/B02/S01. В UI замечания по знаменателям deployment/peer KPI и явному unhealthy исправлены и покрыты регрессиями; повторный review без блокеров.
|
||
- UI: `pnpm --filter @evobgp/web run typecheck`, `lint`, `build` — exit 0; Vitest — 9/9. В lint сохраняется существующий warning `use-file-upload.ts`. Визуальный прогон в браузере не выполнялся.
|
||
- `pwsh -NoProfile -File scripts/lint-go.ps1` после исправлений B01/B02/S01 — exit 0 (gofmt, vet, golangci-lint).
|
||
- B02 Linux-тесты компилируются, но не запускались локально. CI `bird2` дополнен реальным `bird -p`; configure в этом тесте имитируется. Это не проверка работающего BIRD daemon, сетевых сессий или полного восстановления после аварии процесса.
|
||
- Новый apply требует существующий parse-valid `ActiveDir/bird.conf` как LKG. Управляемые include должны быть отдельными строками и ссылаться внутрь `bird.d`; внешние/вложенные/неподдержанные include отклоняются до переключения. Старый удалённый агент продолжает применять прежний bundle своим кодом; ограничение относится к обновлённому локальному apply.
|
||
- B05 transport/proxy и B02 symlink hardening: повторный полный `go test ./... -count=1` — exit 0; scoped tests, `go vet ./...` и `scripts/lint-go.ps1` — exit 0. Astra не нашла блокеров в проверенном diff.
|
||
|
||
### Следующая очередь: B04 migrations / S06 / CDN body
|
||
|
||
- После изменений полный `go test ./... -count=1` — exit 0. После финальных замечаний Astra тесты изменённых пакетов (`db`, `observability`, `repository`, `store`, `pipeline`, `httpapi`) — exit 0; последние lexical-guard регрессии дополнительно проверены `go test ./internal/db -count=1`. DB integration без DSN пропущены и не считаются пройденными.
|
||
- Общий `scripts/lint-go.ps1` — exit 0; OpenAPI lint — exit 0 с прежним предупреждением о неиспользуемой `FirewallRule`; `git diff --check` и shell syntax CI guard — exit 0.
|
||
- CDN: добавлен настоящий TLS HTTP redirect с контролируемым DNS/dial, проверяющий отказ до соединения с private target. Exact-limit/overflow, ingest/preview и gzip tests прошли; данные больше 8 MiB не парсятся частично. Реальный внешний DNS/production при этом не использовался.
|
||
- S06: проверены отсутствие ложных нулей при ошибке БД, сохранение legacy labels и нормализация только нового ряда. Desired/published/applied/live метрики остаются следующей работой.
|
||
- B04: 33 существующих PostgreSQL migration-файла проходят проверку transaction-only policy. Новые DB-тесты используют изолированные схемы; CI guard требует все 23 обязательных DB/repository tests. Повторный review Astra закрыл обходы через комментарии, dollar-identifiers и E-string boundaries. Реальный PostgreSQL, race и Linux BIRD всё ещё требуют соответствующего окружения.
|
||
|
||
CI-запуск для подготовленной изолированной тестовой БД на Linux: задать `EVOBGP_TEST_DATABASE_URL`, затем `bash scripts/ci/postgres-integration.sh`. Использовать только отдельную тестовую БД: тесты применяют миграции и выполняют CRUD/prune. Не указывать production DSN. В Gitea job эта БД создаётся service-контейнером PostgreSQL 16; 23 обязательных DB/repository tests исполняются последовательно с `-race` и проверкой событий pass/skip/fail.
|
||
|
||
|
||
## PostgreSQL runtime: Windows, 26 октября 2026
|
||
|
||
На отдельном временном кластере PostgreSQL **16.15** выполнены все **23 обязательных** DB/repository integration tests из `scripts/ci/postgres-integration.sh`: обе группы PASS, 0 skip, 0 fail. Проверены миграции и код до **000036 включительно**, до начала добавления manifest migration 000037. Сценарии включают competing migration locks/rollback, durable queue/deployment leases, telemetry discovery rollback и snapshot transaction cancellation/concurrency/partial write/потерю backend-соединения.
|
||
|
||
Прогон использовал `go test -count=1 -p 1 -json`: DB-фильтр `^TestPostgresMigration.*Integration$`, repository-фильтр `Integration$`. Все 23 именованных pass проверены по JSON-логам независимо от exit code пакетов. Это Windows-прогон **без `-race`**; обязательный Linux/race CI остаётся отдельным gate.
|
||
|
||
Portable runtime взят из [официального архива EDB](https://www.enterprisedb.com/download-postgresql-binaries), файл `postgresql-16.15-5-windows-x64-binaries.zip`; SHA-256 проверен по vendor `.sha256`: `43bb45f173a6f08cf1d29a97a6d8deb119e8e8093a24c00d2d1001a0ccaa8281`. Кластер слушал только `127.0.0.1` на свободном порту с временным паролем. Служба Windows не создавалась; после тестов `pg_ctl status` подтвердил отсутствие работающего сервера. Локальные JSON-логи сохранены в ignored `artifacts/backend-baseline/pg-test-5c93b7da43dc4c488ca7796a686213c2/`.
|