101 lines
3.1 KiB
C#
101 lines
3.1 KiB
C#
using FluentAssertions;
|
|
using Xunit;
|
|
using ZB.MOM.WW.LmxProxy.Client.Domain;
|
|
using ZB.MOM.WW.LmxProxy.Client.Tests.Fakes;
|
|
|
|
namespace ZB.MOM.WW.LmxProxy.Client.Tests;
|
|
|
|
public class LmxProxyClientSubscriptionTests
|
|
{
|
|
[Fact]
|
|
public async Task SubscribeAsync_InvokesCallbackForEachUpdate()
|
|
{
|
|
var (client, fake) = TestableClient.CreateConnected();
|
|
fake.SubscriptionMessages =
|
|
[
|
|
new VtqMessage
|
|
{
|
|
Tag = "Tag1",
|
|
Value = new TypedValue { DoubleValue = 1.0 },
|
|
TimestampUtcTicks = DateTime.UtcNow.Ticks,
|
|
Quality = new QualityCode { StatusCode = 0x00000000 }
|
|
},
|
|
new VtqMessage
|
|
{
|
|
Tag = "Tag2",
|
|
Value = new TypedValue { Int32Value = 42 },
|
|
TimestampUtcTicks = DateTime.UtcNow.Ticks,
|
|
Quality = new QualityCode { StatusCode = 0x00000000 }
|
|
}
|
|
];
|
|
|
|
var updates = new List<(string Tag, Vtq Vtq)>();
|
|
var subscription = await client.SubscribeAsync(
|
|
["Tag1", "Tag2"],
|
|
(tag, vtq) => updates.Add((tag, vtq)));
|
|
|
|
// Wait for processing to complete (fake yields all then stops)
|
|
await Task.Delay(500);
|
|
|
|
updates.Should().HaveCount(2);
|
|
updates[0].Tag.Should().Be("Tag1");
|
|
updates[0].Vtq.Value.Should().Be(1.0);
|
|
updates[1].Tag.Should().Be("Tag2");
|
|
updates[1].Vtq.Value.Should().Be(42);
|
|
|
|
subscription.Dispose();
|
|
client.Dispose();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task SubscribeAsync_InvokesStreamErrorOnFailure()
|
|
{
|
|
var (client, fake) = TestableClient.CreateConnected();
|
|
fake.SubscriptionException = new InvalidOperationException("Stream broke");
|
|
|
|
Exception? capturedError = null;
|
|
var subscription = await client.SubscribeAsync(
|
|
["Tag1"],
|
|
(_, _) => { },
|
|
ex => capturedError = ex);
|
|
|
|
// Wait for error to propagate
|
|
await Task.Delay(500);
|
|
|
|
capturedError.Should().NotBeNull();
|
|
capturedError.Should().BeOfType<InvalidOperationException>();
|
|
capturedError!.Message.Should().Be("Stream broke");
|
|
|
|
subscription.Dispose();
|
|
client.Dispose();
|
|
}
|
|
|
|
[Fact]
|
|
public async Task SubscribeAsync_DisposeStopsProcessing()
|
|
{
|
|
var (client, fake) = TestableClient.CreateConnected();
|
|
// Provide many messages but we'll dispose early
|
|
fake.SubscriptionMessages =
|
|
[
|
|
new VtqMessage
|
|
{
|
|
Tag = "Tag1",
|
|
Value = new TypedValue { DoubleValue = 1.0 },
|
|
TimestampUtcTicks = DateTime.UtcNow.Ticks,
|
|
Quality = new QualityCode { StatusCode = 0x00000000 }
|
|
}
|
|
];
|
|
|
|
var updates = new List<(string Tag, Vtq Vtq)>();
|
|
var subscription = await client.SubscribeAsync(
|
|
["Tag1"],
|
|
(tag, vtq) => updates.Add((tag, vtq)));
|
|
|
|
// Dispose immediately
|
|
subscription.Dispose();
|
|
|
|
// Should not throw
|
|
client.Dispose();
|
|
}
|
|
}
|