Files
quic-go/internal/utils/rtt_stats_test.go

122 lines
4.7 KiB
Go

package utils
import (
"time"
"github.com/quic-go/quic-go/internal/protocol"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)
var _ = Describe("RTT stats", func() {
It("DefaultsBeforeUpdate", func() {
var rttStats RTTStats
Expect(rttStats.MinRTT()).To(Equal(time.Duration(0)))
Expect(rttStats.SmoothedRTT()).To(Equal(time.Duration(0)))
})
It("SmoothedRTT", func() {
var rttStats RTTStats
// Verify that ack_delay is ignored in the first measurement.
rttStats.UpdateRTT((300 * time.Millisecond), (100 * time.Millisecond), time.Time{})
Expect(rttStats.LatestRTT()).To(Equal((300 * time.Millisecond)))
Expect(rttStats.SmoothedRTT()).To(Equal((300 * time.Millisecond)))
// Verify that Smoothed RTT includes max ack delay if it's reasonable.
rttStats.UpdateRTT((350 * time.Millisecond), (50 * time.Millisecond), time.Time{})
Expect(rttStats.LatestRTT()).To(Equal((300 * time.Millisecond)))
Expect(rttStats.SmoothedRTT()).To(Equal((300 * time.Millisecond)))
// Verify that large erroneous ack_delay does not change Smoothed RTT.
rttStats.UpdateRTT((200 * time.Millisecond), (300 * time.Millisecond), time.Time{})
Expect(rttStats.LatestRTT()).To(Equal((200 * time.Millisecond)))
Expect(rttStats.SmoothedRTT()).To(Equal((287500 * time.Microsecond)))
})
It("MinRTT", func() {
var rttStats RTTStats
rttStats.UpdateRTT((200 * time.Millisecond), 0, time.Time{})
Expect(rttStats.MinRTT()).To(Equal((200 * time.Millisecond)))
rttStats.UpdateRTT((10 * time.Millisecond), 0, time.Time{}.Add((10 * time.Millisecond)))
Expect(rttStats.MinRTT()).To(Equal((10 * time.Millisecond)))
rttStats.UpdateRTT((50 * time.Millisecond), 0, time.Time{}.Add((20 * time.Millisecond)))
Expect(rttStats.MinRTT()).To(Equal((10 * time.Millisecond)))
rttStats.UpdateRTT((50 * time.Millisecond), 0, time.Time{}.Add((30 * time.Millisecond)))
Expect(rttStats.MinRTT()).To(Equal((10 * time.Millisecond)))
rttStats.UpdateRTT((50 * time.Millisecond), 0, time.Time{}.Add((40 * time.Millisecond)))
Expect(rttStats.MinRTT()).To(Equal((10 * time.Millisecond)))
// Verify that ack_delay does not go into recording of MinRTT_.
rttStats.UpdateRTT((7 * time.Millisecond), (2 * time.Millisecond), time.Time{}.Add((50 * time.Millisecond)))
Expect(rttStats.MinRTT()).To(Equal((7 * time.Millisecond)))
})
It("MaxAckDelay", func() {
var rttStats RTTStats
rttStats.SetMaxAckDelay(42 * time.Minute)
Expect(rttStats.MaxAckDelay()).To(Equal(42 * time.Minute))
})
It("computes the PTO", func() {
var rttStats RTTStats
const (
maxAckDelay = 42 * time.Minute
rtt = time.Second
)
rttStats.SetMaxAckDelay(maxAckDelay)
rttStats.UpdateRTT(rtt, 0, time.Time{})
Expect(rttStats.SmoothedRTT()).To(Equal(rtt))
Expect(rttStats.MeanDeviation()).To(Equal(rtt / 2))
Expect(rttStats.PTO(false)).To(Equal(rtt + 4*(rtt/2)))
Expect(rttStats.PTO(true)).To(Equal(rtt + 4*(rtt/2) + maxAckDelay))
})
It("uses the granularity for computing the PTO for short RTTs", func() {
var rttStats RTTStats
const rtt = time.Microsecond
rttStats.UpdateRTT(rtt, 0, time.Time{})
Expect(rttStats.PTO(true)).To(Equal(rtt + protocol.TimerGranularity))
})
It("UpdateRTTWithBadSendDeltas", func() {
var rttStats RTTStats
const initialRtt = 10 * time.Millisecond
rttStats.UpdateRTT(initialRtt, 0, time.Time{})
Expect(rttStats.MinRTT()).To(Equal(initialRtt))
Expect(rttStats.SmoothedRTT()).To(Equal(initialRtt))
badSendDeltas := []time.Duration{
0,
-1000 * time.Microsecond,
}
for _, badSendDelta := range badSendDeltas {
rttStats.UpdateRTT(badSendDelta, 0, time.Time{})
Expect(rttStats.MinRTT()).To(Equal(initialRtt))
Expect(rttStats.SmoothedRTT()).To(Equal(initialRtt))
}
})
It("restores the RTT", func() {
var rttStats RTTStats
rttStats.SetInitialRTT(10 * time.Second)
Expect(rttStats.LatestRTT()).To(Equal(10 * time.Second))
Expect(rttStats.SmoothedRTT()).To(Equal(10 * time.Second))
Expect(rttStats.MeanDeviation()).To(BeZero())
// update the RTT and make sure that the initial value is immediately forgotten
rttStats.UpdateRTT(200*time.Millisecond, 0, time.Time{})
Expect(rttStats.LatestRTT()).To(Equal(200 * time.Millisecond))
Expect(rttStats.SmoothedRTT()).To(Equal(200 * time.Millisecond))
Expect(rttStats.MeanDeviation()).To(Equal(100 * time.Millisecond))
})
It("doesn't restore the RTT if we already have a measurement", func() {
var rttStats RTTStats
const rtt = 10 * time.Millisecond
rttStats.UpdateRTT(rtt, 0, time.Now())
Expect(rttStats.LatestRTT()).To(Equal(rtt))
Expect(rttStats.SmoothedRTT()).To(Equal(rtt))
rttStats.SetInitialRTT(time.Minute)
Expect(rttStats.LatestRTT()).To(Equal(rtt))
Expect(rttStats.SmoothedRTT()).To(Equal(rtt))
})
})