Browse Source

Record validated stream bench runs and explicit RPC error diagnostics

master
evgeny 21 hours ago
parent
commit
b8f8818eef
  1. 22
      tests/stream_netns/TESTED.md
  2. 3
      tests/stream_netns/node.c

22
tests/stream_netns/TESTED.md

@ -0,0 +1,22 @@
# Проверки 2026-10-11
Стенд: 16 процессов uTun, 10 NAT-клиентов, 3 страны. Основной network namespace не изменился во всех перечисленных запусках.
| Сценарий | Команда из корня репозитория | Результат |
| --- | --- | --- |
| Публичный UDP-источник, длинный прогон и перегрузка | `python3 tests/stream_netns/run.py --duration 120 --rate 2000000 --faults --output /tmp/stream-netns-final-01` | PASS: 5996 пачек, 3 оборота timestamp, вытеснение из кольца, WAN recovery, unsubscribe, END |
| Источник за строгим NAT, только TCP | `python3 tests/stream_netns/run.py --publisher n05 --tcp-only --duration 20 --output /tmp/stream-netns-tcp-only-fixed-01` | PASS: 608 пачек, END у всех 15 получателей; после исправления раннего END |
| Источник за строгим NAT, чистые mappings/conntrack, UDP+TCP | `python3 tests/stream_netns/run.py --publisher n05 --tcp --duration 75 --rate 2000000 --faults --fault-duration 15 --output /tmp/stream-netns-clean-nat-fixed-01` | PASS: 4172 пачки, 2 оборота timestamp, 946 вытесненных пачек у источника; после обоих исправлений |
В последнем запуске median LAN RTT: A=2,64 мс, B=2,72 мс, C=2,54 мс; WAN A–B=51,79 мс, A–C=100,85 мс, B–C=150,31 мс. Все 10 NAT-профилей прошли отдельную проверку. После калибровки создана новая сеть без ее conntrack/mappings.
У источника в последнем запуске сохранено 33 550 400 байт подписанных блоков при capacity 33 554 300 байт (в пределах 32 MiB). Все оставшиеся после unsubscribe 13 получателей дошли до cursor=4172 и получили подписанный END. Ошибок checksum/порядка/повторной DATA нет. GAP и увеличенные задержки при перегрузке отражены в `summary.csv` и `samples.jsonl`; PASS не означает доставку без пропусков.
Обнаружены и исправлены два дефекта:
1. END первого поставщика выключал оптимизатор до дочитывания неполной FEC-пачки. Проверка до исправления: `/tmp/stream-netns-early-end-before-02.log`; после: `/tmp/stream-netns-early-end-after.log`.
2. Restart через отстающего поставщика повторно выдавал DATA той же эпохи. Прогон `/tmp/stream-netns-clean-nat-01` зафиксировал seq=2864 при ожидаемом 2865 с верным checksum. Исправление сохраняет уже выданный cursor и отложенный GAP; регрессии: `/tmp/stream-netns-restart-before.log` и `/tmp/stream-netns-restart-after-02.log`.
После последнего исправления `make -C tests check -j4`: **144 passed, 0 failed, 0 skipped** (`/tmp/stream-netns-final-unit-check.log`). `test_stream_service` включает ранний END, старый bootstrap после restart, два restart до GAP и проверку отсутствия оставшихся отслеживаемых аллокаций. Пять проверок изоляции `test_isolation.py` прошли; C-агент проверен с `-Wall -Wextra -Wformat=2` без предупреждений.
Файлы `/tmp` — результаты конкретных запусков; при очистке системы они могут быть удалены. Команды выше позволяют воспроизвести сценарии с новым каталогом `--output`; распределение потерь и расписание процессов могут менять количество GAP и задержки.

3
tests/stream_netns/node.c

@ -63,6 +63,7 @@ static void json_string(const char *value) {
} }
static void reply(uint64_t id, int result) { static void reply(uint64_t id, int result) {
if (result < 0) DEBUG_WARN(DEBUG_CATEGORY_STREAM, "lab: RPC failed id=%" PRIu64 " rc=%d", id, result);
printf("{\"id\":%" PRIu64 ",\"rc\":%d}\n", id, result); printf("{\"id\":%" PRIu64 ",\"rc\":%d}\n", id, result);
} }
@ -236,6 +237,7 @@ static void statistics(struct lab *lab, uint64_t id, int loads) {
static void invite_ready(void *arg, int result, const char *link) { static void invite_ready(void *arg, int result, const char *link) {
struct lab *lab = arg; struct lab *lab = arg;
lab->invite = NULL; lab->invite = NULL;
if (result) DEBUG_WARN(DEBUG_CATEGORY_STREAM, "lab: invite failed id=%" PRIu64 " rc=%d", lab->invite_id, result);
printf("{\"id\":%" PRIu64 ",\"rc\":%d,\"link\":", lab->invite_id, result); printf("{\"id\":%" PRIu64 ",\"rc\":%d,\"link\":", lab->invite_id, result);
json_string(link ? link : ""); printf("}\n"); json_string(link ? link : ""); printf("}\n");
} }
@ -256,6 +258,7 @@ static void command(struct lab *lab, const char *json) {
struct TOPO_GROUP *group = (struct TOPO_GROUP *)e; struct TOPO_GROUP *group = (struct TOPO_GROUP *)e;
if (group->group_type == TOPO_GROUP_TYPE_CHAT) { lab->group = group->group_id; break; } if (group->group_type == TOPO_GROUP_TYPE_CHAT) { lab->group = group->group_id; break; }
} }
if (!lab->group) DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "lab: CHAT group creation failed id=%" PRIu64, id);
printf("{\"id\":%" PRIu64 ",\"rc\":%d,\"group\":\"%" PRIu64 "\"}\n", id, lab->group ? 0 : -1, lab->group); return; printf("{\"id\":%" PRIu64 ",\"rc\":%d,\"group\":\"%" PRIu64 "\"}\n", id, lab->group ? 0 : -1, lab->group); return;
} }
if (!strcmp(operation, "invite")) { if (!strcmp(operation, "invite")) {

Loading…
Cancel
Save