Files
justme 5822285a88
ci/woodpecker/push/web-build Pipeline was successful
ci/woodpecker/push/verify Pipeline was successful
ci/woodpecker/push/dev-image Pipeline was successful
ci/woodpecker/push/dev-backend-image Pipeline was successful
fleet: require a minimum version of the peer at the handshake [CI]
MoShiro__MinAgentVersion makes the backend refuse agents below it at hello (fleet_version_required); fleet.min_server_version or MOSHIRO_MIN_SERVER_VERSION makes the agent drop a backend below it. Either side waits five seconds and shakes hands again, because the other one may be updating.
2026-10-22 05:28:29 +08:00

73 lines
3.1 KiB
C#

using System.Text.Json;
using Fleet.Core;
using Fleet.Rpc;
using Microsoft.Extensions.DependencyInjection;
using MoShiro.Backend.Application;
using MoShiro.TestSupport;
namespace MoShiro.Backend.Tests;
public sealed class VersionRequirementTests : IClassFixture<BackendFixture>
{
private readonly BackendFixture _backend;
public VersionRequirementTests(BackendFixture backend)
{
_backend = backend;
}
[Fact]
public async Task AnAgentBelowTheRequiredVersion_IsRejectedAtHello_AndGetsInOnceTheRequirementIsMet()
{
BackendOptions options = _backend.App.Services.GetRequiredService<BackendOptions>();
options.MinAgentVersion = "9.0.0"; // 模拟器的版本是 0.0.1-sim
try
{
await using AgentSimulator old = await _backend.ConnectAgentAsync(hello: false);
var hello = new HelloParams { NodeVersion = "0.0.1-sim", NowUtcMs = TimeProvider.System.GetUtcNow().ToUnixTimeMilliseconds() };
RpcMessage reply = await old.RequestRawAsync(FleetMethods.Hello, JsonSerializer.SerializeToElement(hello, FleetRpcContext.Default.HelloParams));
Assert.Equal(FleetErrors.VersionRequired.Value, reply.Error!.Data!.Code);
Assert.Contains("9.0.0", reply.Error.Message);
}
finally
{
options.MinAgentVersion = null; // 共用的后端:恢复,别影响别的测试
}
await using AgentSimulator ok = await _backend.ConnectAgentAsync();
Assert.True(_backend.App.Services.GetRequiredService<MoShiro.Backend.Application.IAgentGateway>().IsOnline(ok.NodeId));
}
[Fact]
[Trait("Category", "Slow")]
public async Task AnAgentTheBackendRejectedForItsVersion_TriesAgainEveryFiveSeconds_AndComesOnlineWhenAccepted()
{
BackendOptions options = _backend.App.Services.GetRequiredService<BackendOptions>();
IAgentGateway gateway = _backend.App.Services.GetRequiredService<IAgentGateway>();
options.MinAgentVersion = "999.0.0";
try
{
await using AgentHarness agent = await AgentHarness.StartAsync(_backend, waitForConnection: false);
await Task.Delay(TimeSpan.FromSeconds(2));
Assert.False(gateway.IsOnline(agent.NodeId));
options.MinAgentVersion = null; // 通过了:下一次握手(最迟 5 秒)就上线
await BackendFixture.EventuallyAsync(() => Task.FromResult(gateway.IsOnline(agent.NodeId)), TimeSpan.FromSeconds(12));
}
finally
{
options.MinAgentVersion = null;
}
}
[Fact]
[Trait("Category", "Slow")]
public async Task AnAgentThatRequiresANewerBackend_DoesNotGoOnline_AndKeepsChecking()
{
IAgentGateway gateway = _backend.App.Services.GetRequiredService<IAgentGateway>();
await using AgentHarness agent = await AgentHarness.StartAsync(_backend, config => config.Fleet.MinServerVersion = "999.0.0", waitForConnection: false);
await Task.Delay(TimeSpan.FromSeconds(7)); // 至少重试过一次
Assert.False(gateway.IsOnline(agent.NodeId));
}
}