packet_number_generator_test.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. package ackhandler
  2. import (
  3. "math"
  4. "github.com/lucas-clemente/quic-go/internal/protocol"
  5. "github.com/lucas-clemente/quic-go/internal/wire"
  6. . "github.com/onsi/ginkgo"
  7. . "github.com/onsi/gomega"
  8. )
  9. var _ = Describe("Packet Number Generator", func() {
  10. var png *packetNumberGenerator
  11. BeforeEach(func() {
  12. png = newPacketNumberGenerator(1, 100)
  13. })
  14. It("can be initialized to return any first packet number", func() {
  15. png = newPacketNumberGenerator(12345, 100)
  16. Expect(png.Pop()).To(Equal(protocol.PacketNumber(12345)))
  17. })
  18. It("gets 1 as the first packet number", func() {
  19. num := png.Pop()
  20. Expect(num).To(Equal(protocol.PacketNumber(1)))
  21. })
  22. It("allows peeking", func() {
  23. png.nextToSkip = 1000
  24. Expect(png.Peek()).To(Equal(protocol.PacketNumber(1)))
  25. Expect(png.Peek()).To(Equal(protocol.PacketNumber(1)))
  26. num := png.Pop()
  27. Expect(num).To(Equal(protocol.PacketNumber(1)))
  28. Expect(png.Peek()).To(Equal(protocol.PacketNumber(2)))
  29. Expect(png.Peek()).To(Equal(protocol.PacketNumber(2)))
  30. })
  31. It("skips a packet number", func() {
  32. var last protocol.PacketNumber
  33. var skipped bool
  34. for i := 0; i < 1000; i++ {
  35. num := png.Pop()
  36. if num > last+1 {
  37. skipped = true
  38. break
  39. }
  40. last = num
  41. }
  42. Expect(skipped).To(BeTrue())
  43. })
  44. It("skips a specific packet number", func() {
  45. png.nextToSkip = 2
  46. num := png.Pop()
  47. Expect(num).To(Equal(protocol.PacketNumber(1)))
  48. Expect(png.Peek()).To(Equal(protocol.PacketNumber(3)))
  49. num = png.Pop()
  50. Expect(num).To(Equal(protocol.PacketNumber(3)))
  51. })
  52. It("generates a new packet number to skip", func() {
  53. png.next = 100
  54. png.averagePeriod = 100
  55. rep := 5000
  56. var sum protocol.PacketNumber
  57. for i := 0; i < rep; i++ {
  58. png.generateNewSkip()
  59. Expect(png.nextToSkip).ToNot(Equal(protocol.PacketNumber(101)))
  60. sum += png.nextToSkip
  61. }
  62. average := sum / protocol.PacketNumber(rep)
  63. Expect(average).To(BeNumerically("==", protocol.PacketNumber(200), 4))
  64. })
  65. It("uses random numbers", func() {
  66. var smallest uint16 = math.MaxUint16
  67. var largest uint16
  68. var sum uint64
  69. rep := 10000
  70. for i := 0; i < rep; i++ {
  71. num := png.getRandomNumber()
  72. sum += uint64(num)
  73. if num > largest {
  74. largest = num
  75. }
  76. if num < smallest {
  77. smallest = num
  78. }
  79. }
  80. Expect(smallest).To(BeNumerically("<", 300))
  81. Expect(largest).To(BeNumerically(">", math.MaxUint16-300))
  82. Expect(sum / uint64(rep)).To(BeNumerically("==", uint64(math.MaxUint16/2), 1000))
  83. })
  84. It("validates ACK frames", func() {
  85. var skipped []protocol.PacketNumber
  86. var lastPN protocol.PacketNumber
  87. for len(skipped) < 3 {
  88. if png.Peek() > lastPN+1 {
  89. skipped = append(skipped, lastPN+1)
  90. }
  91. lastPN = png.Pop()
  92. }
  93. invalidACK := &wire.AckFrame{
  94. AckRanges: []wire.AckRange{{Smallest: 1, Largest: lastPN}},
  95. }
  96. Expect(png.Validate(invalidACK)).To(BeFalse())
  97. validACK1 := &wire.AckFrame{
  98. AckRanges: []wire.AckRange{{Smallest: 1, Largest: skipped[0] - 1}},
  99. }
  100. Expect(png.Validate(validACK1)).To(BeTrue())
  101. validACK2 := &wire.AckFrame{
  102. AckRanges: []wire.AckRange{
  103. {Smallest: 1, Largest: skipped[0] - 1},
  104. {Smallest: skipped[0] + 1, Largest: skipped[1] - 1},
  105. {Smallest: skipped[1] + 1, Largest: skipped[2] - 1},
  106. {Smallest: skipped[2] + 1, Largest: skipped[2] + 100},
  107. },
  108. }
  109. Expect(png.Validate(validACK2)).To(BeTrue())
  110. })
  111. It("tracks a maximum number of protocol.MaxTrackedSkippedPackets packets", func() {
  112. var skipped []protocol.PacketNumber
  113. var lastPN protocol.PacketNumber
  114. for len(skipped) < protocol.MaxTrackedSkippedPackets+3 {
  115. if png.Peek() > lastPN+1 {
  116. skipped = append(skipped, lastPN+1)
  117. }
  118. lastPN = png.Pop()
  119. Expect(len(png.history)).To(BeNumerically("<=", protocol.MaxTrackedSkippedPackets))
  120. }
  121. Expect(len(png.history)).To(Equal(protocol.MaxTrackedSkippedPackets))
  122. })
  123. })