mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-04 12:47:36 +03:00
uTLS is not yet bumped to the new version, so this commit breaks the dependencies relationship by getting rid of the local replace.
167 lines
6.7 KiB
Go
167 lines
6.7 KiB
Go
package utils
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/refraction-networking/uquic/internal/protocol"
|
|
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
)
|
|
|
|
var _ = Describe("RTT stats", func() {
|
|
var rttStats *RTTStats
|
|
|
|
BeforeEach(func() {
|
|
rttStats = NewRTTStats()
|
|
})
|
|
|
|
It("DefaultsBeforeUpdate", func() {
|
|
Expect(rttStats.MinRTT()).To(Equal(time.Duration(0)))
|
|
Expect(rttStats.SmoothedRTT()).To(Equal(time.Duration(0)))
|
|
})
|
|
|
|
It("SmoothedRTT", func() {
|
|
// 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() {
|
|
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() {
|
|
rttStats.SetMaxAckDelay(42 * time.Minute)
|
|
Expect(rttStats.MaxAckDelay()).To(Equal(42 * time.Minute))
|
|
})
|
|
|
|
It("computes the PTO", func() {
|
|
maxAckDelay := 42 * time.Minute
|
|
rttStats.SetMaxAckDelay(maxAckDelay)
|
|
rtt := time.Second
|
|
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() {
|
|
rtt := time.Microsecond
|
|
rttStats.UpdateRTT(rtt, 0, time.Time{})
|
|
Expect(rttStats.PTO(true)).To(Equal(rtt + protocol.TimerGranularity))
|
|
})
|
|
|
|
It("ExpireSmoothedMetrics", func() {
|
|
initialRtt := (10 * time.Millisecond)
|
|
rttStats.UpdateRTT(initialRtt, 0, time.Time{})
|
|
Expect(rttStats.MinRTT()).To(Equal(initialRtt))
|
|
Expect(rttStats.SmoothedRTT()).To(Equal(initialRtt))
|
|
|
|
Expect(rttStats.MeanDeviation()).To(Equal(initialRtt / 2))
|
|
|
|
// Update once with a 20ms RTT.
|
|
doubledRtt := initialRtt * (2)
|
|
rttStats.UpdateRTT(doubledRtt, 0, time.Time{})
|
|
Expect(rttStats.SmoothedRTT()).To(Equal(time.Duration(float32(initialRtt) * 1.125)))
|
|
|
|
// Expire the smoothed metrics, increasing smoothed rtt and mean deviation.
|
|
rttStats.ExpireSmoothedMetrics()
|
|
Expect(rttStats.SmoothedRTT()).To(Equal(doubledRtt))
|
|
Expect(rttStats.MeanDeviation()).To(Equal(time.Duration(float32(initialRtt) * 0.875)))
|
|
|
|
// Now go back down to 5ms and expire the smoothed metrics, and ensure the
|
|
// mean deviation increases to 15ms.
|
|
halfRtt := initialRtt / 2
|
|
rttStats.UpdateRTT(halfRtt, 0, time.Time{})
|
|
Expect(doubledRtt).To(BeNumerically(">", rttStats.SmoothedRTT()))
|
|
Expect(initialRtt).To(BeNumerically("<", rttStats.MeanDeviation()))
|
|
})
|
|
|
|
It("UpdateRTTWithBadSendDeltas", func() {
|
|
// Make sure we ignore bad RTTs.
|
|
// base::test::MockLog log;
|
|
|
|
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,
|
|
InfDuration,
|
|
-1000 * time.Microsecond,
|
|
}
|
|
// log.StartCapturingLogs();
|
|
|
|
for _, badSendDelta := range badSendDeltas {
|
|
// SCOPED_TRACE(Message() << "bad_send_delta = "
|
|
// << bad_send_delta.ToMicroseconds());
|
|
// EXPECT_CALL(log, Log(LOG_WARNING, _, _, _, HasSubstr("Ignoring")));
|
|
rttStats.UpdateRTT(badSendDelta, 0, time.Time{})
|
|
Expect(rttStats.MinRTT()).To(Equal(initialRtt))
|
|
Expect(rttStats.SmoothedRTT()).To(Equal(initialRtt))
|
|
}
|
|
})
|
|
|
|
It("ResetAfterConnectionMigrations", func() {
|
|
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.MinRTT()).To(Equal((200 * time.Millisecond)))
|
|
rttStats.UpdateRTT((300 * time.Millisecond), (100 * time.Millisecond), time.Time{})
|
|
Expect(rttStats.LatestRTT()).To(Equal((200 * time.Millisecond)))
|
|
Expect(rttStats.SmoothedRTT()).To(Equal((200 * time.Millisecond)))
|
|
Expect(rttStats.MinRTT()).To(Equal((200 * time.Millisecond)))
|
|
|
|
// Reset rtt stats on connection migrations.
|
|
rttStats.OnConnectionMigration()
|
|
Expect(rttStats.LatestRTT()).To(Equal(time.Duration(0)))
|
|
Expect(rttStats.SmoothedRTT()).To(Equal(time.Duration(0)))
|
|
Expect(rttStats.MinRTT()).To(Equal(time.Duration(0)))
|
|
})
|
|
|
|
It("restores the RTT", func() {
|
|
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() {
|
|
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))
|
|
})
|
|
})
|