Files

48 lines
2.8 KiB
C#

using System.Net;
using System.Text.Json.Nodes;
namespace MoShiro.Backend.Tests;
[Trait("Category", "Slow")]
public sealed class AgentMeshTests : IClassFixture<BackendFixture>
{
private readonly BackendFixture _backend;
public AgentMeshTests(BackendFixture backend) => _backend = backend;
/// <summary>两个都监听的 Agent 只有一条线路:id 较小的拨出,上下行都在这一条连接上测。</summary>
[Fact]
public async Task ListeningAgents_ShareOneLine_DialedBySmallerId_AndReportThroughTheirBackendLinks()
{
await using AgentHarness first = await AgentHarness.StartAsync(_backend);
await using AgentHarness second = await AgentHarness.StartAsync(_backend);
(AgentHarness dialer, AgentHarness listener) = string.CompareOrdinal(first.Id, second.Id) < 0 ? (first, second) : (second, first);
await dialer.OverrideLineTasksAsync(rateHz: 30);
await listener.OverrideLineTasksAsync(rateHz: 30);
await BackendFixture.EventuallyAsync(
() => Task.FromResult(dialer.App.Dialer.IsConnected(listener.Id)),
TimeSpan.FromSeconds(30), "the agent with the smaller id should establish the outgoing measurement session");
Assert.False(listener.App.Dialer.IsConnected(dialer.Id)); // 反方向不再拨
using HttpResponseMessage retry = await _backend.Admin.PostAsync($"/api/admin/links/{dialer.Id}/{listener.Id}/retry", null);
Assert.Equal(HttpStatusCode.Accepted, retry.StatusCode);
JsonNode result = JsonNode.Parse(await retry.Content.ReadAsStringAsync())!;
Assert.True(result["queued"]!.GetValue<bool>());
await BackendFixture.EventuallyAsync(async () =>
{
JsonNode matrix = await _backend.GetJsonAsync(_backend.Admin, "/api/admin/links");
JsonNode[] pair = [.. matrix["items"]!.AsArray().Select(i => i!).Where(i =>
(i["dialer_id"]!.GetValue<string>() == dialer.Id && i["listener_id"]!.GetValue<string>() == listener.Id)
|| (i["dialer_id"]!.GetValue<string>() == listener.Id && i["listener_id"]!.GetValue<string>() == dialer.Id))];
return pair.Length == 1 && pair[0]["connected"]!.GetValue<bool>();
}, TimeSpan.FromSeconds(30), "the dialer's heartbeat should report its outgoing connection, and the pair should have a single line");
await BackendFixture.EventuallyAsync(async () =>
{
JsonNode chunks = await _backend.GetJsonAsync(_backend.Admin, $"/api/admin/raw/chunks?agent_id={listener.Id}");
return chunks["items"]!.AsArray().Any(c => c!["kind"]!.GetValue<string>() == "quic_ping" && c["series"]!.GetValue<string>() == "line:" + dialer.Id);
}, TimeSpan.FromSeconds(40), "the line should persist measured packet data");
}
}