88 lines
3.5 KiB
C#
88 lines
3.5 KiB
C#
using Fleet.Core;
|
|
using Fleet.Hosting;
|
|
using Monitor.Protocol;
|
|
|
|
namespace Monitor.Probe.Tests;
|
|
|
|
public sealed class ProbeTests
|
|
{
|
|
[Fact]
|
|
public void ClockEstimator_UsesTheSampleWithTheShortestRoundTrip()
|
|
{
|
|
var clock = new ClockEstimator();
|
|
Assert.False(clock.HasEstimate);
|
|
|
|
// Offset 1000 with a 50 ms round trip, offset 5000 with a 2 ms round trip (symmetry assumption is far better here)
|
|
clock.Add(sendUs: 0, agentUs: 25_000 + 1000, receiveUs: 50_000);
|
|
clock.Add(sendUs: 100_000, agentUs: 101_000 + 5000, receiveUs: 102_000);
|
|
Assert.True(clock.HasEstimate);
|
|
Assert.Equal(5000, clock.OffsetUs);
|
|
|
|
// Slow samples do not displace the good one
|
|
clock.Add(sendUs: 200_000, agentUs: 300_000, receiveUs: 400_000);
|
|
Assert.Equal(5000, clock.OffsetUs);
|
|
}
|
|
|
|
private static string NewDirectory()
|
|
{
|
|
string path = Path.Combine(Path.GetTempPath(), "probe-tests-" + Guid.NewGuid().ToString("N"));
|
|
Directory.CreateDirectory(path);
|
|
return path;
|
|
}
|
|
|
|
private static ProbeAgentsResult List(long version, params string[] ids) => new()
|
|
{
|
|
Version = version,
|
|
Agents = [.. ids.Select(id => new AgentEndpoint { AgentId = new NodeId(id), Host = id + ".example", TcpPort = 7443, Spki = "c3BraQ==" })],
|
|
};
|
|
|
|
[Fact]
|
|
public void AgentDirectory_StartsFromBootstrap_IgnoresStaleLists_PersistsChanges_AndReloadsThem()
|
|
{
|
|
string directory = NewDirectory();
|
|
try
|
|
{
|
|
var file = new ProbeFile { ProbeId = "prb_x", Bootstrap = [new BootstrapAgent { AgentId = "agt_boot", Host = "boot.example", TcpPort = 7443, Spki = "c3BraQ==" }] };
|
|
var directoryA = new AgentDirectory(new ConfigStore(directory), directory, file, NullNodeLog.Instance);
|
|
int changes = 0;
|
|
directoryA.Changed += () => changes++;
|
|
Assert.Equal(["agt_boot"], directoryA.Agents.Select(a => a.AgentId));
|
|
|
|
directoryA.Apply(List(5, "agt_1", "agt_2"));
|
|
Assert.Equal(1, changes);
|
|
Assert.Equal(["agt_1", "agt_2"], directoryA.Agents.Select(a => a.AgentId));
|
|
|
|
directoryA.Apply(List(4, "agt_old")); // out-of-order older push
|
|
directoryA.Apply(List(5, "agt_1", "agt_2")); // same version and content
|
|
Assert.Equal(1, changes);
|
|
Assert.Equal(5, directoryA.Version);
|
|
|
|
// The next start uses the saved list, not the bootstrap one
|
|
var directoryB = new AgentDirectory(new ConfigStore(directory), directory, file, NullNodeLog.Instance);
|
|
Assert.Equal(["agt_1", "agt_2"], directoryB.Agents.Select(a => a.AgentId));
|
|
Assert.Equal(5, directoryB.Version);
|
|
}
|
|
finally
|
|
{
|
|
Directory.Delete(directory, recursive: true);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void AgentDirectory_FallsBackToBootstrap_WhenTheSavedFileIsCorrupt()
|
|
{
|
|
string directory = NewDirectory();
|
|
try
|
|
{
|
|
new ConfigStore(directory).Write(AgentDirectory.FileName, "{ not json"u8.ToArray());
|
|
var file = new ProbeFile { Bootstrap = [new BootstrapAgent { AgentId = "agt_boot", Host = "h", TcpPort = 1, Spki = "AA==" }] };
|
|
var loaded = new AgentDirectory(new ConfigStore(directory), directory, file, NullNodeLog.Instance);
|
|
Assert.Equal(["agt_boot"], loaded.Agents.Select(a => a.AgentId));
|
|
}
|
|
finally
|
|
{
|
|
Directory.Delete(directory, recursive: true);
|
|
}
|
|
}
|
|
}
|