feat: verify Tornado PGM KTAP connection
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
using MBN_STOCK_WEBVIEW.Playout.Diagnostics;
|
||||
using MBN_STOCK_WEBVIEW.Playout.Interop;
|
||||
using MBN_STOCK_WEBVIEW.Playout.Registration;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace MBN_STOCK_WEBVIEW.Playout.Tests;
|
||||
|
||||
public sealed class InstalledK3dInteropMetadataTests
|
||||
{
|
||||
[Fact]
|
||||
public void ApprovedSha256_RequiresAndDecodesExactly64HexCharacters()
|
||||
{
|
||||
var parsed = InstalledK3dInteropMetadata.ParseApprovedSha256(
|
||||
"0123456789abcdef0123456789ABCDEF0123456789abcdef0123456789ABCDEF");
|
||||
|
||||
Assert.Equal(32, parsed.Length);
|
||||
Assert.Equal(0x01, parsed[0]);
|
||||
Assert.Equal(0xEF, parsed[^1]);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(null)]
|
||||
[InlineData("")]
|
||||
[InlineData("0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde")]
|
||||
[InlineData(" 123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")]
|
||||
[InlineData("g123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef")]
|
||||
public void ApprovedSha256_RejectsMissingMalformedOrWhitespaceValues(string? value)
|
||||
{
|
||||
Assert.Throws<InstalledK3dInteropMetadataUnavailableException>(
|
||||
() => InstalledK3dInteropMetadata.ParseApprovedSha256(value));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApprovedSha256_RequiresExactContentForEitherBinaryPin()
|
||||
{
|
||||
byte[] content = [1, 2, 3, 4];
|
||||
var approved = Convert.ToHexString(SHA256.HashData(content));
|
||||
using var matching = new MemoryStream(content);
|
||||
using var different = new MemoryStream([1, 2, 3, 5]);
|
||||
|
||||
InstalledK3dInteropMetadata.ValidateApprovedSha256(matching, approved);
|
||||
Assert.Throws<InstalledK3dInteropMetadataUnavailableException>(
|
||||
() => InstalledK3dInteropMetadata.ValidateApprovedSha256(different, approved));
|
||||
Assert.Equal(
|
||||
"MBN_STOCK_K3D_NATIVE_SHA256",
|
||||
InstalledK3dInteropMetadata.ApprovedNativeSha256EnvironmentVariable);
|
||||
Assert.Equal(
|
||||
"MBN_STOCK_K3D_INTEROP_SHA256",
|
||||
InstalledK3dInteropMetadata.ApprovedSha256EnvironmentVariable);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void FileLease_KeepsNativeAndInteropFilesWriteLocked()
|
||||
{
|
||||
var directory = Path.Combine(Path.GetTempPath(), $"k3d-lease-{Guid.NewGuid():N}");
|
||||
Directory.CreateDirectory(directory);
|
||||
var nativePath = Path.Combine(directory, "native.dll");
|
||||
var interopPath = Path.Combine(directory, "interop.dll");
|
||||
File.WriteAllBytes(nativePath, [1]);
|
||||
File.WriteAllBytes(interopPath, [2]);
|
||||
|
||||
InstalledK3dInteropFileLease? lease = null;
|
||||
try
|
||||
{
|
||||
lease = new InstalledK3dInteropFileLease(
|
||||
new FileStream(nativePath, FileMode.Open, FileAccess.Read, FileShare.Read),
|
||||
new FileStream(interopPath, FileMode.Open, FileAccess.Read, FileShare.Read));
|
||||
|
||||
Assert.Throws<IOException>(() => OpenForWrite(nativePath).Dispose());
|
||||
Assert.Throws<IOException>(() => OpenForWrite(interopPath).Dispose());
|
||||
}
|
||||
finally
|
||||
{
|
||||
lease?.InteropStream.Dispose();
|
||||
lease?.NativeStream.Dispose();
|
||||
Directory.Delete(directory, recursive: true);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegisteredPaths_MapOnlyExactX64VendorLayout()
|
||||
{
|
||||
const string native = @"C:\Vendor\K3DAsyncEngine\DLL\x64\Release\K3DAsyncEngine.dll";
|
||||
var paths = InstalledK3dInteropMetadata.ResolveRegisteredPaths(ReadySnapshot(native));
|
||||
|
||||
Assert.Equal(Path.GetFullPath(native), paths.NativeBinaryPath);
|
||||
Assert.Equal(
|
||||
Path.GetFullPath(
|
||||
@"C:\Vendor\K3DAsyncEngine\Bin\x64\C#\Interop.K3DAsyncEngineLib.dll"),
|
||||
paths.InteropAssemblyPath);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegisteredPaths_RejectDivergentClassBinary()
|
||||
{
|
||||
const string native = @"C:\Vendor\K3DAsyncEngine\DLL\x64\Release\K3DAsyncEngine.dll";
|
||||
var snapshot = ReadySnapshot(native) with
|
||||
{
|
||||
EventHandler = ReadySnapshot(native).EventHandler with
|
||||
{
|
||||
InprocServerPath =
|
||||
@"C:\Other\K3DAsyncEngine\DLL\x64\Release\K3DAsyncEngine.dll"
|
||||
}
|
||||
};
|
||||
|
||||
Assert.Throws<InstalledK3dInteropMetadataUnavailableException>(
|
||||
() => InstalledK3dInteropMetadata.ResolveRegisteredPaths(snapshot));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RegisteredPaths_RejectUnexpectedNativeLayout()
|
||||
{
|
||||
const string native = @"C:\Vendor\K3DAsyncEngine\bin\K3DAsyncEngine.dll";
|
||||
|
||||
Assert.Throws<InstalledK3dInteropMetadataUnavailableException>(
|
||||
() => InstalledK3dInteropMetadata.ResolveRegisteredPaths(ReadySnapshot(native)));
|
||||
}
|
||||
|
||||
private static K3dRegistrySnapshot ReadySnapshot(string nativePath) => new(
|
||||
true,
|
||||
nativePath,
|
||||
new K3dClassRegistrationSnapshot(
|
||||
true,
|
||||
K3dComConstants.KaEngineProgId,
|
||||
K3dComConstants.KaEngineClassId,
|
||||
nativePath,
|
||||
K3dComConstants.ApartmentThreadingModel,
|
||||
K3dComConstants.TypeLibraryId),
|
||||
new K3dClassRegistrationSnapshot(
|
||||
true,
|
||||
K3dComConstants.KaEventHandlerProgId,
|
||||
K3dComConstants.KaEventHandlerClassId,
|
||||
nativePath,
|
||||
K3dComConstants.ApartmentThreadingModel,
|
||||
K3dComConstants.TypeLibraryId),
|
||||
false);
|
||||
|
||||
private static FileStream OpenForWrite(string path) => new(
|
||||
path,
|
||||
FileMode.Open,
|
||||
FileAccess.Write,
|
||||
FileShare.ReadWrite | FileShare.Delete);
|
||||
}
|
||||
Reference in New Issue
Block a user