golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/quic/acks_test.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build go1.21 6 7 package quic 8 9 import ( 10 "slices" 11 "testing" 12 "time" 13 ) 14 15 func TestAcksDisallowDuplicate(t *testing.T) { 16 // Don't process a packet that we've seen before. 17 acks := ackState{} 18 now := time.Now() 19 receive := []packetNumber{0, 1, 2, 4, 7, 6, 9} 20 seen := map[packetNumber]bool{} 21 for i, pnum := range receive { 22 acks.receive(now, appDataSpace, pnum, true) 23 seen[pnum] = true 24 for ppnum := packetNumber(0); ppnum < 11; ppnum++ { 25 if got, want := acks.shouldProcess(ppnum), !seen[ppnum]; got != want { 26 t.Fatalf("after receiving %v: acks.shouldProcess(%v) = %v, want %v", receive[:i+1], ppnum, got, want) 27 } 28 } 29 } 30 } 31 32 func TestAcksDisallowDiscardedAckRanges(t *testing.T) { 33 // Don't process a packet with a number in a discarded range. 34 acks := ackState{} 35 now := time.Now() 36 for pnum := packetNumber(0); ; pnum += 2 { 37 acks.receive(now, appDataSpace, pnum, true) 38 send, _ := acks.acksToSend(now) 39 for ppnum := packetNumber(0); ppnum < packetNumber(send.min()); ppnum++ { 40 if acks.shouldProcess(ppnum) { 41 t.Fatalf("after limiting ack ranges to %v: acks.shouldProcess(%v) (in discarded range) = true, want false", send, ppnum) 42 } 43 } 44 if send.min() > 10 { 45 break 46 } 47 } 48 } 49 50 func TestAcksSent(t *testing.T) { 51 type packet struct { 52 pnum packetNumber 53 ackEliciting bool 54 } 55 for _, test := range []struct { 56 name string 57 space numberSpace 58 59 // ackedPackets and packets are packets that we receive. 60 // After receiving all packets in ackedPackets, we send an ack. 61 // Then we receive the subsequent packets in packets. 62 ackedPackets []packet 63 packets []packet 64 65 wantDelay time.Duration 66 wantAcks rangeset[packetNumber] 67 }{{ 68 name: "no packets to ack", 69 space: initialSpace, 70 }, { 71 name: "non-ack-eliciting packets are not acked", 72 space: initialSpace, 73 packets: []packet{{ 74 pnum: 0, 75 ackEliciting: false, 76 }}, 77 }, { 78 name: "ack-eliciting Initial packets are acked immediately", 79 space: initialSpace, 80 packets: []packet{{ 81 pnum: 0, 82 ackEliciting: true, 83 }}, 84 wantAcks: rangeset[packetNumber]{{0, 1}}, 85 wantDelay: 0, 86 }, { 87 name: "ack-eliciting Handshake packets are acked immediately", 88 space: handshakeSpace, 89 packets: []packet{{ 90 pnum: 0, 91 ackEliciting: true, 92 }}, 93 wantAcks: rangeset[packetNumber]{{0, 1}}, 94 wantDelay: 0, 95 }, { 96 name: "ack-eliciting AppData packets are acked after max_ack_delay", 97 space: appDataSpace, 98 packets: []packet{{ 99 pnum: 0, 100 ackEliciting: true, 101 }}, 102 wantAcks: rangeset[packetNumber]{{0, 1}}, 103 wantDelay: maxAckDelay - timerGranularity, 104 }, { 105 name: "reordered ack-eliciting packets are acked immediately", 106 space: appDataSpace, 107 ackedPackets: []packet{{ 108 pnum: 1, 109 ackEliciting: true, 110 }}, 111 packets: []packet{{ 112 pnum: 0, 113 ackEliciting: true, 114 }}, 115 wantAcks: rangeset[packetNumber]{{0, 2}}, 116 wantDelay: 0, 117 }, { 118 name: "gaps in ack-eliciting packets are acked immediately", 119 space: appDataSpace, 120 packets: []packet{{ 121 pnum: 1, 122 ackEliciting: true, 123 }}, 124 wantAcks: rangeset[packetNumber]{{1, 2}}, 125 wantDelay: 0, 126 }, { 127 name: "reordered non-ack-eliciting packets are not acked immediately", 128 space: appDataSpace, 129 ackedPackets: []packet{{ 130 pnum: 1, 131 ackEliciting: true, 132 }}, 133 packets: []packet{{ 134 pnum: 2, 135 ackEliciting: true, 136 }, { 137 pnum: 0, 138 ackEliciting: false, 139 }, { 140 pnum: 4, 141 ackEliciting: false, 142 }}, 143 wantAcks: rangeset[packetNumber]{{0, 3}, {4, 5}}, 144 wantDelay: maxAckDelay - timerGranularity, 145 }, { 146 name: "immediate ack after two ack-eliciting packets are received", 147 space: appDataSpace, 148 packets: []packet{{ 149 pnum: 0, 150 ackEliciting: true, 151 }, { 152 pnum: 1, 153 ackEliciting: true, 154 }}, 155 wantAcks: rangeset[packetNumber]{{0, 2}}, 156 wantDelay: 0, 157 }} { 158 t.Run(test.name, func(t *testing.T) { 159 acks := ackState{} 160 start := time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC) 161 for _, p := range test.ackedPackets { 162 t.Logf("receive %v.%v, ack-eliciting=%v", test.space, p.pnum, p.ackEliciting) 163 acks.receive(start, test.space, p.pnum, p.ackEliciting) 164 } 165 t.Logf("send an ACK frame") 166 acks.sentAck() 167 for _, p := range test.packets { 168 t.Logf("receive %v.%v, ack-eliciting=%v", test.space, p.pnum, p.ackEliciting) 169 acks.receive(start, test.space, p.pnum, p.ackEliciting) 170 } 171 switch { 172 case len(test.wantAcks) == 0: 173 // No ACK should be sent, even well after max_ack_delay. 174 if acks.shouldSendAck(start.Add(10 * maxAckDelay)) { 175 t.Errorf("acks.shouldSendAck(T+10*max_ack_delay) = true, want false") 176 } 177 case test.wantDelay > 0: 178 // No ACK should be sent before a delay. 179 if acks.shouldSendAck(start.Add(test.wantDelay - 1)) { 180 t.Errorf("acks.shouldSendAck(T+%v-1ns) = true, want false", test.wantDelay) 181 } 182 fallthrough 183 default: 184 // ACK should be sent after a delay. 185 if !acks.shouldSendAck(start.Add(test.wantDelay)) { 186 t.Errorf("acks.shouldSendAck(T+%v) = false, want true", test.wantDelay) 187 } 188 } 189 // acksToSend always reports the available packets that can be acked, 190 // and the amount of time that has passed since the most recent acked 191 // packet was received. 192 for _, delay := range []time.Duration{ 193 0, 194 test.wantDelay, 195 test.wantDelay + 1, 196 } { 197 gotNums, gotDelay := acks.acksToSend(start.Add(delay)) 198 wantDelay := delay 199 if len(gotNums) == 0 { 200 wantDelay = 0 201 } 202 if !slices.Equal(gotNums, test.wantAcks) || gotDelay != wantDelay { 203 t.Errorf("acks.acksToSend(T+%v) = %v, %v; want %v, %v", delay, gotNums, gotDelay, test.wantAcks, wantDelay) 204 } 205 } 206 }) 207 } 208 } 209 210 func TestAcksDiscardAfterAck(t *testing.T) { 211 acks := ackState{} 212 now := time.Now() 213 acks.receive(now, appDataSpace, 0, true) 214 acks.receive(now, appDataSpace, 2, true) 215 acks.receive(now, appDataSpace, 4, true) 216 acks.receive(now, appDataSpace, 5, true) 217 acks.receive(now, appDataSpace, 6, true) 218 acks.handleAck(6) // discards all ranges prior to the one containing packet 6 219 acks.receive(now, appDataSpace, 7, true) 220 got, _ := acks.acksToSend(now) 221 if len(got) != 1 { 222 t.Errorf("acks.acksToSend contains ranges prior to last acknowledged ack; got %v, want 1 range", got) 223 } 224 } 225 226 func TestAcksLargestSeen(t *testing.T) { 227 acks := ackState{} 228 now := time.Now() 229 acks.receive(now, appDataSpace, 0, true) 230 acks.receive(now, appDataSpace, 4, true) 231 acks.receive(now, appDataSpace, 1, true) 232 if got, want := acks.largestSeen(), packetNumber(4); got != want { 233 t.Errorf("acks.largestSeen() = %v, want %v", got, want) 234 } 235 }