diff --git a/tests/test_etcp_multipath.c b/tests/test_etcp_multipath.c index 504565f4..ed751aab 100644 --- a/tests/test_etcp_multipath.c +++ b/tests/test_etcp_multipath.c @@ -326,6 +326,8 @@ static void stalled(const struct profile* settings, unsigned count, unsigned bro if (!pkt->last_link || ((directions & 1) && traces[0][pkt->seq].first_rx)) continue; for (unsigned p = 0; p < count; p++) if ((broken & (1u << p)) && ss_get_port(&pkt->last_link->remote_addr) == dummynet_get_listen_port(channels[p])) { + // Пакет должен ещё находиться в propagation delay, а не уже лежать в сокете получателя. + if ((directions & 1) && get_time_us() - traces[0][pkt->seq].first_tx >= settings[p].rtt_ms * 500ULL) continue; pending |= 1u << p; if (!fault_seq || pkt->seq < fault_seq) fault_seq = pkt->seq; } @@ -358,16 +360,23 @@ static void stalled(const struct profile* settings, unsigned count, unsigned bro (unsigned long long)rate, (unsigned long long)capacity, fault_seq, (unsigned long long)(traces[0][fault_seq].first_rx > fault_start ? traces[0][fault_seq].first_rx-fault_start : 0), traces[0][fault_seq].attempts); - expect(ep[1].bytes > before, "delivery during active fault", ep[1].bytes-before, 1); + if (duration_ms > 100) expect(ep[1].bytes > before, "delivery during active fault", ep[1].bytes-before, 1); expect(ep[1].max_gap <= MAX_GAP_US, "maximum delivery pause <=100ms", ep[1].max_gap, MAX_GAP_US); if (sparse) expect(ep[1].max_latency <= MAX_GAP_US, "bounded-source latency <=100ms", ep[1].max_latency, MAX_GAP_US); else if (duration_ms > 1000) expect(rate >= capacity * 85 / 100, "fault steady goodput >=85% healthy capacity", rate, capacity * 85 / 100); for (int i = 0; i < 2; i++) CHECK(ep[i].conn->reinit_count == epochs[i] && ep[i].conn->links_up); - measuring = 0; + measuring = duration_ms <= 100; for (unsigned p = 0; p < count; p++) if (broken & (1u << p)) for (unsigned dir = 0; dir < 2; dir++) CHECK(dummynet_set_mode(channels[p], dir, DUMMYNET_RUN) == 0); - run_for(3000, 1, "recovery"); run_for(10000, 0, "drain"); + run_for(1000, 1, "recovery"); + if (duration_ms <= 100) { + expect(ep[1].samples > 0, "delivery after short HOLD", ep[1].samples, 1); + expect(ep[1].max_gap <= MAX_GAP_US, "short HOLD including resume: pause <=100ms", ep[1].max_gap, MAX_GAP_US); + expect(ep[1].max_latency <= MAX_GAP_US, "short HOLD including resume: latency <=100ms", ep[1].max_latency, MAX_GAP_US); + } + measuring = 0; + run_for(2000, 1, "recovery"); run_for(10000, 0, "drain"); for (int i = 0; i < 2; i++) expect(ep[i].sent == ep[1-i].received, "complete delivery after recovery", ep[1-i].received, ep[i].sent); teardown(); @@ -413,6 +422,7 @@ int main(int argc, char** argv) { bidirectional = 0; struct profile settings[] = {{20,8000},{20,8000},{20,2000}}; if (!strcmp(case_name, "slow-drop")) settings[1].rtt_ms = 200; + if (faults[n].count == 3) { settings[1].rtt_ms = 80; settings[2].rtt_ms = 200; } stalled(settings, faults[n].count, faults[n].broken, faults[n].directions, faults[n].mode, faults[n].sparse, faults[n].ms); CHECK(u_get_allocated_count() == baseline); }