|
|
|
|
@ -17,6 +17,7 @@
|
|
|
|
|
#include "etcp.h" |
|
|
|
|
#include "etcp_connections.h" |
|
|
|
|
#include "test_utils.h" |
|
|
|
|
#include "test_clock.h" |
|
|
|
|
#include <sqlite3.h> |
|
|
|
|
#include <openssl/evp.h> |
|
|
|
|
|
|
|
|
|
@ -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; |
|
|
|
|
} |
|
|
|
|
|