Files
MoShiro/backend/shared/tests/MoShiro.Measurement.Tests/QuicSettingsTests.cs
T

58 lines
2.5 KiB
C#

using System.Net;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using Fleet.Core;
namespace MoShiro.Measurement.Tests;
public sealed class QuicSettingsTests
{
[Theory]
[InlineData(1100, null, false)]
[InlineData(null, 70_000, false)]
[InlineData(1400, 1300, false)]
[InlineData(1280, 1500, true)]
[InlineData(null, null, true)]
public void Validate_RejectsMtuOutsideTheSupportedRangeOrOutOfOrder(int? min, int? max, bool valid) =>
Assert.Equal(valid, new QuicSettings { MinMtu = min, MaxMtu = max }.Validate() is null);
/// <summary>设置真的写进了 MsQuic:最大 MTU 压低后数据报上限随之变小,最小 MTU 抬高后一连上就是大包(不用等路径探测)。</summary>
[Theory]
[InlineData(1200, 1280, 1200, 1280)]
[InlineData(1500, 1500, 1400, 1500)]
public async Task Settings_ChangeTheDatagramLimitOfTheConnection(int min, int max, int atLeast, int atMost)
{
var settings = new QuicSettings { MinMtu = min, MaxMtu = max };
var log = new NullLog();
using ECDsa key = ECDsa.Create(ECCurve.NamedCurves.nistP256);
var request = new CertificateRequest("CN=localhost", key, HashAlgorithmName.SHA256);
using X509Certificate2 certificate = request.CreateSelfSigned(DateTimeOffset.UnixEpoch, DateTimeOffset.UnixEpoch.AddYears(100));
await using var listener = new MsQuicListener(IPAddress.Loopback, [0], certificate, (_, _) => { }, log, null, settings);
listener.Start();
using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(15));
MsQuicConnection client = await MsQuicConnection.ConnectAsync(IPAddress.Loopback, listener.BoundPorts[0], 0, key.ExportSubjectPublicKeyInfo(), (_, _) => { }, log, timeout.Token, settings);
try
{
while (!client.IsReady)
{
await Task.Delay(10, timeout.Token);
}
// 路径 MTU 探测还可能在往上走,给它一点时间;上限始终不能超过设置的最大 MTU
await Task.Delay(1500, timeout.Token);
Assert.InRange(client.MaxDatagramBytes, atLeast - 100, atMost);
}
finally
{
await client.DisposeAsync().AsTask().WaitAsync(TimeSpan.FromSeconds(3));
}
}
private sealed class NullLog : INodeLog
{
public void Write(NodeLogLevel level, string message, params (string Key, object? Value)[] fields)
{
}
}
}