fix(data-connection-layer): resolve DataConnectionLayer-002/003/004/005 — Resume supervision, concurrent dicts, subscribe-failure classification, write timeout
This commit is contained in:
@@ -6,6 +6,37 @@ using ScadaLink.DataConnectionLayer.Adapters;
|
||||
|
||||
namespace ScadaLink.DataConnectionLayer.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// DataConnectionLayer-003: structural regression guard. RealOpcUaClient's
|
||||
/// monitored-item / callback maps are read from the OPC UA SDK's publish threads
|
||||
/// concurrently with subscribe/disconnect mutations on other threads. They must be
|
||||
/// concurrent collections, not plain Dictionary. This is verified structurally
|
||||
/// because RealOpcUaClient wraps concrete OPC Foundation SDK types and cannot be
|
||||
/// exercised without a live OPC UA server.
|
||||
/// </summary>
|
||||
public class RealOpcUaClientThreadSafetyTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("_callbacks")]
|
||||
[InlineData("_monitoredItems")]
|
||||
public void DCL003_SharedDictionaryFields_AreConcurrentCollections(string fieldName)
|
||||
{
|
||||
var field = typeof(RealOpcUaClient)
|
||||
.GetField(fieldName,
|
||||
System.Reflection.BindingFlags.Instance |
|
||||
System.Reflection.BindingFlags.NonPublic);
|
||||
|
||||
Assert.NotNull(field);
|
||||
|
||||
var fieldType = field!.FieldType;
|
||||
Assert.True(
|
||||
fieldType.IsGenericType &&
|
||||
fieldType.GetGenericTypeDefinition() == typeof(System.Collections.Concurrent.ConcurrentDictionary<,>),
|
||||
$"RealOpcUaClient.{fieldName} must be a ConcurrentDictionary<,> for thread safety, " +
|
||||
$"but was {fieldType.Name}.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// WP-7: Tests for OPC UA adapter.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user