90 lines
3.0 KiB
C#
90 lines
3.0 KiB
C#
namespace Zcbot.WindowsNode.Tests;
|
|
|
|
public sealed class AdapterArchitectureTests
|
|
{
|
|
[Fact]
|
|
public void ContractLoaderReadsEveryPackagedAdapterWithUniqueCapabilities()
|
|
{
|
|
var descriptors = Directory.EnumerateDirectories(AdapterCatalog.AdapterRoot)
|
|
.Where(path => File.Exists(Path.Combine(path, "adapter.json")))
|
|
.Select(AdapterContractLoader.Load)
|
|
.ToArray();
|
|
|
|
Assert.NotEmpty(descriptors);
|
|
Assert.Equal(
|
|
descriptors.Length,
|
|
descriptors.Select(item => item.Contract.Capability).Distinct().Count());
|
|
Assert.All(descriptors, descriptor =>
|
|
{
|
|
Assert.StartsWith(descriptor.DirectoryPath, descriptor.EntrypointPath);
|
|
Assert.StartsWith(descriptor.DirectoryPath, descriptor.ContractPath);
|
|
Assert.Matches("^[0-9a-f]{64}$", descriptor.ContractSha256);
|
|
});
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ExecutionGateSerializesAllAdapterCapabilities()
|
|
{
|
|
using var gate = new JobExecutionGate();
|
|
using var first = await gate.EnterAsync(CancellationToken.None);
|
|
var secondEntered = false;
|
|
var second = Task.Run(async () =>
|
|
{
|
|
using var lease = await gate.EnterAsync(CancellationToken.None);
|
|
secondEntered = true;
|
|
});
|
|
|
|
await Task.Delay(30);
|
|
Assert.False(secondEntered);
|
|
Assert.True(gate.IsActive);
|
|
first.Dispose();
|
|
await second;
|
|
Assert.True(secondEntered);
|
|
Assert.False(gate.IsActive);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ExecutionGateHonorsCancellationWhileWaiting()
|
|
{
|
|
using var gate = new JobExecutionGate();
|
|
using var first = await gate.EnterAsync(CancellationToken.None);
|
|
using var stop = new CancellationTokenSource();
|
|
stop.Cancel();
|
|
|
|
await Assert.ThrowsAnyAsync<OperationCanceledException>(
|
|
async () => await gate.EnterAsync(stop.Token));
|
|
}
|
|
|
|
[Fact]
|
|
public void SoftwareCatalogKeepsThePublishedRuntimeIdentifiers()
|
|
{
|
|
Assert.Equal(["origin", "ansys", "blender"],
|
|
SoftwareCatalog.Definitions.Select(item => item.RuntimeId));
|
|
Assert.Equal("ZCBOT_ORIGIN_EXE",
|
|
SoftwareCatalog.ByRuntimeId("origin").EnvironmentVariable);
|
|
Assert.Equal("AWP_ROOT242",
|
|
SoftwareCatalog.ByRuntimeId("ansys").EnvironmentVariable);
|
|
Assert.Equal("ZCBOT_BLENDER_EXE",
|
|
SoftwareCatalog.ByRuntimeId("blender").EnvironmentVariable);
|
|
}
|
|
|
|
[Fact]
|
|
public void ProbeServiceCachesAndExplicitlyInvalidatesAProbe()
|
|
{
|
|
var calls = 0;
|
|
var service = new SoftwareProbeService(() =>
|
|
{
|
|
calls++;
|
|
return new AdapterRuntimeStatus(
|
|
"Test", "1.0", "1.0.0", "ready", $"probe-{calls}");
|
|
});
|
|
|
|
Assert.Equal("probe-1", service.Detect().Detail);
|
|
Assert.Equal("probe-1", service.Detect().Detail);
|
|
Assert.Equal(1, calls);
|
|
service.Invalidate();
|
|
Assert.Equal("probe-2", service.Detect().Detail);
|
|
Assert.Equal(2, calls);
|
|
}
|
|
}
|