Test send queue bypass, retry priority, and bounded admission
This commit is contained in:
1 parent
8167e0e5f5
commit
acde6bda9d
1 file changed
+76
@@ -839,6 +839,81 @@ static void retry_alternative_lifecycle(void) {
|
||||
memory_pool_free(inst.pkt_pool, pkt); ack_all(); teardown();
|
||||
}
|
||||
|
||||
/* Заблокированный повтор не держит следующие DATA; среди готовых пакетов повтор имеет приоритет. */
|
||||
static void send_queue_scan(void) {
|
||||
setup(); fill(a, 1, 100);
|
||||
conn->initialized = 0; test_clock_run_for(ua, 120); conn->initialized = 1;
|
||||
struct INFLIGHT_PACKET* blocked = (struct INFLIGHT_PACKET*)conn->input_send_q->head; CHECK(blocked);
|
||||
b->inflight_lim_bytes = 1;
|
||||
struct INFLIGHT_PACKET* fresh = enqueue(80);
|
||||
struct ETCP_DGRAM* pkt = request();
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "Send scan: blocked=%u fresh=%u selected=%u", blocked->seq, fresh->seq,
|
||||
pkt && pkt->attempt ? pkt->attempt->seq : fresh->last_link ? fresh->seq : 0);
|
||||
CHECK(pkt && pkt->link == a && fresh->state == INFLIGHT_STATE_WAIT_ACK && blocked->state == INFLIGHT_STATE_WAIT_SEND);
|
||||
CHECK(blocked->attempt_count == 1 && !blocked->active_attempts);
|
||||
memory_pool_free(inst.pkt_pool, pkt); ack_all(); teardown();
|
||||
|
||||
setup(); fill(a, 1, 100); fill(b, 1, 100);
|
||||
a->data_rtt_us = 10000; b->data_rtt_us = 20000;
|
||||
conn->initialized = 0; test_clock_run_for(ua, 120); conn->initialized = 1;
|
||||
blocked = (struct INFLIGHT_PACKET*)queue_find_data_by_index(conn->input_send_q, &(uint32_t){1});
|
||||
struct INFLIGHT_PACKET* later = (struct INFLIGHT_PACKET*)queue_find_data_by_index(conn->input_send_q, &(uint32_t){2});
|
||||
CHECK(blocked && later && conn->input_send_q->head == &blocked->ll);
|
||||
b->inflight_lim_bytes = 1;
|
||||
pkt = request(); CHECK(pkt && pkt->link == a && later->last_link == a && blocked->state == INFLIGHT_STATE_WAIT_SEND);
|
||||
memory_pool_free(inst.pkt_pool, pkt); ack_all(); teardown();
|
||||
|
||||
setup(); fill(a, 1, 100); fresh = enqueue(80);
|
||||
conn->initialized = 0; test_clock_run_for(ua, 120); conn->initialized = 1;
|
||||
CHECK(conn->input_send_q->head == &fresh->ll);
|
||||
pkt = request(); CHECK(pkt && pkt->link == b && fresh->state == INFLIGHT_STATE_WAIT_SEND);
|
||||
memory_pool_free(inst.pkt_pool, pkt);
|
||||
pkt = request(); CHECK(pkt && fresh->state == INFLIGHT_STATE_WAIT_ACK);
|
||||
memory_pool_free(inst.pkt_pool, pkt); ack_all(); teardown();
|
||||
|
||||
setup(); fill(a, 256, 100);
|
||||
conn->initialized = 0; test_clock_run_for(ua, 120); conn->initialized = 1;
|
||||
b->inflight_lim_bytes = 1; fresh = enqueue(80);
|
||||
uint64_t started = get_time_us(); pkt = request();
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "Send scan: blocked_prefix=256 elapsed_us=%llu", (unsigned long long)(get_time_us() - started));
|
||||
CHECK(pkt && pkt->link == a && fresh->state == INFLIGHT_STATE_WAIT_ACK && conn->input_send_q->count == 256);
|
||||
memory_pool_free(inst.pkt_pool, pkt); ack_all(); teardown();
|
||||
}
|
||||
|
||||
static void queued_input_fragment(unsigned len) {
|
||||
struct ETCP_FRAGMENT* fragment = (struct ETCP_FRAGMENT*)queue_entry_new_from_pool(conn->io_pool); CHECK(fragment);
|
||||
fragment->ll.dgram = memory_pool_alloc(inst.data_pool); CHECK(fragment->ll.dgram);
|
||||
fragment->ll.dgram_pool = inst.data_pool; fragment->ll.len = len; memset(fragment->ll.dgram, 0x5a, len);
|
||||
conn->input_queue->callback_suspended = 1;
|
||||
CHECK(queue_data_put(conn->input_queue, &fragment->ll) == 0);
|
||||
}
|
||||
|
||||
/* Полностью заблокированная send_q не мешает подгрузке, но общий лимит и смена эпохи сохраняются. */
|
||||
static void send_queue_input_admission(void) {
|
||||
setup(); fill(a, 1, 100);
|
||||
conn->initialized = 0; test_clock_run_for(ua, 120); conn->initialized = 1;
|
||||
b->inflight_lim_bytes = 1; queued_input_fragment(80);
|
||||
CHECK(conn->input_queue->count == 1 && conn->input_send_q->count == 1);
|
||||
struct ETCP_DGRAM* pkt = request(); CHECK(pkt && pkt->link == a && pkt->payload_len == 80);
|
||||
CHECK(!conn->input_queue->count && conn->input_send_q->count == 1 && conn->input_wait_ack->count == 1);
|
||||
memory_pool_free(inst.pkt_pool, pkt); ack_all(); teardown();
|
||||
|
||||
setup(); fill(a, 1, 100);
|
||||
conn->initialized = 0; test_clock_run_for(ua, 120); conn->initialized = 1;
|
||||
b->inflight_lim_bytes = 1; conn->optimal_inflight = 100; queued_input_fragment(80);
|
||||
CHECK(!request() && conn->input_queue->count == 1 && conn->next_tx_id == 2 && conn->unacked_bytes == 100);
|
||||
ack(1); pkt = request(); CHECK(pkt && pkt->payload_len == 80 && !conn->input_queue->count);
|
||||
memory_pool_free(inst.pkt_pool, pkt); ack_all(); teardown();
|
||||
|
||||
setup(); fill(a, 1, 100);
|
||||
conn->initialized = 0; test_clock_run_for(ua, 120); conn->initialized = 1;
|
||||
b->inflight_lim_bytes = 1; queued_input_fragment(80); fail_tx_inflight = 1;
|
||||
uint32_t reset = conn->reset_count;
|
||||
CHECK(!request() && !fail_tx_inflight && conn->reset_count != reset && conn->reinit_pending);
|
||||
CHECK(!conn->unacked_bytes && !conn->active_attempts && !conn->input_send_q->count && !conn->input_queue->count);
|
||||
teardown();
|
||||
}
|
||||
|
||||
/* Поздняя копия и общий till не освобождают окно/не обучают модель другого канала. */
|
||||
static void independent_attempt_acks(void) {
|
||||
setup(); enable_models(); fill(a, 1, 100);
|
||||
@@ -1294,6 +1369,7 @@ int main(void) {
|
||||
config_limits, timer_failure, immediate_send, ack_without_data_pacing, bbr_delivery_clock, bbr_probe_window, tcp_initial_window,
|
||||
retransmission_timeout, pacing_rate_changes, pacing_timer_failure, retry_rotation, independent_attempt_acks,
|
||||
retry_waits_for_alternative, retry_alternative_lifecycle,
|
||||
send_queue_scan, send_queue_input_admission,
|
||||
receive_admission_and_path_acks, peer_window_queries, pacing_continuity, pacing_data_units, attempt_memory_limits,
|
||||
normalizer_rx_oom, normalizer_tx_oom, normalizer_callback_abort, reset_without_allocation, restart_allocation_failures,
|
||||
receiver_bandwidth_bounds, receiver_point_lifecycle, receiver_point_wire, receiver_point_truncated,
|
||||
|
||||
Reference in new issue
Block a user