From f5d67d52402b41f3ea221bb7501a47b03a140d6d Mon Sep 17 00:00:00 2001 From: evgeny Date: Fri, 23 Oct 2026 14:19:24 +0200 Subject: [PATCH] Test link deletion from INIT and keepalive callbacks --- tests/test_etcp_init_liveness.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/test_etcp_init_liveness.c b/tests/test_etcp_init_liveness.c index bd46b5ed..9c0247f3 100644 --- a/tests/test_etcp_init_liveness.c +++ b/tests/test_etcp_init_liveness.c @@ -56,6 +56,9 @@ static void link_event(struct ETCP_CONN* conn, struct ETCP_LINK* link, int old_s if (e == &ep[1] && old_status && !link->link_status && close_action == 1) { CHECK(!close_fired++); etcp_connection_close(conn); } + if (e == &ep[1] && old_status && !link->link_status && close_action == 3) { + CHECK(!close_fired++); etcp_link_close(link); + } } static void conn_event(struct ETCP_CONN* conn, int event, void* arg) { @@ -249,6 +252,25 @@ static void response_boundaries(void) { teardown(); } +/* Удаление самого link из уведомления не оставляет RX со ссылкой на освобождённый объект. */ +static void delete_in_callback(unsigned keepalive) { + setup(0, 2); close_action = 3; + struct ETCP_LINK* link = first_link(0); + uint64_t epoch = ep[1].conn->reset_id; + link->recv_keepalive = 0; + if (keepalive) etcp_link_send_keepalive(link); + else etcp_link_send_init(link, 0, 0); + link->recv_keepalive = 1; + run_for(1000); + CHECK(close_fired == 1 && ep[1].conn->links && !ep[1].conn->links->next && ep[1].conn->links_up == 1); + CHECK(ep[1].conn->reset_id == epoch && !ep[1].reinit && !ep[1].down && !ep[1].conn->callbacks_running); + struct ll_entry* entry = ll_alloc_lldgram(2); CHECK(entry); + entry->len = 2; entry->dgram[0] = 253; entry->dgram[1] = 17; + CHECK(etcp_send(ep[0].conn, entry) == 0); run_for(10000); CHECK(ep[1].received == 1); + DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "Callback deletes link: RX=%s, alternate delivery PASS", keepalive ? "keepalive" : "INIT"); + teardown(); +} + /* При отказе показать конкретные живые блоки вместо одного несовпавшего счётчика. */ static void check_memory(size_t baseline) { if (u_get_allocated_count() == baseline) return; @@ -271,6 +293,7 @@ int main(void) { for (unsigned keepalive = 0; keepalive < 2; keepalive++) for (unsigned action = 1; action <= 2; action++) { close_in_callback(action, keepalive); check_memory(baseline); } + for (unsigned keepalive = 0; keepalive < 2; keepalive++) { delete_in_callback(keepalive); check_memory(baseline); } healthy_alternative(); check_memory(baseline); DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "PASS encrypted INIT liveness: cold start, one-way loss, repeated INIT, recovery and callback close"); test_clock_finish(); socket_platform_cleanup(); return 0;