using XFESystem.Core;
using Xunit;
namespace XFESystem.Core.Tests;
public sealed class RenderBackendSelectionTests
{
private static RenderBackendProbeResult Software() => new(
new("CPU framebuffer", RenderAdapterKind.Software, RenderBackendKind.CpuFramebuffer, RenderExecutionScope.XFESystemGuest),
true, true, true, false, false, "Initialized framebuffer; pixel write and presentation verified.");
private static RenderBackendProbeResult Gpu(RenderAdapterKind adapter, RenderBackendKind kind = RenderBackendKind.NativeGpu,
RenderExecutionScope scope = RenderExecutionScope.XFESystemGuest, ushort vendor = 0x10DE) => new(
new(adapter.ToString(), adapter, kind, scope, vendor), true, true, true, true,
kind == RenderBackendKind.Cuda, "Actual driver/context, submission result and presentation verified by owning runtime.");
[Fact]
public void VerifiedDiscreteGpuIsPreferredRegardlessOfEnumerationOrder()
{
var discrete = Gpu(RenderAdapterKind.Discrete);
var selection = RenderBackendSelection.Select([Software(), Gpu(RenderAdapterKind.Integrated), discrete]);
Assert.Equal(discrete, selection.Selected);
Assert.True(selection.GpuAccelerationActive);
Assert.False(selection.CudaAccelerationActive);
}
[Fact]
public void FailedDiscreteInitializationFallsBackToVerifiedIntegratedGpu()
{
var integrated = Gpu(RenderAdapterKind.Integrated);
var failed = Gpu(RenderAdapterKind.Discrete) with { InitializationPassed = false, Evidence = "No native NVIDIA driver." };
var selection = RenderBackendSelection.Select([Software(), failed, integrated]);
Assert.Equal(integrated, selection.Selected);
Assert.Contains("No native NVIDIA driver.", selection.Attempts[1].Reason);
}
[Fact]
public void HostCudaSuccessCannotEnableCudaInTheGuest()
{
var selection = RenderBackendSelection.Select([Gpu(RenderAdapterKind.Discrete, RenderBackendKind.Cuda, RenderExecutionScope.Host), Software()]);
Assert.Equal(Software(), selection.Selected);
Assert.False(selection.GpuAccelerationActive);
Assert.False(selection.CudaAccelerationActive);
Assert.Contains("host hardware is not a guest backend", selection.Attempts[0].Reason);
}
[Fact]
public void VerifiedCudaIsOnlySelectableInItsActualExecutionScope()
{
var host = Gpu(RenderAdapterKind.Discrete, RenderBackendKind.Cuda, RenderExecutionScope.Host);
var selection = RenderBackendSelection.Select([host], RenderExecutionScope.Host);
Assert.Equal(host, selection.Selected);
Assert.True(selection.CudaAccelerationActive);
}
[Theory]
[InlineData(false, true, true)]
[InlineData(true, false, true)]
[InlineData(true, true, false)]
public void UnverifiedGpuNeverSupplantsAWorkingCpuRenderer(bool initialization, bool rendering, bool presentation)
{
var pending = Gpu(RenderAdapterKind.Discrete) with
{ InitializationPassed = initialization, RenderSelfTestPassed = rendering, PresentationSelfTestPassed = presentation };
var selection = RenderBackendSelection.Select([pending, Software()]);
Assert.Equal(Software(), selection.Selected);
Assert.False(selection.GpuAccelerationActive);
}
[Fact]
public void EnumeratedCudaAdapterWithoutCudaSubmissionIsRejected()
{
var cuda = Gpu(RenderAdapterKind.Discrete, RenderBackendKind.Cuda) with { CudaSubmissionVerified = false };
var selection = RenderBackendSelection.Select([cuda, Software()]);
Assert.False(selection.CudaAccelerationActive);
Assert.False(selection.Attempts[0].Eligible);
Assert.Contains("No CUDA kernel submission", selection.Attempts[0].Reason);
}
[Fact]
public void CudaCannotRunOnAnAmdAdapter()
{
var amd = Gpu(RenderAdapterKind.Integrated, RenderBackendKind.Cuda, vendor: 0x1002);
var selection = RenderBackendSelection.Select([amd, Software()]);
Assert.Equal(Software(), selection.Selected);
Assert.Contains("NVIDIA", selection.Attempts[0].Reason);
}
[Fact]
public void VirtIo2DIsCpuRasterizationEvenWhenAHostGpuCompositesTheDisplay()
{
var virtio = Software() with { Identity = new("virtio-gpu 2D", RenderAdapterKind.Virtual, RenderBackendKind.VirtIo2D, RenderExecutionScope.XFESystemGuest) };
var selection = RenderBackendSelection.Select([virtio]);
Assert.Equal(virtio, selection.Selected);
Assert.False(selection.GpuAccelerationActive);
Assert.False(selection.CudaAccelerationActive);
Assert.False(RenderBackendSelection.Select([virtio with { RasterizationOnGpu = true }]).HasBackend);
}
[Fact]
public void MissingEvidenceOrMissingDriverCannotInventASoftwareFallback()
{
Assert.False(RenderBackendSelection.Select([]).HasBackend);
Assert.False(RenderBackendSelection.Select([Software() with { Evidence = "" }]).HasBackend);
Assert.False(RenderBackendSelection.Select([Software() with { InitializationPassed = false }]).HasBackend);
}
[Fact]
public void GpuLabelAloneCannotConvertACpuFramebufferToAnAccelerator()
{
var mislabeled = Software() with
{ Identity = new("RTX 5090 framebuffer", RenderAdapterKind.Discrete, RenderBackendKind.CpuFramebuffer, RenderExecutionScope.XFESystemGuest, 0x10DE), RasterizationOnGpu = true };
var selection = RenderBackendSelection.Select([mislabeled, Software()]);
Assert.Equal(Software(), selection.Selected);
Assert.False(selection.GpuAccelerationActive);
}
private sealed class Probe(RenderBackendProbeResult result) : IRenderBackendProbe
{
public RenderBackendIdentity Identity => result.Identity;
public int Initializations { get; private set; }
public RenderBackendProbeResult InitializeAndVerify() { Initializations++; return result; }
}
[Fact]
public void InitializationEntryPointCallsEachOwningDriverExactlyOnce()
{
var software = new Probe(Software());
var discrete = new Probe(Gpu(RenderAdapterKind.Discrete) with { InitializationPassed = false });
var selected = RenderBackendSelection.InitializeAndSelect([discrete, software]);
Assert.Equal(1, discrete.Initializations);
Assert.Equal(1, software.Initializations);
Assert.Equal(Software(), selected.Selected);
}
private sealed class FailingProbe : IRenderBackendProbe
{
public RenderBackendIdentity Identity => Gpu(RenderAdapterKind.Discrete).Identity;
public RenderBackendProbeResult InitializeAndVerify() => throw new InvalidOperationException("Device initialization failed.");
}
[Fact]
public void FailedGpuDriverExceptionStillPermitsTheWorkingCpuRenderer()
{
var selection = RenderBackendSelection.InitializeAndSelect([new FailingProbe(), new Probe(Software())]);
Assert.Equal(Software(), selection.Selected);
Assert.Contains("Device initialization failed.", selection.Attempts[0].Reason);
}
[Fact]
public void UnknownEnumsAreRejectedRatherThanGivenHigherGpuPriority()
{
var invalid = Gpu((RenderAdapterKind)999);
Assert.False(RenderBackendSelection.Select([invalid]).HasBackend);
Assert.False(RenderBackendSelection.Select([invalid with { Identity = invalid.Identity with { Adapter = RenderAdapterKind.Discrete, Backend = (RenderBackendKind)999 } }]).HasBackend);
}
}
using XFESystem.Core;
using Xunit;
namespace XFESystem.Core.Tests;
public sealed class RenderBackendSelectionTests
{
private static RenderBackendProbeResult Software() => new(
new("CPU framebuffer", RenderAdapterKind.Software, RenderBackendKind.CpuFramebuffer, RenderExecutionScope.XFESystemGuest),
true, true, true, false, false, "Initialized framebuffer; pixel write and presentation verified.");
private static RenderBackendProbeResult Gpu(RenderAdapterKind adapter, RenderBackendKind kind = RenderBackendKind.NativeGpu,
RenderExecutionScope scope = RenderExecutionScope.XFESystemGuest, ushort vendor = 0x10DE) => new(
new(adapter.ToString(), adapter, kind, scope, vendor), true, true, true, true,
kind == RenderBackendKind.Cuda, "Actual driver/context, submission result and presentation verified by owning runtime.");
[Fact]
public void VerifiedDiscreteGpuIsPreferredRegardlessOfEnumerationOrder()
{
var discrete = Gpu(RenderAdapterKind.Discrete);
var selection = RenderBackendSelection.Select([Software(), Gpu(RenderAdapterKind.Integrated), discrete]);
Assert.Equal(discrete, selection.Selected);
Assert.True(selection.GpuAccelerationActive);
Assert.False(selection.CudaAccelerationActive);
}
[Fact]
public void FailedDiscreteInitializationFallsBackToVerifiedIntegratedGpu()
{
var integrated = Gpu(RenderAdapterKind.Integrated);
var failed = Gpu(RenderAdapterKind.Discrete) with { InitializationPassed = false, Evidence = "No native NVIDIA driver." };
var selection = RenderBackendSelection.Select([Software(), failed, integrated]);
Assert.Equal(integrated, selection.Selected);
Assert.Contains("No native NVIDIA driver.", selection.Attempts[1].Reason);
}
[Fact]
public void HostCudaSuccessCannotEnableCudaInTheGuest()
{
var selection = RenderBackendSelection.Select([Gpu(RenderAdapterKind.Discrete, RenderBackendKind.Cuda, RenderExecutionScope.Host), Software()]);
Assert.Equal(Software(), selection.Selected);
Assert.False(selection.GpuAccelerationActive);
Assert.False(selection.CudaAccelerationActive);
Assert.Contains("host hardware is not a guest backend", selection.Attempts[0].Reason);
}
[Fact]
public void VerifiedCudaIsOnlySelectableInItsActualExecutionScope()
{
var host = Gpu(RenderAdapterKind.Discrete, RenderBackendKind.Cuda, RenderExecutionScope.Host);
var selection = RenderBackendSelection.Select([host], RenderExecutionScope.Host);
Assert.Equal(host, selection.Selected);
Assert.True(selection.CudaAccelerationActive);
}
[Theory]
[InlineData(false, true, true)]
[InlineData(true, false, true)]
[InlineData(true, true, false)]
public void UnverifiedGpuNeverSupplantsAWorkingCpuRenderer(bool initialization, bool rendering, bool presentation)
{
var pending = Gpu(RenderAdapterKind.Discrete) with
{ InitializationPassed = initialization, RenderSelfTestPassed = rendering, PresentationSelfTestPassed = presentation };
var selection = RenderBackendSelection.Select([pending, Software()]);
Assert.Equal(Software(), selection.Selected);
Assert.False(selection.GpuAccelerationActive);
}
[Fact]
public void EnumeratedCudaAdapterWithoutCudaSubmissionIsRejected()
{
var cuda = Gpu(RenderAdapterKind.Discrete, RenderBackendKind.Cuda) with { CudaSubmissionVerified = false };
var selection = RenderBackendSelection.Select([cuda, Software()]);
Assert.False(selection.CudaAccelerationActive);
Assert.False(selection.Attempts[0].Eligible);
Assert.Contains("No CUDA kernel submission", selection.Attempts[0].Reason);
}
[Fact]
public void CudaCannotRunOnAnAmdAdapter()
{
var amd = Gpu(RenderAdapterKind.Integrated, RenderBackendKind.Cuda, vendor: 0x1002);
var selection = RenderBackendSelection.Select([amd, Software()]);
Assert.Equal(Software(), selection.Selected);
Assert.Contains("NVIDIA", selection.Attempts[0].Reason);
}
[Fact]
public void VirtIo2DIsCpuRasterizationEvenWhenAHostGpuCompositesTheDisplay()
{
var virtio = Software() with { Identity = new("virtio-gpu 2D", RenderAdapterKind.Virtual, RenderBackendKind.VirtIo2D, RenderExecutionScope.XFESystemGuest) };
var selection = RenderBackendSelection.Select([virtio]);
Assert.Equal(virtio, selection.Selected);
Assert.False(selection.GpuAccelerationActive);
Assert.False(selection.CudaAccelerationActive);
Assert.False(RenderBackendSelection.Select([virtio with { RasterizationOnGpu = true }]).HasBackend);
}
[Fact]
public void MissingEvidenceOrMissingDriverCannotInventASoftwareFallback()
{
Assert.False(RenderBackendSelection.Select([]).HasBackend);
Assert.False(RenderBackendSelection.Select([Software() with { Evidence = "" }]).HasBackend);
Assert.False(RenderBackendSelection.Select([Software() with { InitializationPassed = false }]).HasBackend);
}
[Fact]
public void GpuLabelAloneCannotConvertACpuFramebufferToAnAccelerator()
{
var mislabeled = Software() with
{ Identity = new("RTX 5090 framebuffer", RenderAdapterKind.Discrete, RenderBackendKind.CpuFramebuffer, RenderExecutionScope.XFESystemGuest, 0x10DE), RasterizationOnGpu = true };
var selection = RenderBackendSelection.Select([mislabeled, Software()]);
Assert.Equal(Software(), selection.Selected);
Assert.False(selection.GpuAccelerationActive);
}
private sealed class Probe(RenderBackendProbeResult result) : IRenderBackendProbe
{
public RenderBackendIdentity Identity => result.Identity;
public int Initializations { get; private set; }
public RenderBackendProbeResult InitializeAndVerify() { Initializations++; return result; }
}
[Fact]
public void InitializationEntryPointCallsEachOwningDriverExactlyOnce()
{
var software = new Probe(Software());
var discrete = new Probe(Gpu(RenderAdapterKind.Discrete) with { InitializationPassed = false });
var selected = RenderBackendSelection.InitializeAndSelect([discrete, software]);
Assert.Equal(1, discrete.Initializations);
Assert.Equal(1, software.Initializations);
Assert.Equal(Software(), selected.Selected);
}
private sealed class FailingProbe : IRenderBackendProbe
{
public RenderBackendIdentity Identity => Gpu(RenderAdapterKind.Discrete).Identity;
public RenderBackendProbeResult InitializeAndVerify() => throw new InvalidOperationException("Device initialization failed.");
}
[Fact]
public void FailedGpuDriverExceptionStillPermitsTheWorkingCpuRenderer()
{
var selection = RenderBackendSelection.InitializeAndSelect([new FailingProbe(), new Probe(Software())]);
Assert.Equal(Software(), selection.Selected);
Assert.Contains("Device initialization failed.", selection.Attempts[0].Reason);
}
[Fact]
public void UnknownEnumsAreRejectedRatherThanGivenHigherGpuPriority()
{
var invalid = Gpu((RenderAdapterKind)999);
Assert.False(RenderBackendSelection.Select([invalid]).HasBackend);
Assert.False(RenderBackendSelection.Select([invalid with { Identity = invalid.Identity with { Adapter = RenderAdapterKind.Discrete, Backend = (RenderBackendKind)999 } }]).HasBackend);
}
}