diff --git a/tests/Makefile.am b/tests/Makefile.am index 7f2ad4fe..1912e2ce 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -568,7 +568,7 @@ test_db_sync_schema_SOURCES = test_db_sync_schema.c test_db_sync_schema_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/lib test_db_sync_schema_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS) -test_merkle_sync_SOURCES = test_merkle_sync.c +test_merkle_sync_SOURCES = test_merkle_sync.c $(test_clock_sources) test_chat_feedback_SOURCES = test_chat_feedback.c test_chat_feedback_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/chat -I$(top_srcdir)/lib test_chat_feedback_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS) @@ -579,6 +579,7 @@ test_member_adapter_SOURCES = test_member_adapter.c test_member_adapter_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/chat -I$(top_srcdir)/lib test_member_adapter_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS) test_merkle_sync_CFLAGS = -I$(top_srcdir)/src -I$(top_srcdir)/src/chat -I$(top_srcdir)/lib +test_merkle_sync_LDFLAGS = $(test_clock_ldflags) test_merkle_sync_LDADD = $(LIBUTUN) $(CRYPTO_LIBS) $(COMMON_LIBS) test_chat_sync_stress_SOURCES = test_chat_sync_stress.c diff --git a/tests/test_merkle_sync.c b/tests/test_merkle_sync.c index b857e841..c248c94e 100644 --- a/tests/test_merkle_sync.c +++ b/tests/test_merkle_sync.c @@ -17,6 +17,7 @@ #include "etcp.h" #include "etcp_connections.h" #include "test_utils.h" +#include "test_clock.h" #include #include @@ -576,7 +577,7 @@ static int _cond_links_up(void) { static int _wait_for(const char* desc, int (*cond)(void), int timeout_tb) { uint64_t start = get_time_tb(); while (!cond() && (get_time_tb() - start) < (uint64_t)timeout_tb) - uasync_poll(i_ua, POLL_MS); + test_clock_poll(i_ua, POLL_MS); if (cond()) return 1; printf(" TIMEOUT: %s\n", desc); i_phase = 2; return 0; @@ -731,7 +732,7 @@ static void test_hash_match(void) { _intg_ins_many(&data_b, i_b, 0, 5); done_sync = 0; merkle_sync_start(i_a, MT_DATA_MEMBERS, i_b->node_id, MS_NS_TEST, _on_sync_done, NULL); - for (int i = 0; i < 200 && !done_sync && i_phase == 0; i++) uasync_poll(i_ua, 1); + if (!_wait_for("identical hashes", _cond_done, 2000)) { FAIL("sync did not complete quickly"); _intg_cleanup(); return; } if (!done_sync) { FAIL("sync did not complete quickly"); _intg_cleanup(); return; } if (_intg_verify_all(i_a, i_b, &data_a, &data_b, MS_NS_TEST) != 0) { FAIL("verify failed"); _intg_cleanup(); return; } @@ -848,7 +849,7 @@ static int _intg_init_three(void) { i_timeout_id = uasync_set_timeout(i_ua, INTG_TIMEOUT_TB*5, NULL, _intg_timeout, "ms_intg_timeout"); if (!_wait_for("links up", _cond_links_up, PHASE3_TIMEOUT_TB)) { _intg_cleanup(); return -1; } /* let connections settle */ - for (int i = 0; i < 20; i++) uasync_poll(i_ua, 5); + test_clock_run_for(i_ua, 200); _intg_setup_contexts(); ctx_a.inst = i_a; ctx_b.inst = i_b; ctx_c.inst = i_c; _ms_ensure_groups(i_a); _ms_ensure_groups(i_b); _ms_ensure_groups(i_c); @@ -913,7 +914,7 @@ static void test_cancel(void) { done_sync = 0; merkle_sync_start(i_a, MT_DATA_MEMBERS, i_b->node_id, MS_NS_TEST, _on_sync_done, NULL); merkle_sync_cancel(i_a, MT_DATA_MEMBERS, i_b->node_id, MS_NS_TEST); - for (int i = 0; i < 100 && i_phase == 0; i++) uasync_poll(i_ua, 10); + test_clock_run_for(i_ua, 1000); if (!done_sync) PASS(); else FAIL("done_cb was called"); _intg_cleanup(); } @@ -929,20 +930,21 @@ static void test_start_overwrite(void) { sw_cb1_called = sw_cb2_called = 0; merkle_sync_start(i_a, MT_DATA_MEMBERS, i_b->node_id, MS_NS_TEST, _sw_done1, NULL); merkle_sync_start(i_a, MT_DATA_MEMBERS, i_b->node_id, MS_NS_TEST, _sw_done2, NULL); - for (int i = 0; i < 500 && !sw_cb2_called && i_phase == 0; i++) uasync_poll(i_ua, 10); + uint64_t deadline = get_time_tb() + 5000; + while (!sw_cb2_called && i_phase == 0 && get_time_tb() < deadline) test_clock_poll(i_ua, 10); if (sw_cb1_called && sw_cb2_called) PASS(); else FAIL("cb1=%d cb2=%d", sw_cb1_called, sw_cb2_called); _intg_cleanup(); } static int run_stage4(void) { - printf("--- Stage 4: randomized 2-instance sync (50 iters) ---\n"); + printf("--- Stage 4: randomized 2-instance sync (25 iters) ---\n"); stage_failures = 0; test_randomized_two(); return stage_failures; } static int run_stage5(void) { - printf("--- Stage 5: randomized 3-instance star sync (30 iters) ---\n"); + printf("--- Stage 5: randomized 3-instance star sync (5 iters) ---\n"); stage_failures = 0; test_randomized_three(); return stage_failures; @@ -1068,7 +1070,7 @@ static int _str_wait_for(const char* desc, int (*cond)(void), int timeout_tb) { struct str_state* s = gs; uint64_t start = get_time_tb(); while (!cond() && (get_time_tb() - start) < (uint64_t)timeout_tb && s->phase == 0) - uasync_poll(s->ua, 1); + test_clock_poll(s->ua, 1); if (s->phase == 0 && cond()) return 1; printf(" STRESS TIMEOUT: %s\n", desc); s->phase = 2; return 0; @@ -1383,8 +1385,11 @@ static void test_stress_spam(void) { * poll с ограниченным таймаутом (10ms), т.к. uasync_poll(ua,-1) при уже * просроченном ближайшем таймере уходит в бесконечный epoll_wait и не * обрабатывает expired-таймеры. */ - while (s->phase == 0) - uasync_poll(s->ua, 100); + while (s->phase == 0) { + // Пять секунд активной нагрузки — реальные; ускоряем только подготовку и финальный дренаж. + if (s->spam_active) uasync_poll(s->ua, 100); + else test_clock_poll(s->ua, 100); + } if (s->phase != 1) { FAIL("convergence failed (phase=%d)", s->phase); _str_cleanup(); return; } PASS(); @@ -1437,6 +1442,7 @@ int main(void) { debug_config_init(); debug_set_level(DEBUG_LEVEL_ERROR); if (getenv("UTUN_TEST_DEBUG")) debug_set_category_level(DEBUG_CATEGORY_MEMBER_SYNC, DEBUG_LEVEL_DEBUG); + test_clock_init(100); if (run_stage1() != 0) { printf("=== Stage 1 FAILED ===\n"); return 1; } printf("=== Stage 1 PASSED (%d tests) ===\n\n", tests_run); @@ -1460,5 +1466,6 @@ int main(void) { printf("=== Stage 7 PASSED (%d tests) ===\n\n", tests_run); printf("=== ALL PASS (%d tests) ===\n", tests_run); + test_clock_finish(); return 0; }