Приведение документации к фактическому поведению после ревью PR #53 (раунд 2):
точка входа для CI без make (контракт 0/1/3/4), приоритет AWG_NS_EXEC_MODE над
make-алиасом, сборка без сети (DEV_SKIP_BUILD=1).
Refs #21
Refs #56
GNU make отдаёт 2 на любой упавший рецепт, поэтому контракт 0/1/3/4 через
`make test-netns-ci` до пайплайна #17 не доходит. ci.sh запускает тот же
контейнер (docker compose -f deploy/docker-compose.test.yml run --rm -T netns)
и возвращает его код как есть. Дополнительно: AWG_NS_PRIVILEGED=0 — прогон без
--privileged (проверка ветки «код 3»), AWG_DASH_TEST_ARTIFACTS — каталог отчёта.
Refs #21
Refs #56
Флак: ns_exists мог вернуть false до удаления, и namespace оставался жить.
Теперь `ip netns delete` вызывается всегда, результат проверяется до 5 раз.
Стабильность в контейнере: 5/5 прогонов rc=0 (было 4/5).
Refs #21, Refs #56
В контейнере `ip netns delete` иногда возвращает успех, но namespace остаётся
в `ip netns list` — из-за этого run.sh отдавал код 4 на зелёных тестах (флак
1 из 3). Теперь удаление повторяется до 5 раз с проверкой ns_exists.
Refs #21, Refs #56
- topology.sh: ns_exec для всех ip -n <ns> и ip netns exec, коды 0/1/3/4.
- netns_common.py: ns_exec_mode()/ns_exec_direct(), addrs/links/link_is_up через ns_sh.
- docker-compose.test.yml: проброс AWG_NS_EXEC_MODE в netns-сервис.
- tests/netns/README.md: режимы входа в netns, коды возврата, новый pitfall.
Refs #21, Refs #15, Refs #56
- lib.sh: ns_exec()/ns_prefix() с автоопределением режима (AWG_NS_EXEC_MODE),
stand_fail() для кода 4; cleanup в run.sh больше не оставляет мок и sink.
- run.sh/topology.sh: коды возврата нормализованы к 0/1/3/4 (255 от iproute2 -> 4).
Refs #21, Refs #15, Refs #56
- tests/deploy/test_compose_manifests.py — 7 тестов на compose-инварианты
(без Docker, только PyYAML) — готовы к включению в CI (#17);
- Makefile: dev-up/dev-up-stub/dev-down/dev-logs/dev-verify/dev-verify-stub/
dev-reset/test-netns/test-netns-keep/test-netns-ci/test-manifests/lint-shell,
переменные HOST_DIR, DASH_PORT, NETNS_ARGS; dev-up без docker падает с внятным
сообщением, а не трейсбеком;
- deploy/README.md — таблица артефактов и быстрые команды стенда.
Refs #21
Refs #15
- verify-dev-stand.sh (`make dev-verify`): AC-1 (health 200, различает
api=real/stub), AC-2 (маркеры в /config и /data до и после restart и
--force-recreate, включая проверку на хосте), проверка монтирований и
health контейнера, JSON-отчёт; коды 0/1/2/3 — ok/regression/blocked-#31/
blocked-env;
- tests/deploy/validate_compose.py — проверки без Docker: контейнерный порт
8080, тома /config и /data, healthcheck /api/v1/health, NET_ADMIN и
/dev/net/tun, ip_forward, лимит логов, privileged netns-раннер и DEV-ONLY
заглушка. Флаг --require-dockerfile для интеграционного дерева.
Refs #21
Refs #15
- test_netns_stand.py — 8 тестов: топология и линки, policy routing по fwmark,
правила меток и kill-switch, готовность мока и детектора, доставка handshake
из LAN и из шлюза с ростом счётчика метки, имитация недоступности провайдера
(mode=drop), положительный контроль утечки и блокировка при kill-switch.
Тесты пропускаются вне run.sh, чтобы не падать при случайном pytest-прогоне;
- README.md харнесса — схема топологии, состав файлов, таблица тестов,
переменные окружения и pitfalls (root/CAP_NET_ADMIN, rp_filter, отсутствие
nft и ping в alpine-образе).
Refs #21
Refs #15
- netns_common.py — обёртки над ip/nft/iptables: проверка netns и линков,
счётчики правил меток и kill-switch (nft -j и iptables -v -x), чтение
JSONL-логов мока и детектора, отправка трафика через probe.py;
- run_tests.py — прогон unittest с JSON-отчётом (pytest не нужен: работает
и на хосте, и в alpine-образе);
- README.md — схема топологии, таблица тестов, переменные окружения и pitfalls
(root/CAP_NET_ADMIN, rp_filter, отсутствие nft и ping в образе).
Refs #21
Refs #15
Основы харнесса для тестов без реального VPN-провайдера:
- lib.sh — конфигурация стенда (netns, адреса, fwmark/таблицы) и правила
netfilter с поддержкой nft и iptables (в alpine-образе приложения nft нет);
- topology.sh — up/down/status/killswitch: veth-пары client<->gw<->uplink,
ip_forward, ip rule fwmark 51820 -> table 51820, метки OUTPUT/FORWARD,
DROP kill-switch для прямого выхода в «публичную» сеть;
- run.sh — preflight, запуск мока и детектора утечки в netns uplink, прогон
тестов, снос стенда с проверкой отсутствия остатков.
Refs #21
Refs #15