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
@@ -21,29 +21,29 @@ public sealed class OnDemandTestsTests : IClassFixture<BackendFixture>
|
||||
private static JsonObject Plan(string plan, JsonObject? parameters = null) =>
|
||||
parameters is null ? new JsonObject { ["plan"] = plan } : new JsonObject { ["plan"] = plan, ["params"] = parameters };
|
||||
|
||||
private async Task<AgentSimulator> AgentWithProbeAsync()
|
||||
private async Task<AgentSimulator> AgentWithDialerAsync()
|
||||
{
|
||||
AgentSimulator agent = await _backend.ConnectAgentAsync();
|
||||
await agent.WaitForTaskSetAsync(s => s.Tasks.Count == Defaults.TaskCount);
|
||||
await agent.SendEventAsync(AgentEventKinds.ProbeConnected, _backend.DefaultProbeId);
|
||||
await BackendFixture.EventuallyAsync(async () => (await _backend.GetJsonAsync(_backend.Admin, "/api/admin/agents/" + agent.NodeId.Value))["probe_connected"]!.GetValue<bool>());
|
||||
await agent.SendEventAsync(AgentEventKinds.DialerConnected, _backend.DefaultDialerId);
|
||||
await BackendFixture.EventuallyAsync(async () => (await _backend.GetJsonAsync(_backend.Admin, "/api/admin/agents/" + agent.NodeId.Value))["dialer_connected"]!.GetValue<bool>());
|
||||
return agent;
|
||||
}
|
||||
|
||||
private async Task<JsonNode> TestAsync(string id) => await _backend.GetJsonAsync(_backend.Admin, "/api/public/tests/" + id);
|
||||
|
||||
[Fact]
|
||||
public async Task Start_RequiresAProbeSession_APlanThatExists_AndValidParams()
|
||||
public async Task Start_RequiresADialerSession_APlanThatExists_AndValidParams()
|
||||
{
|
||||
await using AgentSimulator agent = await _backend.ConnectAgentAsync();
|
||||
await agent.WaitForTaskSetAsync(s => s.Tasks.Count == Defaults.TaskCount);
|
||||
|
||||
using HttpResponseMessage offline = await StartAsync(agent, Plan("hy2_ladder"));
|
||||
Assert.Equal(HttpStatusCode.Conflict, offline.StatusCode);
|
||||
Assert.Equal("probe_offline", JsonNode.Parse(await offline.Content.ReadAsStringAsync())!["code"]!.GetValue<string>());
|
||||
Assert.Equal("dialer_offline", JsonNode.Parse(await offline.Content.ReadAsStringAsync())!["code"]!.GetValue<string>());
|
||||
|
||||
await agent.SendEventAsync(AgentEventKinds.ProbeConnected, _backend.DefaultProbeId);
|
||||
await BackendFixture.EventuallyAsync(async () => (await _backend.GetJsonAsync(_backend.Admin, "/api/admin/agents/" + agent.NodeId.Value))["probe_connected"]!.GetValue<bool>());
|
||||
await agent.SendEventAsync(AgentEventKinds.DialerConnected, _backend.DefaultDialerId);
|
||||
await BackendFixture.EventuallyAsync(async () => (await _backend.GetJsonAsync(_backend.Admin, "/api/admin/agents/" + agent.NodeId.Value))["dialer_connected"]!.GetValue<bool>());
|
||||
|
||||
using HttpResponseMessage unknownPlan = await StartAsync(agent, Plan("warp_ladder"));
|
||||
Assert.Equal(HttpStatusCode.NotFound, unknownPlan.StatusCode);
|
||||
@@ -69,7 +69,7 @@ public sealed class OnDemandTestsTests : IClassFixture<BackendFixture>
|
||||
[Trait("Category", "Slow")]
|
||||
public async Task Hy2Ladder_RunsEndToEnd_AndProducesAResultWithScores()
|
||||
{
|
||||
await using AgentSimulator agent = await AgentWithProbeAsync();
|
||||
await using AgentSimulator agent = await AgentWithDialerAsync();
|
||||
using HttpResponseMessage accepted = await StartAsync(agent, Plan("hy2_ladder"));
|
||||
Assert.Equal(HttpStatusCode.Accepted, accepted.StatusCode);
|
||||
JsonNode started = JsonNode.Parse(await accepted.Content.ReadAsStringAsync())!;
|
||||
@@ -140,7 +140,7 @@ public sealed class OnDemandTestsTests : IClassFixture<BackendFixture>
|
||||
[Fact]
|
||||
public async Task AgentRefusal_IsSurfacedAndMarksTheTestFailed()
|
||||
{
|
||||
await using AgentSimulator agent = await AgentWithProbeAsync();
|
||||
await using AgentSimulator agent = await AgentWithDialerAsync();
|
||||
agent.TestRunHandler = _ => (false, "test_busy");
|
||||
using HttpResponseMessage response = await StartAsync(agent, Plan("hy2_ladder"));
|
||||
Assert.Equal(HttpStatusCode.Conflict, response.StatusCode);
|
||||
@@ -160,7 +160,7 @@ public sealed class OnDemandTestsTests : IClassFixture<BackendFixture>
|
||||
[Fact]
|
||||
public async Task Cancel_ReachesTheAgent_AndOnlyTheOwningAgentCanReportStatus()
|
||||
{
|
||||
await using AgentSimulator agent = await AgentWithProbeAsync();
|
||||
await using AgentSimulator agent = await AgentWithDialerAsync();
|
||||
await using AgentSimulator other = await _backend.ConnectAgentAsync();
|
||||
using HttpResponseMessage accepted = await StartAsync(agent, Plan("reality_session"));
|
||||
Assert.Equal(HttpStatusCode.Accepted, accepted.StatusCode);
|
||||
@@ -190,7 +190,7 @@ public sealed class OnDemandTestsTests : IClassFixture<BackendFixture>
|
||||
[Fact]
|
||||
public async Task CancellingATestOfAnOfflineAgent_AbortsItImmediately()
|
||||
{
|
||||
AgentSimulator agent = await AgentWithProbeAsync();
|
||||
AgentSimulator agent = await AgentWithDialerAsync();
|
||||
using HttpResponseMessage accepted = await StartAsync(agent, Plan("reality_session"));
|
||||
string testId = JsonNode.Parse(await accepted.Content.ReadAsStringAsync())!["id"]!.GetValue<string>();
|
||||
await agent.DisposeAsync();
|
||||
@@ -205,7 +205,7 @@ public sealed class OnDemandTestsTests : IClassFixture<BackendFixture>
|
||||
public async Task TestsOfHiddenLines_AreNotFoundForAnonymousVisitors()
|
||||
{
|
||||
await _backend.SiteMustBePublicAsync();
|
||||
await using AgentSimulator agent = await AgentWithProbeAsync();
|
||||
await using AgentSimulator agent = await AgentWithDialerAsync();
|
||||
using HttpResponseMessage accepted = await StartAsync(agent, Plan("reality_session"));
|
||||
string testId = JsonNode.Parse(await accepted.Content.ReadAsStringAsync())!["id"]!.GetValue<string>();
|
||||
|
||||
@@ -230,7 +230,7 @@ public sealed class OnDemandTestsTests : IClassFixture<BackendFixture>
|
||||
JsonNode list = await _backend.GetJsonAsync(_backend.Admin, $"/api/admin/raw/chunks?agent_id={agent.NodeId.Value}&kind=udp_echo");
|
||||
JsonNode item = list["items"]!.AsArray().Single()!;
|
||||
Assert.Equal(chunk.Header.ChunkId.ToString(), item["chunk_id"]!.GetValue<string>());
|
||||
Assert.Equal("line:" + _backend.DefaultProbeId, item["series"]!.GetValue<string>());
|
||||
Assert.Equal("line:" + _backend.DefaultDialerId, item["series"]!.GetValue<string>());
|
||||
|
||||
using HttpResponseMessage download = await _backend.Admin.GetAsync("/api/admin/raw/chunks/" + chunk.Header.ChunkId);
|
||||
Assert.Equal("application/vnd.moshiro.rawchunk", download.Content.Headers.ContentType!.MediaType);
|
||||
|
||||
Reference in new issue
Block a user