using System.Text; using System.Text.Json.Nodes; using Fleet.Core; using MoShiro.Probe; namespace MoShiro.Backend.Tests; /// 进程内的真实 Probe:用加入令牌注册出来的身份(节点自己生成的两把密钥)启动 。 public sealed class ProbeHarness : IAsyncDisposable { private readonly CancellationTokenSource _stop = new(); private readonly string _directory; private readonly Task _run; private readonly EnrolledProbe _enrolled; private ProbeHarness(string directory, ProbeApp app, EnrolledProbe enrolled) { _directory = directory; _enrolled = enrolled; App = app; _run = Task.Run(() => app.RunAsync(_stop.Token), CancellationToken.None); } public ProbeApp App { get; } public string Directory => _directory; public string ProbeId { get; init; } = ""; /// 用加入令牌注册(节点自己生成密钥),把面板地址和身份目录写进 probe.json,然后启动。 public static async Task StartAsync(BackendFixture backend, Action? configure = null) { EnrolledProbe enrolled = await backend.CreateProbeAsync(); string directory = enrolled.Directory; string path = Path.Combine(directory, "probe.json"); var written = new ProbeFile { Fleet = { Server = backend.BaseAddress.ToString(), IdentityDir = directory } }; await File.WriteAllTextAsync(path, System.Text.Json.JsonSerializer.Serialize(written, ProbeConfigContext.Default.ProbeFile), Encoding.UTF8); ProbeFile file = Fleet.Hosting.NodeConfig.Load(path, ProbeConfigContext.Default.ProbeFile); configure?.Invoke(file); var app = new ProbeApp(file, enrolled.Identity, directory, TimeProvider.System, NullNodeLog.Instance); return new ProbeHarness(directory, app, enrolled) { ProbeId = enrolled.ProbeId }; } public async ValueTask DisposeAsync() { await _stop.CancelAsync(); try { await _run.WaitAsync(TimeSpan.FromSeconds(15)); } catch (Exception ex) when (ex is OperationCanceledException or TimeoutException) { // 停止中 } App.Dispose(); _enrolled.Dispose(); _stop.Dispose(); try { System.IO.Directory.Delete(_directory, recursive: true); } catch (IOException) { // 临时目录清理失败不影响测试结果 } } }