agent: unify listening and dialing with directed mutual measurements

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.
This commit is contained in:
justme committed 2026-10-21 11:55:36 +08:00
1 parent d5ebf29e57
commit ad5efc62ff
206 files changed
+4202 -4964

No files matched your search

@@ -5,7 +5,7 @@ using MoShiro.TestSupport;
namespace MoShiro.Backend.Tests;
/// <summary>Exercises the complete Backend → Agent → Probe desired task update with an isolated Backend fixture.</summary>
/// <summary>Exercises the complete Backend → Agent → Dialer desired task update with an isolated Backend fixture.</summary>
[Trait("Category", "Slow")]
public sealed class AgentTaskSetEndToEndTests : IClassFixture<BackendFixture>
{
@@ -17,12 +17,12 @@ public sealed class AgentTaskSetEndToEndTests : IClassFixture<BackendFixture>
}
[Fact]
public async Task LineTaskSet_FollowsTheDesiredState_AndIsPushedToTheProbe()
public async Task LineTaskSet_FollowsTheDesiredState_AndIsPushedToTheDialer()
{
await using AgentHarness agent = await AgentHarness.StartAsync(_backend);
await agent.OverrideLineTasksAsync(rateHz: 30);
await using ProbeSimulator probe = await agent.ConnectProbeAsync();
LineTask udp = (await probe.WaitForTasksAsync(s => s.Tasks.Any(t => t.Kind == "udp_echo" && t.Port == agent.App.QuicPorts[0])))
await using DialerSimulator dialer = await agent.ConnectDialerAsync();
LineTask udp = (await dialer.WaitForTasksAsync(s => s.Tasks.Any(t => t.Kind == "udp_echo" && t.Port == agent.App.QuicPorts[0])))
.Tasks.Single(t => t.Kind == "udp_echo");
JsonNode tasks = await _backend.GetJsonAsync(_backend.Admin, "/api/admin/tasks");
@@ -30,7 +30,7 @@ public sealed class AgentTaskSetEndToEndTests : IClassFixture<BackendFixture>
using HttpResponseMessage disabled = await _backend.Admin.PatchAsync("/api/admin/tasks/" + mine["id"]!.GetValue<string>(), BackendFixture.Json(new JsonObject { ["enabled"] = false }, "application/merge-patch+json"));
disabled.EnsureSuccessStatusCode();
LineTaskSet next = await probe.WaitForTasksAsync(s => s.Tasks.All(t => t.Kind != "udp_echo") && s.Version > 0);
LineTaskSet next = await dialer.WaitForTasksAsync(s => s.Tasks.All(t => t.Kind != "udp_echo") && s.Version > 0);
Assert.DoesNotContain(next.Tasks, t => t.Id == udp.Id);
}
}