|
|
|
|
@ -37,6 +37,7 @@
|
|
|
|
|
#include "../lib/u_async.h" |
|
|
|
|
#include "../lib/debug_config.h" |
|
|
|
|
#include "../lib/mem.h" |
|
|
|
|
#include "test_clock.h" |
|
|
|
|
|
|
|
|
|
#define POLL_MS 5 |
|
|
|
|
#define LINK_TIMEOUT_MS 8000 |
|
|
|
|
@ -118,7 +119,7 @@ static void conn_cb_b(struct CONN_MGR_HANDLE* h, uint64_t node, uint64_t grp, en
|
|
|
|
|
|
|
|
|
|
static int poll_until(int (*cond)(void), uint32_t timeout_ms) { |
|
|
|
|
uint64_t start = get_time_tb(); |
|
|
|
|
while (!cond() && (get_time_tb() - start) < (uint64_t)timeout_ms * 10) uasync_poll(ua, POLL_MS); |
|
|
|
|
while (!cond() && (get_time_tb() - start) < (uint64_t)timeout_ms * 10) test_clock_poll(ua, POLL_MS); |
|
|
|
|
return cond(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -356,13 +357,12 @@ static int send_data(uint8_t marker, uint64_t hop) {
|
|
|
|
|
e->dgram[0] = TEST_CM_SERVICE; e->dgram[1] = marker; e->len = 2; |
|
|
|
|
if (etcp_route_send(inst_a, TOPO_GROUP_UTUN, nid_b, e, 1, 0) < 0) { fail("DATA: send failed"); return -1; } |
|
|
|
|
uint64_t end = get_time_tb() + 30000; |
|
|
|
|
while (!data_count && get_time_tb() < end) uasync_poll(ua, POLL_MS); |
|
|
|
|
while (!data_count && get_time_tb() < end) test_clock_poll(ua, POLL_MS); |
|
|
|
|
if (!data_count || data_hop != hop || expected_marker != marker) { fail("DATA: wrong delivery/hop"); return -1; } |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
static void poll_ms(int ms) { |
|
|
|
|
uint64_t end = get_time_tb() + (uint64_t)ms * 10; |
|
|
|
|
while (get_time_tb() < end) uasync_poll(ua, POLL_MS); |
|
|
|
|
test_clock_run_for(ua, ms * 10); |
|
|
|
|
} |
|
|
|
|
static int direct_a_ready(void) { |
|
|
|
|
uint8_t ty = conn_type_of(inst_a, nid_b); |
|
|
|
|
@ -576,20 +576,26 @@ static int run_recovery(void) {
|
|
|
|
|
fail("RECOVERY: late loss did not start recovery with reserve"); return -1; |
|
|
|
|
} |
|
|
|
|
if (send_data(2, nid_c)) return -1; |
|
|
|
|
// Сокращаем только срок тестовой пробы; интервалы backoff проверяем настоящими часами.
|
|
|
|
|
// Сроки backoff остаются 1/2/4с; оснастка проходит все промежуточные сетевые события и таймеры.
|
|
|
|
|
for (int cycle = 0; cycle < 3; cycle++) { |
|
|
|
|
uint64_t start = entry->start_tb; |
|
|
|
|
unsigned delay = entry->retry_delay_ms; |
|
|
|
|
if (delay != (CONN_MGR_RETRY_MIN_MS << cycle)) { fail("RECOVERY: wrong exponential backoff"); return -1; } |
|
|
|
|
entry->deadline_tb = get_time_tb() + 100; |
|
|
|
|
cm_arm_timer(entry); poll_ms(30); |
|
|
|
|
if (entry->attempt_active || !entry->retry_tb || entry->retry_tb <= get_time_tb()) { |
|
|
|
|
fail("RECOVERY: exhausted round did not enter backoff"); return -1; |
|
|
|
|
} |
|
|
|
|
if (send_data((uint8_t)(3 + cycle), nid_c)) return -1; |
|
|
|
|
while (entry->start_tb == start && get_time_tb() < entry->retry_tb + 3000) uasync_poll(ua, POLL_MS); |
|
|
|
|
if (entry->start_tb == start || !entry->attempt_active || entry->start_tb - start < delay * 10 || timeout_count) { |
|
|
|
|
uint64_t due = entry->retry_tb; |
|
|
|
|
while (entry->start_tb == start && get_time_tb() < due + 3000) test_clock_poll(ua, POLL_MS); |
|
|
|
|
if (entry->start_tb == start || !entry->attempt_active || entry->start_tb < due || |
|
|
|
|
entry->start_tb - start < delay * 10 || timeout_count) { |
|
|
|
|
fail("RECOVERY: retry/backoff lost demand or repeated TIMEOUT"); return -1; |
|
|
|
|
} |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "CM recovery: cycle=%d delay_ms=%u retry_due_tb=%llu started_tb=%llu reserve=%u events=%d/%d/%d", |
|
|
|
|
cycle + 1, delay, (unsigned long long)due, (unsigned long long)entry->start_tb, |
|
|
|
|
entry->conn_type, up_count, down_count, timeout_count); |
|
|
|
|
} |
|
|
|
|
entry->deadline_tb = get_time_tb() + 100; cm_arm_timer(entry); poll_ms(30); |
|
|
|
|
uint64_t start = entry->start_tb; |
|
|
|
|
@ -736,6 +742,7 @@ static int run_initial_timeout(void) {
|
|
|
|
|
int main(void) { |
|
|
|
|
debug_config_init(); |
|
|
|
|
debug_set_level(DEBUG_LEVEL_ERROR); |
|
|
|
|
test_clock_init(1000); |
|
|
|
|
if (getenv("UTUN_TEST_DEBUG")) { |
|
|
|
|
debug_set_category_level(DEBUG_CATEGORY_BGP, DEBUG_LEVEL_INFO); |
|
|
|
|
debug_set_category_level(DEBUG_CATEGORY_GENERAL, DEBUG_LEVEL_DEBUG); |
|
|
|
|
@ -774,6 +781,7 @@ int main(void) {
|
|
|
|
|
scenario_teardown(); |
|
|
|
|
|
|
|
|
|
if (ua) { uasync_poll(ua, 0); uasync_destroy(ua, 0); ua = NULL; } |
|
|
|
|
test_clock_finish(); |
|
|
|
|
|
|
|
|
|
fprintf(stderr, "%s\n", g_failed ? "RESULT: FAIL" : "RESULT: PASS"); fflush(stderr); |
|
|
|
|
return g_failed ? 1 : 0; |
|
|
|
|
|