Files
2026-10-07 16:57:34 +08:00

70 lines
2.5 KiB
C#

using System.Text;
using System.Text.Json.Nodes;
using Fleet.Core;
using MoShiro.Probe;
namespace MoShiro.Backend.Tests;
/// <summary>进程内的真实 Probe:用加入令牌注册出来的身份(节点自己生成的两把密钥)启动 <see cref="ProbeApp"/>。</summary>
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; } = "";
/// <summary>用加入令牌注册(节点自己生成密钥),把面板地址和身份目录写进 <c>probe.json</c>,然后启动。</summary>
public static async Task<ProbeHarness> StartAsync(BackendFixture backend, Action<ProbeFile>? 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, new Fleet.Hosting.ConsoleNodeLog(TimeProvider.System, Console.Out));
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)
{
// 临时目录清理失败不影响测试结果
}
}
}