using Fleet.Core;
using Fleet.Hosting;
using MoShiro.Agent;
namespace MoShiro.Backend.Tests;
/// 进程内的真实拨号节点:用加入令牌注册出来的身份启动 ,监听关闭(listen.enabled = false),只向 Backend 下发的目标拨出。
public sealed class DialerHarness : IAsyncDisposable
{
private readonly CancellationTokenSource _stop = new();
private readonly string _directory;
private readonly Task _run;
private readonly EnrolledDialer _enrolled;
private DialerHarness(string directory, AgentApp app, EnrolledDialer enrolled)
{
_directory = directory;
_enrolled = enrolled;
App = app;
_run = Task.Run(() => app.RunAsync(_stop.Token), CancellationToken.None);
}
public AgentApp App { get; }
public string Directory => _directory;
public string DialerId { get; init; } = "";
public static async Task StartAsync(BackendFixture backend, Action? configure = null)
{
EnrolledDialer enrolled = await backend.CreateDialerAsync();
var config = new AgentConfig { Fleet = { Server = backend.BaseAddress.ToString(), IdentityDir = enrolled.Directory }, Listen = { Enabled = false } };
configure?.Invoke(config);
var app = new AgentApp(config, enrolled.Identity, enrolled.Directory, TimeProvider.System, NullNodeLog.Instance);
return new DialerHarness(enrolled.Directory, app, enrolled) { DialerId = enrolled.DialerId };
}
public async ValueTask DisposeAsync()
{
await _stop.CancelAsync();
try
{
await _run.WaitAsync(TimeSpan.FromSeconds(15));
}
catch (Exception ex) when (ex is OperationCanceledException or TimeoutException)
{
// 停止中
}
await App.DisposeAsync();
_enrolled.Dispose();
_stop.Dispose();
try
{
System.IO.Directory.Delete(_directory, recursive: true);
}
catch (IOException)
{
// 临时目录清理失败不影响测试结果
}
}
}