Files
lmxopcua/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Wonderware.Tests/Backend/HistorianDataSourceStartQueryClassificationTests.cs
T
Joseph Doherty 64e3fbe035
v2-ci / build (push) Failing after 1m43s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
docs: backfill XML documentation across 756 files
Adds <summary>, <param>, <typeparam>, and <inheritdoc/> tags to public
members surfaced by commentchecker — resolves 5,847 of 5,869 issues
(99.6%) across three /fixdocs passes.
2026-05-28 08:10:17 -04:00

55 lines
3.0 KiB
C#

using ArchestrA;
using Shouldly;
using Xunit;
using ZB.MOM.WW.OtOpcUa.Driver.Historian.Wonderware.Backend;
namespace ZB.MOM.WW.OtOpcUa.Driver.Historian.Wonderware.Tests.Backend;
/// <summary>
/// Driver.Historian.Wonderware-008 regression. The previous implementation unconditionally
/// called <c>HandleConnectionError()</c> whenever <c>StartQuery</c> returned <c>false</c>,
/// which tore down the (relatively expensive) shared SDK connection on a query-class error
/// such as a bad tag name. A burst of bad-tag queries could therefore push an otherwise
/// healthy cluster node into cooldown via the picker's <c>MarkFailed</c>. The fix
/// classifies the SDK error code: connection-class codes drop the connection; query-class
/// codes leave it intact.
/// </summary>
[Trait("Category", "Unit")]
public sealed class HistorianDataSourceStartQueryClassificationTests
{
// ── Connection-class codes — the connection should be reset ───────────
/// <summary>Verifies that connection-class error codes are classified as connection errors.</summary>
/// <param name="code">The historian error code to test.</param>
[Theory]
[InlineData(HistorianAccessError.ErrorValue.FailedToConnect)]
[InlineData(HistorianAccessError.ErrorValue.FailedToCreateSession)]
[InlineData(HistorianAccessError.ErrorValue.NoReply)]
[InlineData(HistorianAccessError.ErrorValue.NotReady)]
[InlineData(HistorianAccessError.ErrorValue.NotInitialized)]
[InlineData(HistorianAccessError.ErrorValue.Stopping)]
[InlineData(HistorianAccessError.ErrorValue.Win32Exception)]
[InlineData(HistorianAccessError.ErrorValue.InvalidResponse)]
public void Connection_class_codes_are_classified_as_connection_errors(HistorianAccessError.ErrorValue code)
{
HistorianDataSource.IsConnectionClassError(code).ShouldBeTrue(
$"{code} is a connection/server failure — the SDK connection should be reset");
}
// ── Query-class codes — the connection should NOT be reset ────────────
/// <summary>Verifies that query-class error codes are NOT classified as connection errors.</summary>
/// <param name="code">The historian error code to test.</param>
[Theory]
[InlineData(HistorianAccessError.ErrorValue.InvalidArgument)] // bad tag name, etc.
[InlineData(HistorianAccessError.ErrorValue.ValidationFailed)] // bad query args
[InlineData(HistorianAccessError.ErrorValue.NotApplicable)] // wrong tag kind for query
[InlineData(HistorianAccessError.ErrorValue.NotImplemented)] // unsupported aggregate
[InlineData(HistorianAccessError.ErrorValue.NoData)] // empty range
public void Query_class_codes_are_NOT_classified_as_connection_errors(HistorianAccessError.ErrorValue code)
{
HistorianDataSource.IsConnectionClassError(code).ShouldBeFalse(
$"{code} is a query payload problem — must NOT tear down the SDK connection");
}
}