Apply code style formatting and restore partial modifiers on Avalonia views
Linter/formatter pass across the full codebase. Restores required partial keyword on AXAML code-behind classes that the formatter incorrectly removed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -7,20 +7,19 @@ using Opc.Ua;
|
||||
using Opc.Ua.Client;
|
||||
using Shouldly;
|
||||
using Xunit;
|
||||
using ZB.MOM.WW.LmxOpcUa.Host.Domain;
|
||||
using ZB.MOM.WW.LmxOpcUa.Tests.Helpers;
|
||||
|
||||
namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
{
|
||||
/// <summary>
|
||||
/// Integration tests verifying multi-client subscription sync and concurrent operations.
|
||||
/// Integration tests verifying multi-client subscription sync and concurrent operations.
|
||||
/// </summary>
|
||||
public class MultiClientTests
|
||||
{
|
||||
// ── Subscription Sync ─────────────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Confirms that multiple OPC UA clients subscribed to the same tag all receive the same runtime update.
|
||||
/// Confirms that multiple OPC UA clients subscribed to the same tag all receive the same runtime update.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task MultipleClients_SubscribeToSameTag_AllReceiveDataChanges()
|
||||
@@ -33,14 +32,14 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
var notifications = new ConcurrentDictionary<int, List<MonitoredItemNotification>>();
|
||||
var subscriptions = new List<Subscription>();
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
var client = new OpcUaTestClient();
|
||||
await client.ConnectAsync(fixture.EndpointUrl);
|
||||
clients.Add(client);
|
||||
|
||||
var nodeId = client.MakeNodeId("TestMachine_001.MachineID");
|
||||
var (sub, item) = await client.SubscribeAsync(nodeId, intervalMs: 100);
|
||||
var (sub, item) = await client.SubscribeAsync(nodeId, 100);
|
||||
subscriptions.Add(sub);
|
||||
|
||||
var clientIndex = i;
|
||||
@@ -55,14 +54,12 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
await Task.Delay(500); // let subscriptions settle
|
||||
|
||||
// Simulate data change
|
||||
fixture.MxProxy!.SimulateDataChangeByAddress("TestMachine_001.MachineID", "MACHINE_42", 192);
|
||||
fixture.MxProxy!.SimulateDataChangeByAddress("TestMachine_001.MachineID", "MACHINE_42");
|
||||
await Task.Delay(1000); // let publish cycle deliver
|
||||
|
||||
// All 3 clients should have received the notification
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (var i = 0; i < 3; i++)
|
||||
notifications[i].Count.ShouldBeGreaterThan(0, $"Client {i} did not receive notification");
|
||||
}
|
||||
|
||||
foreach (var sub in subscriptions) await sub.DeleteAsync(true);
|
||||
foreach (var c in clients) c.Dispose();
|
||||
@@ -74,7 +71,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Confirms that one client disconnecting does not stop remaining clients from receiving updates.
|
||||
/// Confirms that one client disconnecting does not stop remaining clients from receiving updates.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task Client_Disconnects_OtherClientsStillReceive()
|
||||
@@ -97,8 +94,14 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
var (sub2, _) = await client2.SubscribeAsync(client2.MakeNodeId("TestMachine_001.MachineID"), 100);
|
||||
var (sub3, item3) = await client3.SubscribeAsync(client3.MakeNodeId("TestMachine_001.MachineID"), 100);
|
||||
|
||||
item1.Notification += (_, e) => { if (e.NotificationValue is MonitoredItemNotification n) notifications1.Add(n); };
|
||||
item3.Notification += (_, e) => { if (e.NotificationValue is MonitoredItemNotification n) notifications3.Add(n); };
|
||||
item1.Notification += (_, e) =>
|
||||
{
|
||||
if (e.NotificationValue is MonitoredItemNotification n) notifications1.Add(n);
|
||||
};
|
||||
item3.Notification += (_, e) =>
|
||||
{
|
||||
if (e.NotificationValue is MonitoredItemNotification n) notifications3.Add(n);
|
||||
};
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
@@ -108,11 +111,13 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
await Task.Delay(500); // let server process disconnect
|
||||
|
||||
// Simulate data change — should not crash, clients 1+3 should still receive
|
||||
fixture.MxProxy!.SimulateDataChangeByAddress("TestMachine_001.MachineID", "AFTER_DISCONNECT", 192);
|
||||
fixture.MxProxy!.SimulateDataChangeByAddress("TestMachine_001.MachineID", "AFTER_DISCONNECT");
|
||||
await Task.Delay(1000);
|
||||
|
||||
notifications1.Count.ShouldBeGreaterThan(0, "Client 1 should still receive after client 2 disconnected");
|
||||
notifications3.Count.ShouldBeGreaterThan(0, "Client 3 should still receive after client 2 disconnected");
|
||||
notifications1.Count.ShouldBeGreaterThan(0,
|
||||
"Client 1 should still receive after client 2 disconnected");
|
||||
notifications3.Count.ShouldBeGreaterThan(0,
|
||||
"Client 3 should still receive after client 2 disconnected");
|
||||
|
||||
await sub1.DeleteAsync(true);
|
||||
await sub3.DeleteAsync(true);
|
||||
@@ -126,7 +131,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Confirms that one client unsubscribing does not interrupt delivery to other subscribed clients.
|
||||
/// Confirms that one client unsubscribing does not interrupt delivery to other subscribed clients.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task Client_Unsubscribes_OtherClientsStillReceive()
|
||||
@@ -144,7 +149,10 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
|
||||
var (sub1, _) = await client1.SubscribeAsync(client1.MakeNodeId("TestMachine_001.MachineID"), 100);
|
||||
var (sub2, item2) = await client2.SubscribeAsync(client2.MakeNodeId("TestMachine_001.MachineID"), 100);
|
||||
item2.Notification += (_, e) => { if (e.NotificationValue is MonitoredItemNotification n) notifications2.Add(n); };
|
||||
item2.Notification += (_, e) =>
|
||||
{
|
||||
if (e.NotificationValue is MonitoredItemNotification n) notifications2.Add(n);
|
||||
};
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
@@ -153,10 +161,11 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
await Task.Delay(500);
|
||||
|
||||
// Simulate data change — client 2 should still receive
|
||||
fixture.MxProxy!.SimulateDataChangeByAddress("TestMachine_001.MachineID", "AFTER_UNSUB", 192);
|
||||
fixture.MxProxy!.SimulateDataChangeByAddress("TestMachine_001.MachineID", "AFTER_UNSUB");
|
||||
await Task.Delay(1000);
|
||||
|
||||
notifications2.Count.ShouldBeGreaterThan(0, "Client 2 should still receive after client 1 unsubscribed");
|
||||
notifications2.Count.ShouldBeGreaterThan(0,
|
||||
"Client 2 should still receive after client 1 unsubscribed");
|
||||
|
||||
await sub2.DeleteAsync(true);
|
||||
client1.Dispose();
|
||||
@@ -169,7 +178,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Confirms that clients subscribed to different tags only receive updates for their own monitored data.
|
||||
/// Confirms that clients subscribed to different tags only receive updates for their own monitored data.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task MultipleClients_SubscribeToDifferentTags_EachGetsOwnData()
|
||||
@@ -187,15 +196,22 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
var notifications2 = new ConcurrentBag<MonitoredItemNotification>();
|
||||
|
||||
var (sub1, item1) = await client1.SubscribeAsync(client1.MakeNodeId("TestMachine_001.MachineID"), 100);
|
||||
var (sub2, item2) = await client2.SubscribeAsync(client2.MakeNodeId("DelmiaReceiver_001.DownloadPath"), 100);
|
||||
var (sub2, item2) =
|
||||
await client2.SubscribeAsync(client2.MakeNodeId("DelmiaReceiver_001.DownloadPath"), 100);
|
||||
|
||||
item1.Notification += (_, e) => { if (e.NotificationValue is MonitoredItemNotification n) notifications1.Add(n); };
|
||||
item2.Notification += (_, e) => { if (e.NotificationValue is MonitoredItemNotification n) notifications2.Add(n); };
|
||||
item1.Notification += (_, e) =>
|
||||
{
|
||||
if (e.NotificationValue is MonitoredItemNotification n) notifications1.Add(n);
|
||||
};
|
||||
item2.Notification += (_, e) =>
|
||||
{
|
||||
if (e.NotificationValue is MonitoredItemNotification n) notifications2.Add(n);
|
||||
};
|
||||
|
||||
await Task.Delay(500);
|
||||
|
||||
// Only change MachineID
|
||||
fixture.MxProxy!.SimulateDataChangeByAddress("TestMachine_001.MachineID", "CHANGED", 192);
|
||||
fixture.MxProxy!.SimulateDataChangeByAddress("TestMachine_001.MachineID", "CHANGED");
|
||||
await Task.Delay(1000);
|
||||
|
||||
notifications1.Count.ShouldBeGreaterThan(0, "Client 1 should receive MachineID change");
|
||||
@@ -219,7 +235,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
// ── Concurrent Operation Tests ────────────────────────────────────
|
||||
|
||||
/// <summary>
|
||||
/// Confirms that concurrent browse operations from several clients all complete successfully.
|
||||
/// Confirms that concurrent browse operations from several clients all complete successfully.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task ConcurrentBrowseFromMultipleClients_AllSucceed()
|
||||
@@ -230,7 +246,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
try
|
||||
{
|
||||
var clients = new List<OpcUaTestClient>();
|
||||
for (int i = 0; i < 5; i++)
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
var c = new OpcUaTestClient();
|
||||
await c.ConnectAsync(fixture.EndpointUrl);
|
||||
@@ -262,7 +278,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Confirms that concurrent browse requests return consistent results across clients.
|
||||
/// Confirms that concurrent browse requests return consistent results across clients.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task ConcurrentBrowse_AllReturnSameResults()
|
||||
@@ -272,7 +288,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
try
|
||||
{
|
||||
var clients = new List<OpcUaTestClient>();
|
||||
for (int i = 0; i < 5; i++)
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
var c = new OpcUaTestClient();
|
||||
await c.ConnectAsync(fixture.EndpointUrl);
|
||||
@@ -287,7 +303,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
|
||||
// All should get identical child lists
|
||||
var firstResult = results[0].Select(r => r.Name).OrderBy(n => n).ToList();
|
||||
for (int i = 1; i < results.Length; i++)
|
||||
for (var i = 1; i < results.Length; i++)
|
||||
{
|
||||
var thisResult = results[i].Select(r => r.Name).OrderBy(n => n).ToList();
|
||||
thisResult.ShouldBe(firstResult, $"Client {i} got different browse results");
|
||||
@@ -302,7 +318,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Confirms that simultaneous browse and subscribe operations do not interfere with one another.
|
||||
/// Confirms that simultaneous browse and subscribe operations do not interfere with one another.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task ConcurrentBrowseAndSubscribe_NoInterference()
|
||||
@@ -312,7 +328,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
try
|
||||
{
|
||||
var clients = new List<OpcUaTestClient>();
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (var i = 0; i < 4; i++)
|
||||
{
|
||||
var c = new OpcUaTestClient();
|
||||
await c.ConnectAsync(fixture.EndpointUrl);
|
||||
@@ -340,7 +356,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Confirms that concurrent subscribe, read, and browse operations complete without deadlocking the server.
|
||||
/// Confirms that concurrent subscribe, read, and browse operations complete without deadlocking the server.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task ConcurrentSubscribeAndRead_NoDeadlock()
|
||||
@@ -380,7 +396,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Confirms that repeated client churn does not leave the server in an unstable state.
|
||||
/// Confirms that repeated client churn does not leave the server in an unstable state.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task RapidConnectDisconnect_ServerStaysStable()
|
||||
@@ -390,7 +406,7 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
try
|
||||
{
|
||||
// Rapidly connect, browse, disconnect — 10 iterations
|
||||
for (int i = 0; i < 10; i++)
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
using var client = new OpcUaTestClient();
|
||||
await client.ConnectAsync(fixture.EndpointUrl);
|
||||
@@ -411,4 +427,4 @@ namespace ZB.MOM.WW.LmxOpcUa.Tests.Integration
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user