diff --git a/tests/test_group_avatar.c b/tests/test_group_avatar.c index a45371f1..60a3c098 100644 --- a/tests/test_group_avatar.c +++ b/tests/test_group_avatar.c @@ -127,7 +127,23 @@ int main(void) { etcp_router_set_receive_ready(nodes[1], ETCP_RT_ID_GROUP_AVATAR, hold); image[0] ^= 1; assert(!group_avatar_set(nodes[0], GROUP, image, 4097)); struct group_avatar_record next; assert(!group_avatar_get(nodes[0], GROUP, &next)); - deadline = get_time_tb() + 20000; while (get_time_tb() < deadline) uasync_poll(ua, 2); + // Проверяем остановку доставки и повтор BUSY ACK, затем сразу переходим к restart. + struct ETCP_ROUTER_CONN* sender = etcp_router_conn_get(nodes[0], GROUP, nodes[1]->node_id, ETCP_RT_ID_GROUP_AVATAR); + struct ETCP_ROUTER_CONN* receiver = etcp_router_conn_get(nodes[1], GROUP, nodes[0]->node_id, ETCP_RT_ID_GROUP_AVATAR); + uint64_t hold_started = get_time_tb(), first_busy_ack = 0; + int busy_repeated = 0; + deadline = hold_started + 20000; + while (get_time_tb() < deadline) { + uasync_poll(ua, 2); + if (!receiver->receive_blocked || !sender->peer_receive_blocked) continue; + if (!first_busy_ack) first_busy_ack = sender->last_ack_changed_tb; + else if (sender->last_ack_changed_tb != first_busy_ack) { busy_repeated = 1; break; } + } + if (!busy_repeated) DEBUG_ERROR(DEBUG_CATEGORY_CHAT, "test group avatar: BUSY ACK repeat missing blocked=%u peer_blocked=%u", + receiver->receive_blocked, sender->peer_receive_blocked); + assert(busy_repeated && sender->tx_acked != sender->tx_sent); + DEBUG_INFO(DEBUG_CATEGORY_CHAT, "test group avatar: delivery paused, BUSY ACK repeated elapsed_tb=%llu acked=%u sent=%u", + (unsigned long long)(get_time_tb() - hold_started), sender->tx_acked, sender->tx_sent); assert(!group_avatar_get(nodes[1], GROUP, ©) && copy.version == first.version); etcp_router_conn_restart(nodes[0], GROUP, nodes[1]->node_id, ETCP_RT_ID_GROUP_AVATAR); etcp_router_set_receive_ready(nodes[1], ETCP_RT_ID_GROUP_AVATAR, ga_receive_ready); diff --git a/tests/test_node_conn_direct.c b/tests/test_node_conn_direct.c index a3d38972..3814cc7c 100644 --- a/tests/test_node_conn_direct.c +++ b/tests/test_node_conn_direct.c @@ -45,7 +45,7 @@ #include "../lib/mem.h" #define TIMEOUT_TB 600000 -#define SHORT_TO_TB 50000 +#define SHORT_TO_TB 5000 /* 500мс: проверяем истечение заданного бюджета, без ожидания 5с. */ #define POLL_MS 5 static struct UTUN_INSTANCE *g_a = NULL, *g_b = NULL; @@ -53,6 +53,7 @@ static struct UASYNC *ua = NULL; static volatile int g_result = 0; static int g_phase = 0; static void *g_ttimer = NULL; +static uint64_t g_timeout_started_tb; static char tdir[] = "/tmp/utun_ncd_XXXXXX"; static char ca[256], cb[256]; @@ -303,6 +304,7 @@ static void t8(void* arg) { memset((void*)g_tout, 0, sizeof(g_tout)); g_a->etcp_connect_timeout_tb = SHORT_TO_TB; + g_timeout_started_tb = get_time_tb(); int r = node_conn_direct_open(g_a, fake_id, ncd_cb, (void*)0, &gh[0], NULL); fprintf(stderr, " open(unreachable) → %s\n", r == NCD_NEW ? "NCD_NEW" : "?"); if (r != NCD_NEW) { fail("expected NCD_NEW"); return; } @@ -314,6 +316,14 @@ static void t9(void* arg) { (void)arg; g_phase = 9; if (g_tout[0] == 0) { uasync_set_timeout(ua, POLL_MS, NULL, (timeout_callback_t)t9, "t9"); return; } if (g_up[0] > 0) { fail("up fired, expected only timeout"); return; } + uint64_t elapsed = get_time_tb() - g_timeout_started_tb; + if (g_tout[0] != 1 || elapsed + 10 < SHORT_TO_TB) { + DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "NCD test: invalid timeout calls=%d elapsed_tb=%llu budget_tb=%d", + g_tout[0], (unsigned long long)elapsed, SHORT_TO_TB); + g_result = 2; return; + } + DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "NCD test: one TIMEOUT without UP elapsed_tb=%llu budget_tb=%d", + (unsigned long long)elapsed, SHORT_TO_TB); fprintf(stderr, "\n=== P9: timeout_cb fired, no up ===\n"); fflush(stderr); node_conn_direct_close(gh[0]); gh[0] = NULL; uasync_call_soon(ua, NULL, t_done);