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:
1 parent
d5ebf29e57
commit
ad5efc62ff
206 files changed
+4202
-4964
No files matched your search
@@ -1,6 +1,7 @@
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text.Json.Nodes;
|
||||
using Fleet.Core;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using MoShiro.Backend.Application;
|
||||
using MoShiro.Protocol;
|
||||
@@ -31,7 +32,7 @@ public sealed class Ipv6Tests : IClassFixture<BackendFixture>
|
||||
{
|
||||
RawChunk chunk = ChunkFactory.Echo(agent.NodeId, "udp_echo", start + k * 10_000, 100, 100,
|
||||
i => new EchoPacket(false, version == IpVersions.V6 && i % 2 == 0, 20_000, 20_000));
|
||||
chunk.Header.ProbeId = new ProbeId(_backend.DefaultProbeId);
|
||||
chunk.Header.DialerId = new NodeId(_backend.DefaultDialerId);
|
||||
chunk.Header.IpVersion = version;
|
||||
Assert.True(await agent.SendChunkAsync(chunk));
|
||||
}
|
||||
@@ -75,8 +76,9 @@ public sealed class Ipv6Tests : IClassFixture<BackendFixture>
|
||||
using HttpResponseMessage valid = await _backend.Admin.PatchAsync("/api/admin/agents/" + agent.NodeId.Value,
|
||||
BackendFixture.Json(new JsonObject { ["ipv6_host"] = "::1" }));
|
||||
Assert.True(valid.IsSuccessStatusCode);
|
||||
ProbeAgentList endpoints = await _backend.Services.GetRequiredService<AgentService>().ProbeAgentsAsync(_backend.DefaultProbeId, default);
|
||||
Assert.Null(Assert.Single(endpoints.Agents, a => a.AgentId == agent.NodeId).Ipv6Host);
|
||||
AgentRecord dialer = (await _backend.Services.GetRequiredService<IAgentStore>().GetAsync(new NodeId(_backend.DefaultDialerId), default))!;
|
||||
DialTargets endpoints = await _backend.Services.GetRequiredService<AgentService>().DialTargetsAsync(dialer, default);
|
||||
Assert.Null(Assert.Single(endpoints.Targets, t => t.NodeId == agent.NodeId).Ipv6Host);
|
||||
JsonNode identity = await _backend.GetJsonAsync(_backend.Admin, "/api/admin/agents/" + agent.NodeId.Value);
|
||||
Assert.Equal("::1", identity["ipv6_host"]!.GetValue<string>());
|
||||
Assert.False(identity["ipv6_supported"]!.GetValue<bool>());
|
||||
@@ -91,16 +93,16 @@ public sealed class Ipv6Tests : IClassFixture<BackendFixture>
|
||||
using HttpResponseMessage configured = await _backend.Admin.PatchAsync("/api/admin/agents/" + agent.Id,
|
||||
BackendFixture.Json(new JsonObject { ["public_host"] = "127.0.0.1", ["ipv6_host"] = "::1" }));
|
||||
Assert.True(configured.IsSuccessStatusCode, await configured.Content.ReadAsStringAsync());
|
||||
await using ProbeHarness probe = await ProbeHarness.StartAsync(_backend);
|
||||
await BackendFixture.EventuallyAsync(() => Task.FromResult(probe.App.IsConnected(agent.Id) && probe.App.IsConnected(agent.Id, IpVersions.V6)));
|
||||
await using DialerHarness dialer = await DialerHarness.StartAsync(_backend);
|
||||
await BackendFixture.EventuallyAsync(() => Task.FromResult(dialer.App.Dialer.IsConnected(agent.Id) && dialer.App.Dialer.IsConnected(agent.Id, IpVersions.V6)));
|
||||
await BackendFixture.EventuallyAsync(async () =>
|
||||
{
|
||||
JsonNode raw = await _backend.GetJsonAsync(_backend.Admin, "/api/admin/raw/chunks?agent_id=" + agent.Id);
|
||||
return new[] { "line:" + probe.ProbeId, "line:" + probe.ProbeId + ":ipv6" }.All(series =>
|
||||
return new[] { "line:" + dialer.DialerId, "line:" + dialer.DialerId + ":ipv6" }.All(series =>
|
||||
new[] { "udp_echo", "tcp_echo" }.All(kind => raw["items"]!.AsArray().Any(c => c!["series"]!.GetValue<string>() == series && c["kind"]!.GetValue<string>() == kind)));
|
||||
}, TimeSpan.FromSeconds(45));
|
||||
|
||||
string v4 = agent.Id + "~" + probe.ProbeId;
|
||||
string v4 = agent.Id + "~" + dialer.DialerId;
|
||||
string v6 = v4 + "~ipv6";
|
||||
foreach (string step in new[] { "1s", "10s" })
|
||||
{
|
||||
@@ -117,13 +119,13 @@ public sealed class Ipv6Tests : IClassFixture<BackendFixture>
|
||||
Assert.Contains(overview["lines"]!.AsArray(), l => l!["id"]!.GetValue<string>() == v6);
|
||||
Assert.All(overview["lines"]!.AsArray(), l => Assert.Equal("ipv6", l!["ip_version"]!.GetValue<string>()));
|
||||
|
||||
var ipv4Connection = probe.App.Connection(agent.Id);
|
||||
var ipv4Connection = dialer.App.Dialer.Connection(agent.Id);
|
||||
long previous = agent.App.Counters.Fragments;
|
||||
using HttpResponseMessage disabled = await _backend.Admin.PatchAsync("/api/admin/agents/" + agent.Id, BackendFixture.Json(new JsonObject { ["ipv6_host"] = "" }));
|
||||
Assert.True(disabled.IsSuccessStatusCode);
|
||||
await BackendFixture.EventuallyAsync(() => Task.FromResult(probe.App.Connection(agent.Id, IpVersions.V6) is null));
|
||||
Assert.Same(ipv4Connection, probe.App.Connection(agent.Id));
|
||||
Assert.True(probe.App.IsConnected(agent.Id));
|
||||
await BackendFixture.EventuallyAsync(() => Task.FromResult(dialer.App.Dialer.Connection(agent.Id, IpVersions.V6) is null));
|
||||
Assert.Same(ipv4Connection, dialer.App.Dialer.Connection(agent.Id));
|
||||
Assert.True(dialer.App.Dialer.IsConnected(agent.Id));
|
||||
await BackendFixture.EventuallyAsync(() => Task.FromResult(agent.App.Counters.Fragments > previous), TimeSpan.FromSeconds(20));
|
||||
Assert.Equal(0, agent.App.Counters.FragmentsDiscarded);
|
||||
}
|
||||
@@ -139,12 +141,12 @@ public sealed class Ipv6Tests : IClassFixture<BackendFixture>
|
||||
using HttpResponseMessage configured = await _backend.Admin.PatchAsync("/api/admin/agents/" + agent.Id,
|
||||
BackendFixture.Json(new JsonObject { ["ipv6_host"] = "::1" }));
|
||||
Assert.True(configured.IsSuccessStatusCode);
|
||||
await using ProbeHarness probe = await ProbeHarness.StartAsync(_backend);
|
||||
string v4 = agent.Id + "~" + probe.ProbeId;
|
||||
await using DialerHarness dialer = await DialerHarness.StartAsync(_backend);
|
||||
string v4 = agent.Id + "~" + dialer.DialerId;
|
||||
string v6 = v4 + "~ipv6";
|
||||
await BackendFixture.EventuallyAsync(async () =>
|
||||
(await _backend.GetJsonAsync(_backend.Admin, "/api/admin/agents/" + agent.Id))["probes"]!.AsArray()
|
||||
.Any(p => p!["probe_id"]!.GetValue<string>() == probe.ProbeId && p["ip_version"]!.GetValue<string>() == "ipv6"));
|
||||
(await _backend.GetJsonAsync(_backend.Admin, "/api/admin/agents/" + agent.Id))["dialers"]!.AsArray()
|
||||
.Any(p => p!["dialer_id"]!.GetValue<string>() == dialer.DialerId && p["ip_version"]!.GetValue<string>() == "ipv6"));
|
||||
var parameters = plan == "hy2_ladder" ? new JsonObject { ["mbps"] = 1, ["duration_s"] = 1 } : new JsonObject { ["duration_s"] = 1 };
|
||||
using HttpResponseMessage accepted = await _backend.Admin.PostAsync($"/api/admin/lines/{v6}/tests", BackendFixture.Json(new JsonObject { ["plan"] = plan, ["params"] = parameters }));
|
||||
Assert.Equal(HttpStatusCode.Accepted, accepted.StatusCode);
|
||||
|
||||
Reference in new issue
Block a user