test(engine): teach FakeNdiInterop to model finder failure + use-after-dispose
All checks were successful
CI / build-and-test (push) Successful in 30s
All checks were successful
CI / build-and-test (push) Successful in 30s
Additive, backwards-compatible test-double extensions so the discovery
rebuild failure path is observable:
- CreateFinderHook: optional callback invoked on every CreateFinder,
letting a test throw on the Nth call to simulate a runtime that
refuses to build a replacement finder.
- FinderCreatedCount: how many finders were built.
- The fake find handle now flips a Disposed flag, and GetCurrentSources
throws ObjectDisposedException if asked to read a disposed finder —
so a regression that polls a retired finder fails loudly instead of
silently passing (the fake previously ignored the handle entirely).
Default behavior is unchanged when CreateFinderHook is null.
This commit is contained in:
parent
97a40f3ac2
commit
886e20e501
1 changed files with 26 additions and 2 deletions
|
|
@ -24,12 +24,35 @@ public sealed class FakeNdiInterop : INdiInterop
|
|||
/// <summary>Per-output <c>groups</c> string seen by <see cref="CreateSender"/>; null = default Public.</summary>
|
||||
public Dictionary<string, string?> SenderGroups { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// Number of finders created so far (initial construction + every rebuild).
|
||||
/// Lets tests assert how many times the discovery service tried to rebuild.
|
||||
/// </summary>
|
||||
public int FinderCreatedCount { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Optional hook invoked at the top of every <see cref="CreateFinder"/> call,
|
||||
/// receiving the 1-based creation ordinal. Throw from here to simulate a runtime
|
||||
/// that refuses to build a finder (e.g. the rebuild-failure path); return normally
|
||||
/// to allow creation. Null (default) = always succeed.
|
||||
/// </summary>
|
||||
public Action<int>? CreateFinderHook { get; set; }
|
||||
|
||||
public NdiFindHandle CreateFinder(string? groups = null)
|
||||
{
|
||||
FinderCreatedCount++;
|
||||
CreateFinderHook?.Invoke(FinderCreatedCount);
|
||||
LastFinderGroups = groups;
|
||||
return new FakeFindHandle();
|
||||
}
|
||||
public IReadOnlyList<string> GetCurrentSources(NdiFindHandle finder) => Sources.ToArray();
|
||||
|
||||
public IReadOnlyList<string> GetCurrentSources(NdiFindHandle finder)
|
||||
{
|
||||
if (finder is FakeFindHandle { Disposed: true })
|
||||
throw new ObjectDisposedException(nameof(FakeFindHandle),
|
||||
"GetCurrentSources called on a finder that was already disposed.");
|
||||
return Sources.ToArray();
|
||||
}
|
||||
|
||||
public NdiReceiverHandle CreateReceiver(string sourceFullName)
|
||||
{
|
||||
|
|
@ -72,7 +95,8 @@ public sealed class FakeNdiInterop : INdiInterop
|
|||
|
||||
private sealed class FakeFindHandle : NdiFindHandle
|
||||
{
|
||||
public override void Dispose() { }
|
||||
public bool Disposed { get; private set; }
|
||||
public override void Dispose() => Disposed = true;
|
||||
}
|
||||
|
||||
private sealed class FakeReceiverHandle : NdiReceiverHandle
|
||||
|
|
|
|||
Loading…
Reference in a new issue