From e3bd66f0b7fea9a80ca900aada9d8bad52fe58f7 Mon Sep 17 00:00:00 2001 From: evgeny Date: Tue, 27 Oct 2026 07:42:29 +0100 Subject: [PATCH] test(chat): reproduce ready startup after a required subscription fails --- tests/Makefile.am | 4 ++++ tests/test_chat_lifecycle.c | 39 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 tests/test_chat_lifecycle.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 4d6db00f..03d1cbcf 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -307,6 +307,7 @@ check_PROGRAMS += test_chat_member check_PROGRAMS += test_chat_json check_PROGRAMS += test_chat_profile check_PROGRAMS += test_chat_preferences +check_PROGRAMS += test_chat_lifecycle check_PROGRAMS += test_instance_contract test_instance_contract_SOURCES = test_instance_contract.c test_instance_contract_LDADD = $(LIBUTUN) $(COMMON_LIBS) @@ -341,6 +342,9 @@ test_chat_json_LDFLAGS = -Wl,--wrap=sqlite3_prepare_v2 -Wl,--wrap=sqlite3_bind_t -Wl,--wrap=u_realloc_impl -Wl,--wrap=u_calloc_impl test_chat_profile_SOURCES = test_chat_profile.c test_chat_preferences_SOURCES = test_chat_preferences.c +test_chat_lifecycle_SOURCES = test_chat_lifecycle.c +test_chat_lifecycle_LDADD = $(LIBUTUN) $(COMMON_LIBS) +test_chat_lifecycle_LDFLAGS = -Wl,--wrap=member_sync_add_props_cbk test_chat_preferences_LDADD = $(LIBUTUN) $(COMMON_LIBS) test_chat_preferences_LDFLAGS = -Wl,--wrap=sqlite3_finalize -Wl,--wrap=sqlite3_prepare_v2 -Wl,--wrap=sqlite3_bind_text \ -Wl,--wrap=sqlite3_step -Wl,--wrap=sqlite3_changes -Wl,--wrap=sqlite3_exec -Wl,--wrap=sqlite3_column_text \ diff --git a/tests/test_chat_lifecycle.c b/tests/test_chat_lifecycle.c new file mode 100644 index 00000000..41942ef6 --- /dev/null +++ b/tests/test_chat_lifecycle.c @@ -0,0 +1,39 @@ +/* Старт chat_core не должен игнорировать отказ обязательной подписки. */ +#define _GNU_SOURCE +#include "../src/utun_instance.h" +#include "../src/chat/chat_core.h" +#include "../src/chat/chat_event.h" +#include "../src/chat/member_sync.h" +#include "../lib/debug_config.h" +#include "../lib/mem.h" +#include +#include +#include + +static int fail_props; +static unsigned ready; +extern int __real_member_sync_add_props_cbk(struct UTUN_INSTANCE*, node_props_changed_fn, void*); +int __wrap_member_sync_add_props_cbk(struct UTUN_INSTANCE* inst, node_props_changed_fn callback, void* arg) { + if (fail_props) { fail_props = 0; DEBUG_WARN(DEBUG_CATEGORY_CHAT, "lifecycle test: property subscription refused"); return -1; } + return __real_member_sync_add_props_cbk(inst, callback, arg); +} +static void event(struct UTUN_INSTANCE* inst, int type, const uint8_t* data, int bytes) { + (void)inst; (void)data; (void)bytes; + if (type == CHAT_EVT_DB_READY || type == CHAT_EVT_MY_NODE_ID) ready++; +} + +int main(void) { + debug_config_init(); debug_set_level(DEBUG_LEVEL_ERROR); size_t baseline = u_get_allocated_count(); + utun_instance_set_tun_init_enabled(0); struct UASYNC* ua = uasync_create(); assert(ua); + char directory[] = "/tmp/utun-lifecycle-XXXXXX"; assert(mkdtemp(directory)); char config[512], database[512]; + snprintf(config, sizeof(config), "[global]\nmy_node_name=lifecycle test\ndb_path=%s\n[ntp]\nenabled=no\n" + "[chatserver]\ngroup_autoconnect=0\nstorage_autoload=0\n", directory); + struct UTUN_INSTANCE* inst = utun_instance_create_from_str(ua, config); assert(inst && !utun_core_start(inst)); + chat_event_set_handler(inst, event); snprintf(database, sizeof(database), "%s/chats.db", directory); + fail_props = 1; int rc = chat_core_init(inst, database); + if (rc >= 0) DEBUG_ERROR(DEBUG_CATEGORY_CHAT, "lifecycle test: startup succeeded after refused properties subscription rc=%d ready=%u", rc, ready); + assert(rc < 0 && !fail_props && !ready && !inst->chat_core && inst->core_started); + assert(!chat_service_start(inst) && ready == 2); chat_service_stop(inst); + utun_instance_destroy(inst); uasync_poll(ua, 0); uasync_destroy(ua, 0); assert(u_get_allocated_count() == baseline); + puts("PASS lifecycle:subscription failure aborts startup without ready events;core survives and retry succeeds"); return 0; +}