diff --git a/tests/db_sync_fixture.h b/tests/db_sync_fixture.h new file mode 100644 index 00000000..928a5b58 --- /dev/null +++ b/tests/db_sync_fixture.h @@ -0,0 +1,31 @@ +/* Модель истории для тестов с заранее заданными участниками, без запуска chat_sync. + * Общий Merkle настоящий; пустая MEMBERS-модель не реплицирует тестовые удостоверения. + * Если движок создан фикстурой (!chat_sync), перед destroy ядра вызвать merkle_sync_destroy. */ +#ifndef TEST_DB_SYNC_FIXTURE_H +#define TEST_DB_SYNC_FIXTURE_H +#include "../src/utun_instance.h" +#include "../src/transport_layer/etcp_api.h" +#include "../src/chat/db_sync.h" +#include "../src/chat/merkle_sync.h" +#include + +static int fixture_member_hash(void* ctx, const char* ns, uint8_t level, uint64_t prefix, EVP_MD_CTX* hash) { + (void)ctx; (void)ns; (void)level; (void)prefix; (void)hash; return 0; +} +static int fixture_member_page(void* ctx, const char* ns, uint64_t prefix, int av, const merkle_key_t* after, + uint8_t* data, size_t* len, merkle_key_t* next, int* more) { + (void)ctx; (void)ns; (void)prefix; (void)av; (void)after; (void)data; + *len = 0; *more = 0; memset(next, 0, sizeof(*next)); return 0; +} +static int fixture_member_apply(void* ctx, const char* ns, uint64_t peer, const uint8_t* data, size_t len) { + (void)ctx; (void)ns; (void)peer; (void)data; return len ? -1 : 0; +} +/* После init ядра и регистрации таблиц; 0/-1. READY/допуск пира/подписи истории не подменяются. */ +static int setup_history_model(struct UTUN_INSTANCE* inst) { + static const struct merkle_sync_data_ops ops = { + .update_bucket_hash = fixture_member_hash, .get_page = fixture_member_page, .apply_items = fixture_member_apply + }; + if (!inst->msync && merkle_sync_init(inst, ETCP_ID_MEMBER_SYNC, &ops, inst) < 0) return -1; + return db_sync_register_model(inst); +} +#endif diff --git a/tests/test_chat_sync_stress.c b/tests/test_chat_sync_stress.c index b632ee95..6884b926 100644 --- a/tests/test_chat_sync_stress.c +++ b/tests/test_chat_sync_stress.c @@ -7,6 +7,7 @@ #include "../lib/platform_compat.h" #include "test_utils.h" #include "test_net.h" +#include "db_sync_fixture.h" #ifdef _WIN32 #include #include @@ -174,6 +175,9 @@ int main(void) { si_a = db_sync_instance_add(inst_a, INSTANCE_NAME, INSTANCE_ID); si_b = db_sync_instance_add(inst_b, INSTANCE_NAME, INSTANCE_ID); if (!si_a || !si_b) { DEBUG_ERROR(DEBUG_CATEGORY_DEBUG, "db_sync_instance_add"); return 1; } + if (setup_history_model(inst_a) < 0 || setup_history_model(inst_b) < 0) { + DEBUG_ERROR(DEBUG_CATEGORY_DEBUG, "history model registration"); return 1; + } db_sync_instance_set_gated(si_a, 0); db_sync_instance_set_gated(si_b, 0); timeout_id = uasync_set_timeout(ua, TOTAL_TIMEOUT_TB, NULL, test_timeout, "total_timeout"); @@ -257,8 +261,8 @@ cleanup: if (timeout_id && ua) { uasync_cancel_timeout(ua, timeout_id); timeout_id = NULL; } if (si_a) { db_sync_instance_remove(si_a); si_a = NULL; } if (si_b) { db_sync_instance_remove(si_b); si_b = NULL; } - if (inst_a) { inst_a->running = 0; utun_instance_destroy(inst_a); inst_a = NULL; } - if (inst_b) { inst_b->running = 0; utun_instance_destroy(inst_b); inst_b = NULL; } + if (inst_a) { inst_a->running = 0; if (!inst_a->chat_sync) merkle_sync_destroy(inst_a); utun_instance_destroy(inst_a); inst_a = NULL; } + if (inst_b) { inst_b->running = 0; if (!inst_b->chat_sync) merkle_sync_destroy(inst_b); utun_instance_destroy(inst_b); inst_b = NULL; } if (ua) { uasync_destroy(ua, 0); ua = NULL; } debug_disable_file_output(); diff --git a/tests/test_db_sync.c b/tests/test_db_sync.c index 60d4894d..d7943c9c 100644 --- a/tests/test_db_sync.c +++ b/tests/test_db_sync.c @@ -8,6 +8,7 @@ #include "../lib/platform_compat.h" #include "test_utils.h" #include "test_net.h" +#include "db_sync_fixture.h" #ifdef _WIN32 #include #include @@ -247,25 +248,6 @@ static struct DB_SYNC_INSTANCE* add_table(struct UTUN_INSTANCE* inst, const char } -/* Изолируем модель истории от протокола MEMBERS; настоящие групповые READY и транспорт не подменяются. */ -static int empty_hash(void* ctx, const char* ns, uint8_t level, uint64_t prefix, EVP_MD_CTX* hash) { - (void)ctx; (void)ns; (void)level; (void)prefix; (void)hash; return 0; -} -static int empty_page(void* ctx, const char* ns, uint64_t prefix, int av, const merkle_key_t* after, - uint8_t* data, size_t* len, merkle_key_t* next, int* more) { - (void)ctx; (void)ns; (void)prefix; (void)av; (void)after; (void)data; - *len = 0; *more = 0; memset(next, 0, sizeof(*next)); return 0; -} -static int empty_apply(void* ctx, const char* ns, uint64_t peer, const uint8_t* data, size_t len) { - (void)ctx; (void)ns; (void)peer; (void)data; return len ? -1 : 0; -} -static int setup_history_model(struct UTUN_INSTANCE* inst) { - static const struct merkle_sync_data_ops ops = { - .update_bucket_hash = empty_hash, .get_page = empty_page, .apply_items = empty_apply - }; - if (!inst->msync && merkle_sync_init(inst, ETCP_ID_MEMBER_SYNC, &ops, inst) < 0) return -1; - return db_sync_register_model(inst); -} static int history_ready(struct DB_SYNC_INSTANCE* si) { uint8_t root[32]; return db_sync_read_root(si, root); } static int same_roots(struct DB_SYNC_INSTANCE* a, struct DB_SYNC_INSTANCE* b, struct DB_SYNC_INSTANCE* c) { uint8_t ra[32], rb[32], rc[32];