test(gateway): measure qualification wire capacity
Verify Data Plane / gateway (push) Successful in 4m46s
Verify Data Plane / gateway (push) Successful in 4m46s
This commit is contained in:
@@ -669,6 +669,117 @@ func TestQualificationLossAndSteppedThroughputBounds(t *testing.T) {
|
||||
profile.Name == "constrained" && len(observation.CapacityStepObservations) != 2 {
|
||||
t.Fatalf("%s observation = %#v", profile.Name, observation)
|
||||
}
|
||||
for _, step := range observation.CapacityStepObservations {
|
||||
t.Logf("%s %d%%: convergence=%s wire_max_5s=%d wire_cap=%d", profile.Name, step.ReductionPercent, step.Convergence, step.MaximumFiveSecond, step.FiveSecondCap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestQualificationCapacityStepsMeasurePublicWireDatagrams(t *testing.T) {
|
||||
const packetCount = qualificationImpairmentPacketCount
|
||||
profile := qualificationMediaProfiles()[0]
|
||||
started := time.Date(2026, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||
spacing := time.Duration(int64(time.Second) * int64(profile.PacketBytes) * 8 / (profile.BitrateKbps * 1000))
|
||||
stepAt := map[int]time.Time{
|
||||
25: started.Add(time.Duration(packetCount/3) * spacing),
|
||||
50: started.Add(time.Duration(packetCount*2/3) * spacing),
|
||||
}
|
||||
if phase := stepAt[50].Sub(stepAt[25]); phase != 1_571_842_800*time.Nanosecond {
|
||||
t.Fatalf("25%% phase = %s, want exact source-shaped transition", phase)
|
||||
}
|
||||
|
||||
pacer := newFairPacer(qualificationMediaPacerKbps(profile, 0))
|
||||
const flow = "qualification-wire-flow"
|
||||
now := started
|
||||
stalled := false
|
||||
quarterApplied := false
|
||||
halfApplied := false
|
||||
debtBeforeQuarter := time.Duration(0)
|
||||
logicalDeliveries := make([]qualificationDeliverySample, 0, packetCount)
|
||||
type wireSample struct {
|
||||
reserved time.Time
|
||||
delivery qualificationDeliverySample
|
||||
}
|
||||
wireSamples := make([]wireSample, 0, packetCount*2)
|
||||
for index := 0; index < packetCount; index++ {
|
||||
sourceAt := started.Add(time.Duration(index) * spacing)
|
||||
if now.Before(sourceAt) {
|
||||
now = sourceAt
|
||||
}
|
||||
if !stalled && !sourceAt.Before(stepAt[25].Add(-150*time.Millisecond)) {
|
||||
now = now.Add(42 * time.Millisecond)
|
||||
stalled = true
|
||||
}
|
||||
for _, encodedBytes := range []int{1200, 25} {
|
||||
if !quarterApplied && !now.Before(stepAt[25]) {
|
||||
pacer.mu.Lock()
|
||||
debtBeforeQuarter = pacer.flows[flow].debt
|
||||
pacer.mu.Unlock()
|
||||
pacer.setKbps(qualificationMediaPacerKbps(profile, 25))
|
||||
quarterApplied = true
|
||||
}
|
||||
if !halfApplied && !now.Before(stepAt[50]) {
|
||||
pacer.setKbps(qualificationMediaPacerKbps(profile, 50))
|
||||
halfApplied = true
|
||||
}
|
||||
reserved := pacer.reserveAt(now, flow, encodedBytes)
|
||||
if reserved.After(now) {
|
||||
now = reserved
|
||||
}
|
||||
wireSamples = append(wireSamples, wireSample{
|
||||
reserved: reserved,
|
||||
delivery: qualificationDeliverySample{At: now, Bytes: int64(encodedBytes)},
|
||||
})
|
||||
}
|
||||
logicalDeliveries = append(logicalDeliveries, qualificationDeliverySample{At: now, Bytes: 1225})
|
||||
}
|
||||
if !quarterApplied || !halfApplied || debtBeforeQuarter <= 0 || debtBeforeQuarter > nativeApolloVideoQueueLatency-fairPacerMaximumCatchup {
|
||||
t.Fatalf("capacity transition state quarter=%t half=%t debt=%s", quarterApplied, halfApplied, debtBeforeQuarter)
|
||||
}
|
||||
pacer.mu.Lock()
|
||||
remainingDebt := pacer.flows[flow].debt
|
||||
pacer.mu.Unlock()
|
||||
if remainingDebt != 0 {
|
||||
t.Fatalf("remaining debt = %s, want zero", remainingDebt)
|
||||
}
|
||||
t.Logf("wire model: datagrams=%d debt_before_25=%s remaining_debt=%s", len(wireSamples), debtBeforeQuarter, remainingDebt)
|
||||
wireDeliveries := make([]qualificationDeliverySample, len(wireSamples))
|
||||
for index, sample := range wireSamples {
|
||||
if sample.delivery.At.Before(sample.reserved) {
|
||||
t.Fatalf("wire datagram %d delivered at %s before reservation %s", index, sample.delivery.At, sample.reserved)
|
||||
}
|
||||
wireDeliveries[index] = sample.delivery
|
||||
}
|
||||
|
||||
for _, reduction := range []int{25, 50} {
|
||||
wireBytesPerSecond := qualificationMediaPacerKbps(profile, reduction) * 1000 / 8
|
||||
wireAfterStep := qualificationDeliveriesAfter(wireDeliveries, stepAt[reduction])
|
||||
maximum := qualificationMaximumDeliveryBytes(wireAfterStep, 5*time.Second)
|
||||
if maximum > wireBytesPerSecond*5*105/100 {
|
||||
t.Fatalf("%d%% wire five-second maximum = %d, cap = %d", reduction, maximum, wireBytesPerSecond*5*105/100)
|
||||
}
|
||||
payloadBytesPerSecond := profile.BitrateKbps * int64(100-reduction) * 1000 / 100 / 8
|
||||
legacy := qualificationMeasuredConvergence(
|
||||
qualificationDeliveriesAfter(logicalDeliveries, stepAt[reduction]), stepAt[reduction], payloadBytesPerSecond,
|
||||
)
|
||||
if reduction == 25 && legacy != 11*time.Second {
|
||||
t.Fatalf("25%% complete-frame classifier convergence = %s, want 11s sentinel reproduction", legacy)
|
||||
}
|
||||
observation := qualificationCapacityStepObservation(wireDeliveries, stepAt[reduction], profile, reduction)
|
||||
if observation.Convergence > 10*time.Second {
|
||||
for offset := time.Duration(0); offset < 2*time.Second; offset += 250 * time.Millisecond {
|
||||
var bucket int64
|
||||
for _, delivery := range wireAfterStep {
|
||||
if !delivery.At.Before(stepAt[reduction].Add(offset)) && delivery.At.Before(stepAt[reduction].Add(offset+250*time.Millisecond)) {
|
||||
bucket += delivery.Bytes
|
||||
}
|
||||
}
|
||||
t.Logf("%d%% wire bucket %s = %d bytes (%d B/s)", reduction, offset, bucket, bucket*4)
|
||||
}
|
||||
t.Fatalf("%d%% wire convergence = %s sentinel with wire maximum %d under cap %d", reduction, observation.Convergence, maximum, wireBytesPerSecond*5*105/100)
|
||||
}
|
||||
t.Logf("%d%%: payload_target=%d wire_target=%d legacy=%s wire_convergence=%s wire_max_5s=%d wire_cap_105=%d",
|
||||
reduction, payloadBytesPerSecond, wireBytesPerSecond, legacy, observation.Convergence, maximum, wireBytesPerSecond*5*105/100)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user