513fa1aa16
Comment/XML-doc changes only: - add summaries to ~10k test methods, fixtures, fakes and helpers (+ <param> on theories, <returns> on async Task methods, <inheritdoc/> on interface implementations the checker can resolve) - strip ~2.6k project-tracking references (WP*, P*-*, row-NN, Task N, #NN, Component-0NN) from comments, keeping the explanatory text; reword false positives in comments only - real docs on fakes implementing BCL/library interfaces (IDisposable, ILogger, IOptionsMonitor, IAsyncLifetime) - reword the last 5 src/ false positives (CWE-1236, failures-1, year-0001, M365) Only non-comment edits: four one-line nested classes split across lines so members can carry docs. Build 0 errors / 0 warnings.
91 lines
3.0 KiB
C#
91 lines
3.0 KiB
C#
using Microsoft.Extensions.Logging.Abstractions;
|
|
using ZB.MOM.WW.ScadaBridge.Commons.Messages.Scripting;
|
|
using ZB.MOM.WW.ScadaBridge.Host.Services;
|
|
|
|
namespace ZB.MOM.WW.ScadaBridge.Host.Tests;
|
|
|
|
/// <summary>
|
|
/// Unit tests for the in-process script-artifact change bus — delivery,
|
|
/// unsubscribe, and the swallow-and-log guard that keeps a faulting subscriber from
|
|
/// faulting the producer.
|
|
/// </summary>
|
|
public sealed class InProcessScriptArtifactChangeBusTests
|
|
{
|
|
private static InProcessScriptArtifactChangeBus NewBus() =>
|
|
new(NullLogger<InProcessScriptArtifactChangeBus>.Instance);
|
|
|
|
private static ScriptArtifactsChanged Sample(string kind = ScriptArtifactKinds.ApiMethod) =>
|
|
new(kind, new[] { "M1" }, "Management", DateTimeOffset.UnixEpoch);
|
|
|
|
/// <summary>Verifies that publish delivers to all current subscribers.</summary>
|
|
[Fact]
|
|
public void Publish_delivers_to_all_current_subscribers()
|
|
{
|
|
var bus = NewBus();
|
|
var a = new List<ScriptArtifactsChanged>();
|
|
var b = new List<ScriptArtifactsChanged>();
|
|
bus.Subscribe(a.Add);
|
|
bus.Subscribe(b.Add);
|
|
|
|
var n = Sample();
|
|
bus.Publish(n);
|
|
|
|
Assert.Same(n, Assert.Single(a));
|
|
Assert.Same(n, Assert.Single(b));
|
|
}
|
|
|
|
/// <summary>Verifies that disposing subscription stops delivery.</summary>
|
|
[Fact]
|
|
public void Disposing_subscription_stops_delivery()
|
|
{
|
|
var bus = NewBus();
|
|
var received = new List<ScriptArtifactsChanged>();
|
|
var token = bus.Subscribe(received.Add);
|
|
|
|
bus.Publish(Sample());
|
|
token.Dispose();
|
|
bus.Publish(Sample());
|
|
|
|
Assert.Single(received); // only the pre-dispose publish landed.
|
|
}
|
|
|
|
/// <summary>Verifies that dispose is idempotent.</summary>
|
|
[Fact]
|
|
public void Dispose_is_idempotent()
|
|
{
|
|
var bus = NewBus();
|
|
var received = new List<ScriptArtifactsChanged>();
|
|
var token = bus.Subscribe(received.Add);
|
|
|
|
token.Dispose();
|
|
token.Dispose(); // must not throw nor corrupt the handler list.
|
|
|
|
bus.Publish(Sample());
|
|
Assert.Empty(received);
|
|
}
|
|
|
|
/// <summary>Verifies that a faulting subscriber does not prevent delivery to others nor throw.</summary>
|
|
[Fact]
|
|
public void A_faulting_subscriber_does_not_prevent_delivery_to_others_nor_throw()
|
|
{
|
|
var bus = NewBus();
|
|
var good = new List<ScriptArtifactsChanged>();
|
|
bus.Subscribe(_ => throw new InvalidOperationException("bad consumer"));
|
|
bus.Subscribe(good.Add);
|
|
|
|
// Publish must not propagate the subscriber fault...
|
|
var ex = Record.Exception(() => bus.Publish(Sample()));
|
|
Assert.Null(ex);
|
|
// ...and the well-behaved subscriber still receives it.
|
|
Assert.Single(good);
|
|
}
|
|
|
|
/// <summary>Verifies that publish with no subscribers is a noop.</summary>
|
|
[Fact]
|
|
public void Publish_with_no_subscribers_is_a_noop()
|
|
{
|
|
var bus = NewBus();
|
|
Assert.Null(Record.Exception(() => bus.Publish(Sample())));
|
|
}
|
|
}
|