Test nested deletion of the current and neighboring ETCP paths

This commit is contained in:
evgeny committed 2026-10-23 22:03:58 +02:00
1 parent 986193055e
commit 2ea4fb94ab
1 file changed
+30 -1
+30 -1
View File
@@ -142,6 +142,35 @@ static void ncd_late_up_case(struct UTUN_INSTANCE* inst) {
CHECK(!inst->ncd_registry && !inst->connections->count);
puts("PASS NCD late UP after timeout and subsequent reconnect");
}
struct link_close_case { struct ETCP_LINK *neighbor; unsigned events, nested; };
static void close_neighbor(struct ETCP_CONN *conn, struct ETCP_LINK *link, int old_state, int old_status, void *arg) {
(void)conn; (void)old_state; (void)old_status;
struct link_close_case *test = arg;
test->events++;
CHECK(link->closing);
etcp_link_close(link);
if (test->neighbor && test->neighbor != link) {
struct ETCP_LINK *neighbor = test->neighbor;
test->neighbor = NULL; test->nested++;
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "Closing neighbor from teardown callback: current=%u neighbor=%u",
link->local_link_id, neighbor->local_link_id);
etcp_link_close(neighbor);
}
}
static void neighbor_close_case(struct UTUN_INSTANCE *inst) {
struct ETCP_CONN *conn = etcp_connection_create(inst, "neighbor close"); CHECK(conn);
CHECK(etcp_conn_ref_take(conn) == 0);
CHECK(etcp_link_new(conn, NULL, NULL, 0));
struct link_close_case test = {.neighbor = etcp_link_new(conn, NULL, NULL, 0)}; CHECK(test.neighbor);
etcp_add_link_status_cbk(inst, close_neighbor, &test);
etcp_connection_close(conn);
CHECK(!conn->links && test.events == 2 && test.nested == 1 && conn->delete_complete);
etcp_remove_link_status_cbk(inst, close_neighbor, &test);
etcp_conn_ref_free(conn); uasync_drain_immediate(inst->ua); uasync_poll(inst->ua, 0);
CHECK(!inst->connections->count);
puts("PASS nested close: current and neighbor links, no cached next pointer");
}
int main(void) {
debug_config_init(); debug_set_level(DEBUG_LEVEL_WARN);
const char* log = getenv("LIFECYCLE_TEST_LOG");
@@ -173,7 +202,7 @@ int main(void) {
uasync_poll(inst.ua,0); CHECK(inst.connections->count == 0);
printf("PASS lifecycle scenario %d\n",scenario+1);
}
ncd_cases(&inst); ncd_late_up_case(&inst); recovery_cases(&inst);
ncd_cases(&inst); ncd_late_up_case(&inst); recovery_cases(&inst); neighbor_close_case(&inst);
queue_free(inst.connections); uasync_poll(inst.ua,0);
CHECK(inst.ua->timer_alloc_count == inst.ua->timer_free_count);
uasync_destroy(inst.ua,0); CHECK(u_get_allocated_count() == baseline);