github.com/tumi8/quic-go@v0.37.4-tum/noninternal/ackhandler/received_packet_history_test.go (about) 1 package ackhandler 2 3 import ( 4 "fmt" 5 "math/rand" 6 "sort" 7 8 "github.com/tumi8/quic-go/noninternal/protocol" 9 "github.com/tumi8/quic-go/noninternal/wire" 10 . "github.com/onsi/ginkgo/v2" 11 . "github.com/onsi/gomega" 12 ) 13 14 var _ = Describe("receivedPacketHistory", func() { 15 var hist *receivedPacketHistory 16 17 BeforeEach(func() { 18 hist = newReceivedPacketHistory() 19 }) 20 21 Context("ranges", func() { 22 It("adds the first packet", func() { 23 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 24 Expect(hist.ranges.Len()).To(Equal(1)) 25 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 4, End: 4})) 26 }) 27 28 It("doesn't care about duplicate packets", func() { 29 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 30 Expect(hist.ReceivedPacket(4)).To(BeFalse()) 31 Expect(hist.ranges.Len()).To(Equal(1)) 32 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 4, End: 4})) 33 }) 34 35 It("adds a few consecutive packets", func() { 36 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 37 Expect(hist.ReceivedPacket(5)).To(BeTrue()) 38 Expect(hist.ReceivedPacket(6)).To(BeTrue()) 39 Expect(hist.ranges.Len()).To(Equal(1)) 40 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 4, End: 6})) 41 }) 42 43 It("doesn't care about a duplicate packet contained in an existing range", func() { 44 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 45 Expect(hist.ReceivedPacket(5)).To(BeTrue()) 46 Expect(hist.ReceivedPacket(6)).To(BeTrue()) 47 Expect(hist.ReceivedPacket(5)).To(BeFalse()) 48 Expect(hist.ranges.Len()).To(Equal(1)) 49 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 4, End: 6})) 50 }) 51 52 It("extends a range at the front", func() { 53 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 54 Expect(hist.ReceivedPacket(3)).To(BeTrue()) 55 Expect(hist.ranges.Len()).To(Equal(1)) 56 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 3, End: 4})) 57 }) 58 59 It("creates a new range when a packet is lost", func() { 60 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 61 Expect(hist.ReceivedPacket(6)).To(BeTrue()) 62 Expect(hist.ranges.Len()).To(Equal(2)) 63 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 4, End: 4})) 64 Expect(hist.ranges.Back().Value).To(Equal(interval{Start: 6, End: 6})) 65 }) 66 67 It("creates a new range in between two ranges", func() { 68 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 69 Expect(hist.ReceivedPacket(10)).To(BeTrue()) 70 Expect(hist.ranges.Len()).To(Equal(2)) 71 Expect(hist.ReceivedPacket(7)).To(BeTrue()) 72 Expect(hist.ranges.Len()).To(Equal(3)) 73 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 4, End: 4})) 74 Expect(hist.ranges.Front().Next().Value).To(Equal(interval{Start: 7, End: 7})) 75 Expect(hist.ranges.Back().Value).To(Equal(interval{Start: 10, End: 10})) 76 }) 77 78 It("creates a new range before an existing range for a belated packet", func() { 79 Expect(hist.ReceivedPacket(6)).To(BeTrue()) 80 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 81 Expect(hist.ranges.Len()).To(Equal(2)) 82 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 4, End: 4})) 83 Expect(hist.ranges.Back().Value).To(Equal(interval{Start: 6, End: 6})) 84 }) 85 86 It("extends a previous range at the end", func() { 87 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 88 Expect(hist.ReceivedPacket(7)).To(BeTrue()) 89 Expect(hist.ReceivedPacket(5)).To(BeTrue()) 90 Expect(hist.ranges.Len()).To(Equal(2)) 91 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 4, End: 5})) 92 Expect(hist.ranges.Back().Value).To(Equal(interval{Start: 7, End: 7})) 93 }) 94 95 It("extends a range at the front", func() { 96 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 97 Expect(hist.ReceivedPacket(7)).To(BeTrue()) 98 Expect(hist.ReceivedPacket(6)).To(BeTrue()) 99 Expect(hist.ranges.Len()).To(Equal(2)) 100 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 4, End: 4})) 101 Expect(hist.ranges.Back().Value).To(Equal(interval{Start: 6, End: 7})) 102 }) 103 104 It("closes a range", func() { 105 Expect(hist.ReceivedPacket(6)).To(BeTrue()) 106 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 107 Expect(hist.ranges.Len()).To(Equal(2)) 108 Expect(hist.ReceivedPacket(5)).To(BeTrue()) 109 Expect(hist.ranges.Len()).To(Equal(1)) 110 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 4, End: 6})) 111 }) 112 113 It("closes a range in the middle", func() { 114 Expect(hist.ReceivedPacket(1)).To(BeTrue()) 115 Expect(hist.ReceivedPacket(10)).To(BeTrue()) 116 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 117 Expect(hist.ReceivedPacket(6)).To(BeTrue()) 118 Expect(hist.ranges.Len()).To(Equal(4)) 119 Expect(hist.ReceivedPacket(5)).To(BeTrue()) 120 Expect(hist.ranges.Len()).To(Equal(3)) 121 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 1, End: 1})) 122 Expect(hist.ranges.Front().Next().Value).To(Equal(interval{Start: 4, End: 6})) 123 Expect(hist.ranges.Back().Value).To(Equal(interval{Start: 10, End: 10})) 124 }) 125 }) 126 127 Context("deleting", func() { 128 It("does nothing when the history is empty", func() { 129 hist.DeleteBelow(5) 130 Expect(hist.ranges.Len()).To(BeZero()) 131 }) 132 133 It("deletes a range", func() { 134 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 135 Expect(hist.ReceivedPacket(5)).To(BeTrue()) 136 Expect(hist.ReceivedPacket(10)).To(BeTrue()) 137 hist.DeleteBelow(6) 138 Expect(hist.ranges.Len()).To(Equal(1)) 139 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 10, End: 10})) 140 }) 141 142 It("deletes multiple ranges", func() { 143 Expect(hist.ReceivedPacket(1)).To(BeTrue()) 144 Expect(hist.ReceivedPacket(5)).To(BeTrue()) 145 Expect(hist.ReceivedPacket(10)).To(BeTrue()) 146 hist.DeleteBelow(8) 147 Expect(hist.ranges.Len()).To(Equal(1)) 148 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 10, End: 10})) 149 }) 150 151 It("adjusts a range, if packets are delete from an existing range", func() { 152 Expect(hist.ReceivedPacket(3)).To(BeTrue()) 153 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 154 Expect(hist.ReceivedPacket(5)).To(BeTrue()) 155 Expect(hist.ReceivedPacket(6)).To(BeTrue()) 156 Expect(hist.ReceivedPacket(7)).To(BeTrue()) 157 hist.DeleteBelow(5) 158 Expect(hist.ranges.Len()).To(Equal(1)) 159 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 5, End: 7})) 160 }) 161 162 It("adjusts a range, if only one packet remains in the range", func() { 163 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 164 Expect(hist.ReceivedPacket(5)).To(BeTrue()) 165 Expect(hist.ReceivedPacket(10)).To(BeTrue()) 166 hist.DeleteBelow(5) 167 Expect(hist.ranges.Len()).To(Equal(2)) 168 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 5, End: 5})) 169 Expect(hist.ranges.Back().Value).To(Equal(interval{Start: 10, End: 10})) 170 }) 171 172 It("keeps a one-packet range, if deleting up to the packet directly below", func() { 173 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 174 hist.DeleteBelow(4) 175 Expect(hist.ranges.Len()).To(Equal(1)) 176 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 4, End: 4})) 177 }) 178 179 It("doesn't add delayed packets below deleted ranges", func() { 180 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 181 Expect(hist.ReceivedPacket(5)).To(BeTrue()) 182 Expect(hist.ReceivedPacket(6)).To(BeTrue()) 183 hist.DeleteBelow(5) 184 Expect(hist.ranges.Len()).To(Equal(1)) 185 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 5, End: 6})) 186 Expect(hist.ReceivedPacket(2)).To(BeFalse()) 187 Expect(hist.ranges.Len()).To(Equal(1)) 188 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 5, End: 6})) 189 }) 190 191 It("doesn't create more than MaxNumAckRanges ranges", func() { 192 for i := protocol.PacketNumber(0); i < protocol.MaxNumAckRanges; i++ { 193 Expect(hist.ReceivedPacket(2 * i)).To(BeTrue()) 194 } 195 Expect(hist.ranges.Len()).To(Equal(protocol.MaxNumAckRanges)) 196 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 0, End: 0})) 197 hist.ReceivedPacket(2*protocol.MaxNumAckRanges + 1000) 198 // check that the oldest ACK range was deleted 199 Expect(hist.ranges.Len()).To(Equal(protocol.MaxNumAckRanges)) 200 Expect(hist.ranges.Front().Value).To(Equal(interval{Start: 2, End: 2})) 201 }) 202 }) 203 204 Context("ACK range export", func() { 205 It("returns nil if there are no ranges", func() { 206 Expect(hist.AppendAckRanges(nil)).To(BeEmpty()) 207 }) 208 209 It("gets a single ACK range", func() { 210 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 211 Expect(hist.ReceivedPacket(5)).To(BeTrue()) 212 ackRanges := hist.AppendAckRanges(nil) 213 Expect(ackRanges).To(HaveLen(1)) 214 Expect(ackRanges[0]).To(Equal(wire.AckRange{Smallest: 4, Largest: 5})) 215 }) 216 217 It("appends ACK ranges", func() { 218 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 219 Expect(hist.ReceivedPacket(5)).To(BeTrue()) 220 ackRanges := hist.AppendAckRanges([]wire.AckRange{{Smallest: 1, Largest: 2}}) 221 Expect(ackRanges).To(HaveLen(2)) 222 Expect(ackRanges[0]).To(Equal(wire.AckRange{Smallest: 1, Largest: 2})) 223 Expect(ackRanges[1]).To(Equal(wire.AckRange{Smallest: 4, Largest: 5})) 224 }) 225 226 It("gets multiple ACK ranges", func() { 227 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 228 Expect(hist.ReceivedPacket(5)).To(BeTrue()) 229 Expect(hist.ReceivedPacket(6)).To(BeTrue()) 230 Expect(hist.ReceivedPacket(1)).To(BeTrue()) 231 Expect(hist.ReceivedPacket(11)).To(BeTrue()) 232 Expect(hist.ReceivedPacket(10)).To(BeTrue()) 233 Expect(hist.ReceivedPacket(2)).To(BeTrue()) 234 ackRanges := hist.AppendAckRanges(nil) 235 Expect(ackRanges).To(HaveLen(3)) 236 Expect(ackRanges[0]).To(Equal(wire.AckRange{Smallest: 10, Largest: 11})) 237 Expect(ackRanges[1]).To(Equal(wire.AckRange{Smallest: 4, Largest: 6})) 238 Expect(ackRanges[2]).To(Equal(wire.AckRange{Smallest: 1, Largest: 2})) 239 }) 240 }) 241 242 Context("Getting the highest ACK range", func() { 243 It("returns the zero value if there are no ranges", func() { 244 Expect(hist.GetHighestAckRange()).To(BeZero()) 245 }) 246 247 It("gets a single ACK range", func() { 248 Expect(hist.ReceivedPacket(4)).To(BeTrue()) 249 Expect(hist.ReceivedPacket(5)).To(BeTrue()) 250 Expect(hist.GetHighestAckRange()).To(Equal(wire.AckRange{Smallest: 4, Largest: 5})) 251 }) 252 253 It("gets the highest of multiple ACK ranges", func() { 254 Expect(hist.ReceivedPacket(3)).To(BeTrue()) 255 Expect(hist.ReceivedPacket(6)).To(BeTrue()) 256 Expect(hist.ReceivedPacket(7)).To(BeTrue()) 257 Expect(hist.GetHighestAckRange()).To(Equal(wire.AckRange{Smallest: 6, Largest: 7})) 258 }) 259 }) 260 261 Context("duplicate detection", func() { 262 It("doesn't declare the first packet a duplicate", func() { 263 Expect(hist.IsPotentiallyDuplicate(5)).To(BeFalse()) 264 }) 265 266 It("detects a duplicate in a range", func() { 267 hist.ReceivedPacket(4) 268 hist.ReceivedPacket(5) 269 hist.ReceivedPacket(6) 270 Expect(hist.IsPotentiallyDuplicate(3)).To(BeFalse()) 271 Expect(hist.IsPotentiallyDuplicate(4)).To(BeTrue()) 272 Expect(hist.IsPotentiallyDuplicate(5)).To(BeTrue()) 273 Expect(hist.IsPotentiallyDuplicate(6)).To(BeTrue()) 274 Expect(hist.IsPotentiallyDuplicate(7)).To(BeFalse()) 275 }) 276 277 It("detects a duplicate in multiple ranges", func() { 278 hist.ReceivedPacket(4) 279 hist.ReceivedPacket(5) 280 hist.ReceivedPacket(8) 281 hist.ReceivedPacket(9) 282 Expect(hist.IsPotentiallyDuplicate(3)).To(BeFalse()) 283 Expect(hist.IsPotentiallyDuplicate(4)).To(BeTrue()) 284 Expect(hist.IsPotentiallyDuplicate(5)).To(BeTrue()) 285 Expect(hist.IsPotentiallyDuplicate(6)).To(BeFalse()) 286 Expect(hist.IsPotentiallyDuplicate(7)).To(BeFalse()) 287 Expect(hist.IsPotentiallyDuplicate(8)).To(BeTrue()) 288 Expect(hist.IsPotentiallyDuplicate(9)).To(BeTrue()) 289 Expect(hist.IsPotentiallyDuplicate(10)).To(BeFalse()) 290 }) 291 292 It("says a packet is a potentially duplicate if the ranges were already deleted", func() { 293 hist.ReceivedPacket(4) 294 hist.ReceivedPacket(5) 295 hist.ReceivedPacket(8) 296 hist.ReceivedPacket(9) 297 hist.ReceivedPacket(11) 298 hist.DeleteBelow(8) 299 Expect(hist.IsPotentiallyDuplicate(3)).To(BeTrue()) 300 Expect(hist.IsPotentiallyDuplicate(4)).To(BeTrue()) 301 Expect(hist.IsPotentiallyDuplicate(5)).To(BeTrue()) 302 Expect(hist.IsPotentiallyDuplicate(6)).To(BeTrue()) 303 Expect(hist.IsPotentiallyDuplicate(7)).To(BeTrue()) 304 Expect(hist.IsPotentiallyDuplicate(8)).To(BeTrue()) 305 Expect(hist.IsPotentiallyDuplicate(9)).To(BeTrue()) 306 Expect(hist.IsPotentiallyDuplicate(10)).To(BeFalse()) 307 Expect(hist.IsPotentiallyDuplicate(11)).To(BeTrue()) 308 Expect(hist.IsPotentiallyDuplicate(12)).To(BeFalse()) 309 }) 310 }) 311 312 Context("randomized receiving", func() { 313 It("receiving packets in a random order, with gaps", func() { 314 packets := make(map[protocol.PacketNumber]int) 315 // Make sure we never end up with more than protocol.MaxNumAckRanges ACK ranges, even 316 // when we're receiving packets in a random order. 317 const num = 2 * protocol.MaxNumAckRanges 318 numLostPackets := rand.Intn(protocol.MaxNumAckRanges) 319 numRcvdPackets := num - numLostPackets 320 321 for i := 0; i < num; i++ { 322 packets[protocol.PacketNumber(i)] = 0 323 } 324 lostPackets := make([]protocol.PacketNumber, 0, numLostPackets) 325 for len(lostPackets) < numLostPackets { 326 p := protocol.PacketNumber(rand.Intn(num)) 327 if _, ok := packets[p]; ok { 328 lostPackets = append(lostPackets, p) 329 delete(packets, p) 330 } 331 } 332 sort.Slice(lostPackets, func(i, j int) bool { return lostPackets[i] < lostPackets[j] }) 333 fmt.Fprintf(GinkgoWriter, "Losing packets: %v\n", lostPackets) 334 335 ordered := make([]protocol.PacketNumber, 0, numRcvdPackets) 336 for p := range packets { 337 ordered = append(ordered, p) 338 } 339 rand.Shuffle(len(ordered), func(i, j int) { ordered[i], ordered[j] = ordered[j], ordered[i] }) 340 341 fmt.Fprintf(GinkgoWriter, "Receiving packets: %v\n", ordered) 342 for i, p := range ordered { 343 Expect(hist.ReceivedPacket(p)).To(BeTrue()) 344 // sometimes receive a duplicate 345 if i > 0 && rand.Int()%5 == 0 { 346 Expect(hist.ReceivedPacket(ordered[rand.Intn(i)])).To(BeFalse()) 347 } 348 } 349 var counter int 350 ackRanges := hist.AppendAckRanges(nil) 351 fmt.Fprintf(GinkgoWriter, "ACK ranges: %v\n", ackRanges) 352 Expect(len(ackRanges)).To(BeNumerically("<=", numLostPackets+1)) 353 for _, ackRange := range ackRanges { 354 for p := ackRange.Smallest; p <= ackRange.Largest; p++ { 355 counter++ 356 Expect(packets).To(HaveKey(p)) 357 } 358 } 359 Expect(counter).To(Equal(numRcvdPackets)) 360 }) 361 }) 362 })