diff --git a/Directory.Packages.props b/Directory.Packages.props index 7483a331..4b820513 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -85,7 +85,7 @@ - + @@ -124,13 +124,13 @@ provider that breaks the "managed only" rule, which is why it is opt-in per instance. --> - + - - - + + + diff --git a/tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests/NodeManagerHistoryReadTests.cs b/tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests/NodeManagerHistoryReadTests.cs index aa83493f..810d2df1 100644 --- a/tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests/NodeManagerHistoryReadTests.cs +++ b/tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests/NodeManagerHistoryReadTests.cs @@ -361,7 +361,7 @@ public sealed class NodeManagerHistoryReadTests : IDisposable fake.LastAggregate.ShouldBe(HistoryAggregateType.StandardDeviationPopulation); var diagnostics = (CustomNodeManager2)nm.Server.DiagnosticsNodeManager; - var folder = diagnostics.FindPredefinedNode(ObjectIds.HistoryServerCapabilities_AggregateFunctions, null)!; + var folder = diagnostics.FindPredefinedNode(ObjectIds.HistoryServerCapabilities_AggregateFunctions)!; AggregateFunctionMap.ByNodeId.Keys.Count(id => folder.ReferenceExists(ReferenceTypeIds.Organizes, false, id)) .ShouldBe(AggregateFunctionMap.ByNodeId.Count); @@ -447,20 +447,43 @@ public sealed class NodeManagerHistoryReadTests : IDisposable await host.DisposeAsync(); } - /// #677: the server's declared aggregate defaults are the SDK's own server defaults. + /// + /// #677 / #782: our declared aggregate defaults are pinned, and we DELIBERATELY diverge from the SDK on + /// TreatUncertainAsBad (SDK 1.5.378.182 default is true; Part 13 and our evaluators say false). The SDK-default + /// assertions are a tripwire: if a future SDK changes them, this fails and the divergence is re-decided. + /// [Fact] - public void The_server_aggregate_defaults_agree_with_the_SDK_AggregateManager() + public void The_server_aggregate_defaults_deliberately_diverge_from_the_SDK_on_TreatUncertainAsBad() { var sdk = new Opc.Ua.Server.AggregateManager(null!).GetDefaultConfiguration(null); var ours = ServerAggregateConfiguration.Defaults; - ours.TreatUncertainAsBad.ShouldBe(sdk.TreatUncertainAsBad); + ours.TreatUncertainAsBad.ShouldBeFalse(); + ours.PercentDataBad.ShouldBe((byte)100); + ours.PercentDataGood.ShouldBe((byte)100); + ours.UseSlopedExtrapolation.ShouldBeFalse(); + // What we believe the SDK default is (1.5.378.182): TreatUncertainAsBad flipped to true. + sdk.TreatUncertainAsBad.ShouldBeTrue("the SDK default changed - re-decide the deliberate divergence"); ours.PercentDataBad.ShouldBe(sdk.PercentDataBad); ours.PercentDataGood.ShouldBe(sdk.PercentDataGood); ours.UseSlopedExtrapolation.ShouldBe(sdk.UseSlopedExtrapolation); - ServerAggregateConfiguration.IsServable(sdk).ShouldBeTrue(); + ServerAggregateConfiguration.IsServable(ours).ShouldBeTrue(); + ServerAggregateConfiguration.IsServable(sdk).ShouldBeFalse("the SDK default is not what we serve"); ServerAggregateConfiguration.IsServable(null).ShouldBeTrue(); } + /// #782: the booted SDK server's AggregateManager (live AggregateFilter path) runs under OUR defaults. + [Fact] + public async Task The_booted_SDK_AggregateManager_default_is_our_TreatUncertainAsBad_false() + { + var (host, server) = await BootAsync(); + var cfg = server.CurrentInstance.AggregateManager.GetDefaultConfiguration(null); + cfg.TreatUncertainAsBad.ShouldBeFalse(); + cfg.PercentDataBad.ShouldBe(ServerAggregateConfiguration.PercentDataBad); + cfg.PercentDataGood.ShouldBe(ServerAggregateConfiguration.PercentDataGood); + cfg.UseSlopedExtrapolation.ShouldBeFalse(); + await host.DisposeAsync(); + } + /// #285: a Part 13 aggregate beyond the original five (Interpolative) is forwarded to the /// backend as its own member. [Fact]