diff --git a/tests/Makefile.am b/tests/Makefile.am index 237533d1..855225a9 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -303,6 +303,7 @@ check_PROGRAMS += test_config_parser check_PROGRAMS += test_chat_setting check_PROGRAMS += test_chat_channel check_PROGRAMS += test_group_avatar_sql +check_PROGRAMS += test_chat_member check_PROGRAMS += test_instance_contract test_instance_contract_SOURCES = test_instance_contract.c test_instance_contract_LDADD = $(LIBUTUN) $(COMMON_LIBS) @@ -325,6 +326,9 @@ test_group_avatar_sql_LDADD = $(LIBUTUN) $(COMMON_LIBS) test_group_avatar_sql_LDFLAGS = -Wl,--wrap=sqlite3_bind_blob -Wl,--wrap=sqlite3_bind_int64 -Wl,--wrap=sqlite3_bind_text \ -Wl,--wrap=sqlite3_exec -Wl,--wrap=sqlite3_prepare_v2 -Wl,--wrap=sqlite3_step -Wl,--wrap=sqlite3_changes -Wl,--wrap=sqlite3_finalize \ -Wl,--wrap=sc_ed25519_sign +test_chat_member_SOURCES = test_chat_member.c +test_chat_member_LDADD = $(LIBUTUN) $(COMMON_LIBS) +test_chat_member_LDFLAGS = -Wl,--wrap=sqlite3_finalize else test_socket_monitor_LDFLAGS += -Wl,--wrap=read endif diff --git a/tests/test_chat_member.c b/tests/test_chat_member.c new file mode 100644 index 00000000..1d58e4c3 --- /dev/null +++ b/tests/test_chat_member.c @@ -0,0 +1,32 @@ +/* Полный снимок участников не выдаёт успех после отказа SQL. */ +#define _GNU_SOURCE +#include "../src/chat/chat_member.c" +#include "../src/routing_layer/topo_node_sqlite.h" +#include + +static int fail_query; +extern int __real_sqlite3_finalize(sqlite3_stmt*); +int __wrap_sqlite3_finalize(sqlite3_stmt* st) { + const char* target = "SELECT p.node_id"; + int fail = fail_query && st && !strncmp(sqlite3_sql(st), target, strlen(target)); + if (fail) { fail_query = 0; DEBUG_WARN(DEBUG_CATEGORY_CHAT_SYNC, "member test: injected snapshot finalize failure"); } + int rc = __real_sqlite3_finalize(st); return fail ? SQLITE_IOERR : rc; +} + +int main(void) { + debug_config_init(); debug_set_level(DEBUG_LEVEL_ERROR); debug_set_category_level(DEBUG_CATEGORY_CHAT_SYNC, DEBUG_LEVEL_INFO); + size_t baseline = u_get_allocated_count(); utun_instance_set_tun_init_enabled(0); + struct UASYNC* ua = uasync_create(); assert(ua); + struct UTUN_INSTANCE* inst = utun_instance_create_from_str(ua, + "[ntp]\nenabled=no\n[chatserver]\ngroup_autoconnect=0\nstorage_autoload=0\n"); + assert(inst && !utun_core_start(inst) && !chat_service_start(inst)); + uint64_t group = chat_core_create_channel_auto(inst, "member SQL"); assert(group); + char channel[32]; snprintf(channel, sizeof(channel), "%llu", (unsigned long long)group); + uint8_t* wire = NULL; int count = 0; fail_query = 1; + int rc = chat_core_get_member_list(inst, channel, &wire, &count); + DEBUG_INFO(DEBUG_CATEGORY_CHAT_SYNC, "member test: finalize fault result=%d count=%d fault_pending=%d", rc, count, fail_query); + assert(rc < 0 && !wire && !count && !fail_query); + assert(!chat_core_get_member_list(inst, channel, &wire, &count) && count == 1); u_free(wire); + utun_instance_destroy(inst); uasync_poll(ua, 0); uasync_destroy(ua, 0); assert(u_get_allocated_count() == baseline); + DEBUG_INFO(DEBUG_CATEGORY_CHAT_SYNC, "PASS member snapshot SQL refusal and retry"); return 0; +}