feat(quic): replace probe UDP data plane with QUIC datagrams

This commit is contained in:
justme committed 2026-10-10 02:59:56 +08:00
1 parent 4609048865
commit b964dc2bbc
53 files changed
+2413 -411

No files matched your search

@@ -40,8 +40,8 @@ public sealed class ModelAndTestEvaluatorTests
[Fact]
public void BaseModel_PerfectLine_ScoresHigh_AndBadLine_ScoresLow()
{
double good = new BaseModel().Score(View(("rtt.p95", 25), ("loss.total", 0), ("jitter.down.p95", 1), ("jitter.up.p95", 1), ("loss.run_max", 1))).Score!.Value;
double bad = new BaseModel().Score(View(("rtt.p95", 400), ("loss.total", 12), ("jitter.down.p95", 90), ("jitter.up.p95", 90), ("loss.run_max", 40))).Score!.Value;
double good = new BaseModel().Score(View(("rtt.p95", 25), ("loss.total", 0), ("jitter.down.p95", 1), ("jitter.up.p95", 1), ("loss.run.up_max", 1), ("loss.run.down_max", 1))).Score!.Value;
double bad = new BaseModel().Score(View(("rtt.p95", 400), ("loss.total", 12), ("jitter.down.p95", 90), ("jitter.up.p95", 90), ("loss.run.up_max", 40), ("loss.run.down_max", 40))).Score!.Value;
Assert.True(good > 95);
Assert.True(bad < 10);
}
@@ -83,7 +83,7 @@ public sealed class ModelAndTestEvaluatorTests
var ranges = new Dictionary<string, double[]>
{
["rtt.p95"] = [10, 30, 80, 150, 300, 600], ["loss.total"] = [0, 0.5, 1, 3, 10, 30],
["jitter.down.p95"] = [0, 2, 8, 20, 80, 200], ["jitter.up.p95"] = [0, 2, 8, 20, 80, 200], ["loss.run_max"] = [1, 3, 10, 30, 60],
["jitter.down.p95"] = [0, 2, 8, 20, 80, 200], ["jitter.up.p95"] = [0, 2, 8, 20, 80, 200], ["loss.run.up_max"] = [1, 3, 10, 30, 60], ["loss.run.down_max"] = [1, 3, 10, 30, 60],
["tcp.rtt.p95"] = [10, 40, 100, 200, 400, 800], ["tcp.stall.per_min"] = [0, 1, 5, 20, 60, 200], ["tcp.stall_max"] = [50, 150, 500, 2000, 5000],
["tcp.retrans"] = [0, 0.1, 1, 3, 10, 30], ["connect.tls_ms.p95"] = [50, 150, 400, 1000, 3000], ["hold.resets.per_h"] = [0, 1, 4, 12, 30],
["connect.success"] = [100, 99, 95, 80, 50], ["tcp.bulk.peak.max"] = [800, 400, 100, 10, 1], ["hy2.sustainable_mbps"] = [100, 50, 25, 10, 0],
@@ -90,6 +90,28 @@ public sealed class OpTests
Assert.Equal(2, ((RunLengthAcc)EvaluateOneBucket(chunk, "loss.run").Items["loss.run"]).Max);
}
[Fact]
public void LossRuns_AreSeparatedByDirection_AndDownstreamExcludesRequestsLostUpstream()
{
bool[] upLost = [false, true, true, false, false, false, true, true];
bool[] downLost = [false, false, true, true, false, true, false, true];
RawChunk chunk = ChunkFactory.Echo(s_agent, "udp_echo", T0, upLost.Length, 100,
i => new EchoPacket(upLost[i], downLost[i], 20_000, 20_000));
MetricSet set = EvaluateOneBucket(chunk, "loss.run.up", "loss.run.down");
Assert.Equal(2, ((MaxAcc)set.Items["loss.run.up"]).Result);
Assert.Equal(1, ((MaxAcc)set.Items["loss.run.down"]).Result);
}
[Fact]
public void LossRuns_NoLoss_ExportsZeroForBothDirections()
{
RawChunk chunk = ChunkFactory.UdpEchoClean(s_agent, T0, count: 8);
MetricSet set = EvaluateOneBucket(chunk, "loss.run.up", "loss.run.down");
Assert.Equal(0, ((MaxAcc)set.Items["loss.run.up"]).Result);
Assert.Equal(0, ((MaxAcc)set.Items["loss.run.down"]).Result);
}
[Fact]
public void Reorder_CountsLateArrivals_AndIgnoresDuplicates()
{