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 { private readonly BackendFixture _backend; public VersionRequirementTests(BackendFixture backend) { _backend = backend; } [Fact] public async Task AnAgentBelowTheRequiredVersion_IsRejectedAtHello_AndGetsInOnceTheRequirementIsMet() { BackendOptions options = _backend.App.Services.GetRequiredService(); 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().IsOnline(ok.NodeId)); } [Fact] [Trait("Category", "Slow")] public async Task AnAgentTheBackendRejectedForItsVersion_TriesAgainEveryFiveSeconds_AndComesOnlineWhenAccepted() { BackendOptions options = _backend.App.Services.GetRequiredService(); IAgentGateway gateway = _backend.App.Services.GetRequiredService(); 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(); 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)); } }