using Opc.Ua; using Shouldly; using Xunit; namespace ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests; /// Review 01 P6 — the SDK request and transport quotas are configurable (OpcUa:Quotas:*) and /// default to exactly what used to be hard-coded. public sealed class OpcUaApplicationHostQuotaTests { [Fact] public void Default_request_quotas_are_the_former_hard_coded_values() { var config = new ServerConfiguration(); OpcUaApplicationHost.ApplyRequestQuotas(config, new OpcUaQuotaOptions()); config.MinRequestThreadCount.ShouldBe(5); config.MaxRequestThreadCount.ShouldBe(100); config.MaxQueuedRequestCount.ShouldBe(200); } [Fact] public void Configured_request_quotas_are_applied() { var config = new ServerConfiguration(); OpcUaApplicationHost.ApplyRequestQuotas(config, new OpcUaQuotaOptions { MinRequestThreadCount = 8, MaxRequestThreadCount = 250, MaxQueuedRequestCount = 1000, }); config.MinRequestThreadCount.ShouldBe(8); config.MaxRequestThreadCount.ShouldBe(250); config.MaxQueuedRequestCount.ShouldBe(1000); } [Fact] public void Unset_transport_quotas_keep_the_sdk_defaults() { var sdkDefault = new TransportQuotas(); var built = OpcUaApplicationHost.BuildTransportQuotas(new OpcUaQuotaOptions()); built.OperationTimeout.ShouldBe(sdkDefault.OperationTimeout); built.MaxStringLength.ShouldBe(sdkDefault.MaxStringLength); built.MaxByteStringLength.ShouldBe(sdkDefault.MaxByteStringLength); built.MaxArrayLength.ShouldBe(sdkDefault.MaxArrayLength); built.MaxMessageSize.ShouldBe(sdkDefault.MaxMessageSize); built.MaxBufferSize.ShouldBe(sdkDefault.MaxBufferSize); built.ChannelLifetime.ShouldBe(sdkDefault.ChannelLifetime); built.SecurityTokenLifetime.ShouldBe(sdkDefault.SecurityTokenLifetime); } [Fact] public void Configured_transport_quotas_replace_only_what_is_set() { var sdkDefault = new TransportQuotas(); var built = OpcUaApplicationHost.BuildTransportQuotas(new OpcUaQuotaOptions { MaxMessageSize = 8 * 1024 * 1024, OperationTimeoutMs = 45_000, MaxArrayLength = 1_000_000, }); built.MaxMessageSize.ShouldBe(8 * 1024 * 1024); built.OperationTimeout.ShouldBe(45_000); built.MaxArrayLength.ShouldBe(1_000_000); built.MaxStringLength.ShouldBe(sdkDefault.MaxStringLength); built.ChannelLifetime.ShouldBe(sdkDefault.ChannelLifetime); } [Fact] public void History_read_batch_cap_default_scales_with_the_machine() { OtOpcUaNodeManager.DefaultMaxConcurrentHistoryReadBatches .ShouldBe(Math.Clamp(Environment.ProcessorCount * 2, 4, 16)); } }