Retain and replay ServiceLevel across publisher binding and failures
v2-ci / unit-tests (pull_request) Waiting to run

This commit is contained in:
Joseph Doherty
2026-10-13 13:26:27 -04:00
parent 6f0674296b
commit c8e3e279b4
13 changed files with 545 additions and 30 deletions
@@ -19,6 +19,40 @@ public sealed class SdkServiceLevelPublisherTests : IDisposable
Path.GetTempPath(),
$"otopcua-pki-{Guid.NewGuid():N}");
[Fact]
public void Missing_ServiceLevel_is_reported_as_failure()
{
var server = System.Reflection.DispatchProxy.Create<IServerInternal, FaultingServer>();
var publisher = new SdkServiceLevelPublisher(server, NullLogger<SdkServiceLevelPublisher>.Instance);
Should.Throw<InvalidOperationException>(() => publisher.Publish(0));
}
[Fact]
public void Sdk_write_failure_propagates_the_original_exception()
{
var server = System.Reflection.DispatchProxy.Create<IServerInternal, FaultingServer>();
var proxy = (FaultingServer)(object)server;
proxy.Node = new Opc.Ua.ServerObjectState(null)
{
ServiceLevel = new Opc.Ua.PropertyState<byte>(null),
};
proxy.Fault = new InvalidOperationException("controlled diagnostics failure");
var publisher = new SdkServiceLevelPublisher(server, NullLogger<SdkServiceLevelPublisher>.Instance);
Should.Throw<InvalidOperationException>(() => publisher.Publish(0)).ShouldBeSameAs(proxy.Fault);
}
public class FaultingServer : System.Reflection.DispatchProxy
{
public Opc.Ua.ServerObjectState? Node { get; set; }
public Exception? Fault { get; set; }
protected override object? Invoke(System.Reflection.MethodInfo? method, object?[]? args)
{
if (method?.Name == "get_ServerObject") return Node;
if (method?.Name == "get_DiagnosticsLock") throw Fault!;
throw new NotSupportedException(method?.Name);
}
}
/// <summary>Verifies that the publisher writes values to the standard Server.ServiceLevel variable.</summary>
[Fact]
public async Task Publish_writes_value_to_Server_ServiceLevel_variable()