Replace Probe with Agent across node runtime, Fleet contracts, backend state, API and storage. Report incoming sessions and outgoing link health through each Agent uplink, and retain directed link controls and retry. Update protocol fixtures and end-to-end coverage for the unified model; accept requested cancellation during the Fleet timeout test cleanup.
47 lines
2.5 KiB
C#
47 lines
2.5 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;
|
|
|
|
[Fact]
|
|
public async Task ListeningAgents_MeasureBothDirections_AndReportThroughTheirBackendLinks()
|
|
{
|
|
await using AgentHarness a = await AgentHarness.StartAsync(_backend);
|
|
await using AgentHarness b = await AgentHarness.StartAsync(_backend);
|
|
await a.OverrideLineTasksAsync(rateHz: 30);
|
|
await b.OverrideLineTasksAsync(rateHz: 30);
|
|
await BackendFixture.EventuallyAsync(
|
|
() => Task.FromResult(a.App.Dialer.IsConnected(b.Id) && b.App.Dialer.IsConnected(a.Id)),
|
|
TimeSpan.FromSeconds(30), "both listening agents should establish outgoing measurement sessions");
|
|
|
|
using HttpResponseMessage retry = await _backend.Admin.PostAsync($"/api/admin/links/{a.Id}/{b.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");
|
|
return matrix["items"]!.AsArray().Count(i =>
|
|
((i!["dialer_id"]!.GetValue<string>() == a.Id && i["listener_id"]!.GetValue<string>() == b.Id)
|
|
|| (i["dialer_id"]!.GetValue<string>() == b.Id && i["listener_id"]!.GetValue<string>() == a.Id))
|
|
&& i["connected"]!.GetValue<bool>()) == 2;
|
|
}, TimeSpan.FromSeconds(30), "each agent heartbeat should report its outgoing connection");
|
|
|
|
await BackendFixture.EventuallyAsync(async () =>
|
|
{
|
|
JsonNode left = await _backend.GetJsonAsync(_backend.Admin, $"/api/admin/raw/chunks?agent_id={a.Id}");
|
|
JsonNode right = await _backend.GetJsonAsync(_backend.Admin, $"/api/admin/raw/chunks?agent_id={b.Id}");
|
|
return left["items"]!.AsArray().Any(c => c!["kind"]!.GetValue<string>() == "udp_echo" && c["series"]!.GetValue<string>() == "line:" + b.Id)
|
|
&& right["items"]!.AsArray().Any(c => c!["kind"]!.GetValue<string>() == "udp_echo" && c["series"]!.GetValue<string>() == "line:" + a.Id);
|
|
}, TimeSpan.FromSeconds(40), "both directed lines should persist measured packet data");
|
|
}
|
|
}
|