github.com/danielpfeifer02/quic-go-prio-packs@v0.41.0-28/internal/utils/rtt_stats_test.go (about) 1 package utils 2 3 import ( 4 "time" 5 6 "github.com/danielpfeifer02/quic-go-prio-packs/internal/protocol" 7 8 . "github.com/onsi/ginkgo/v2" 9 . "github.com/onsi/gomega" 10 ) 11 12 var _ = Describe("RTT stats", func() { 13 var rttStats *RTTStats 14 15 BeforeEach(func() { 16 rttStats = NewRTTStats() 17 }) 18 19 It("DefaultsBeforeUpdate", func() { 20 Expect(rttStats.MinRTT()).To(Equal(time.Duration(0))) 21 Expect(rttStats.SmoothedRTT()).To(Equal(time.Duration(0))) 22 }) 23 24 It("SmoothedRTT", func() { 25 // Verify that ack_delay is ignored in the first measurement. 26 rttStats.UpdateRTT((300 * time.Millisecond), (100 * time.Millisecond), time.Time{}) 27 Expect(rttStats.LatestRTT()).To(Equal((300 * time.Millisecond))) 28 Expect(rttStats.SmoothedRTT()).To(Equal((300 * time.Millisecond))) 29 // Verify that Smoothed RTT includes max ack delay if it's reasonable. 30 rttStats.UpdateRTT((350 * time.Millisecond), (50 * time.Millisecond), time.Time{}) 31 Expect(rttStats.LatestRTT()).To(Equal((300 * time.Millisecond))) 32 Expect(rttStats.SmoothedRTT()).To(Equal((300 * time.Millisecond))) 33 // Verify that large erroneous ack_delay does not change Smoothed RTT. 34 rttStats.UpdateRTT((200 * time.Millisecond), (300 * time.Millisecond), time.Time{}) 35 Expect(rttStats.LatestRTT()).To(Equal((200 * time.Millisecond))) 36 Expect(rttStats.SmoothedRTT()).To(Equal((287500 * time.Microsecond))) 37 }) 38 39 It("MinRTT", func() { 40 rttStats.UpdateRTT((200 * time.Millisecond), 0, time.Time{}) 41 Expect(rttStats.MinRTT()).To(Equal((200 * time.Millisecond))) 42 rttStats.UpdateRTT((10 * time.Millisecond), 0, time.Time{}.Add((10 * time.Millisecond))) 43 Expect(rttStats.MinRTT()).To(Equal((10 * time.Millisecond))) 44 rttStats.UpdateRTT((50 * time.Millisecond), 0, time.Time{}.Add((20 * time.Millisecond))) 45 Expect(rttStats.MinRTT()).To(Equal((10 * time.Millisecond))) 46 rttStats.UpdateRTT((50 * time.Millisecond), 0, time.Time{}.Add((30 * time.Millisecond))) 47 Expect(rttStats.MinRTT()).To(Equal((10 * time.Millisecond))) 48 rttStats.UpdateRTT((50 * time.Millisecond), 0, time.Time{}.Add((40 * time.Millisecond))) 49 Expect(rttStats.MinRTT()).To(Equal((10 * time.Millisecond))) 50 // Verify that ack_delay does not go into recording of MinRTT_. 51 rttStats.UpdateRTT((7 * time.Millisecond), (2 * time.Millisecond), time.Time{}.Add((50 * time.Millisecond))) 52 Expect(rttStats.MinRTT()).To(Equal((7 * time.Millisecond))) 53 }) 54 55 It("MaxAckDelay", func() { 56 rttStats.SetMaxAckDelay(42 * time.Minute) 57 Expect(rttStats.MaxAckDelay()).To(Equal(42 * time.Minute)) 58 }) 59 60 It("computes the PTO", func() { 61 maxAckDelay := 42 * time.Minute 62 rttStats.SetMaxAckDelay(maxAckDelay) 63 rtt := time.Second 64 rttStats.UpdateRTT(rtt, 0, time.Time{}) 65 Expect(rttStats.SmoothedRTT()).To(Equal(rtt)) 66 Expect(rttStats.MeanDeviation()).To(Equal(rtt / 2)) 67 Expect(rttStats.PTO(false)).To(Equal(rtt + 4*(rtt/2))) 68 Expect(rttStats.PTO(true)).To(Equal(rtt + 4*(rtt/2) + maxAckDelay)) 69 }) 70 71 It("uses the granularity for computing the PTO for short RTTs", func() { 72 rtt := time.Microsecond 73 rttStats.UpdateRTT(rtt, 0, time.Time{}) 74 Expect(rttStats.PTO(true)).To(Equal(rtt + protocol.TimerGranularity)) 75 }) 76 77 It("ExpireSmoothedMetrics", func() { 78 initialRtt := (10 * time.Millisecond) 79 rttStats.UpdateRTT(initialRtt, 0, time.Time{}) 80 Expect(rttStats.MinRTT()).To(Equal(initialRtt)) 81 Expect(rttStats.SmoothedRTT()).To(Equal(initialRtt)) 82 83 Expect(rttStats.MeanDeviation()).To(Equal(initialRtt / 2)) 84 85 // Update once with a 20ms RTT. 86 doubledRtt := initialRtt * (2) 87 rttStats.UpdateRTT(doubledRtt, 0, time.Time{}) 88 Expect(rttStats.SmoothedRTT()).To(Equal(time.Duration(float32(initialRtt) * 1.125))) 89 90 // Expire the smoothed metrics, increasing smoothed rtt and mean deviation. 91 rttStats.ExpireSmoothedMetrics() 92 Expect(rttStats.SmoothedRTT()).To(Equal(doubledRtt)) 93 Expect(rttStats.MeanDeviation()).To(Equal(time.Duration(float32(initialRtt) * 0.875))) 94 95 // Now go back down to 5ms and expire the smoothed metrics, and ensure the 96 // mean deviation increases to 15ms. 97 halfRtt := initialRtt / 2 98 rttStats.UpdateRTT(halfRtt, 0, time.Time{}) 99 Expect(doubledRtt).To(BeNumerically(">", rttStats.SmoothedRTT())) 100 Expect(initialRtt).To(BeNumerically("<", rttStats.MeanDeviation())) 101 }) 102 103 It("UpdateRTTWithBadSendDeltas", func() { 104 // Make sure we ignore bad RTTs. 105 // base::test::MockLog log; 106 107 initialRtt := (10 * time.Millisecond) 108 rttStats.UpdateRTT(initialRtt, 0, time.Time{}) 109 Expect(rttStats.MinRTT()).To(Equal(initialRtt)) 110 Expect(rttStats.SmoothedRTT()).To(Equal(initialRtt)) 111 112 badSendDeltas := []time.Duration{ 113 0, 114 InfDuration, 115 -1000 * time.Microsecond, 116 } 117 // log.StartCapturingLogs(); 118 119 for _, badSendDelta := range badSendDeltas { 120 // SCOPED_TRACE(Message() << "bad_send_delta = " 121 // << bad_send_delta.ToMicroseconds()); 122 // EXPECT_CALL(log, Log(LOG_WARNING, _, _, _, HasSubstr("Ignoring"))); 123 rttStats.UpdateRTT(badSendDelta, 0, time.Time{}) 124 Expect(rttStats.MinRTT()).To(Equal(initialRtt)) 125 Expect(rttStats.SmoothedRTT()).To(Equal(initialRtt)) 126 } 127 }) 128 129 It("ResetAfterConnectionMigrations", func() { 130 rttStats.UpdateRTT(200*time.Millisecond, 0, time.Time{}) 131 Expect(rttStats.LatestRTT()).To(Equal((200 * time.Millisecond))) 132 Expect(rttStats.SmoothedRTT()).To(Equal((200 * time.Millisecond))) 133 Expect(rttStats.MinRTT()).To(Equal((200 * time.Millisecond))) 134 rttStats.UpdateRTT((300 * time.Millisecond), (100 * time.Millisecond), time.Time{}) 135 Expect(rttStats.LatestRTT()).To(Equal((200 * time.Millisecond))) 136 Expect(rttStats.SmoothedRTT()).To(Equal((200 * time.Millisecond))) 137 Expect(rttStats.MinRTT()).To(Equal((200 * time.Millisecond))) 138 139 // Reset rtt stats on connection migrations. 140 rttStats.OnConnectionMigration() 141 Expect(rttStats.LatestRTT()).To(Equal(time.Duration(0))) 142 Expect(rttStats.SmoothedRTT()).To(Equal(time.Duration(0))) 143 Expect(rttStats.MinRTT()).To(Equal(time.Duration(0))) 144 }) 145 146 It("restores the RTT", func() { 147 rttStats.SetInitialRTT(10 * time.Second) 148 Expect(rttStats.LatestRTT()).To(Equal(10 * time.Second)) 149 Expect(rttStats.SmoothedRTT()).To(Equal(10 * time.Second)) 150 Expect(rttStats.MeanDeviation()).To(BeZero()) 151 // update the RTT and make sure that the initial value is immediately forgotten 152 rttStats.UpdateRTT(200*time.Millisecond, 0, time.Time{}) 153 Expect(rttStats.LatestRTT()).To(Equal(200 * time.Millisecond)) 154 Expect(rttStats.SmoothedRTT()).To(Equal(200 * time.Millisecond)) 155 Expect(rttStats.MeanDeviation()).To(Equal(100 * time.Millisecond)) 156 }) 157 158 It("doesn't restore the RTT if we already have a measurement", func() { 159 const rtt = 10 * time.Millisecond 160 rttStats.UpdateRTT(rtt, 0, time.Now()) 161 Expect(rttStats.LatestRTT()).To(Equal(rtt)) 162 Expect(rttStats.SmoothedRTT()).To(Equal(rtt)) 163 rttStats.SetInitialRTT(time.Minute) 164 Expect(rttStats.LatestRTT()).To(Equal(rtt)) 165 Expect(rttStats.SmoothedRTT()).To(Equal(rtt)) 166 }) 167 })