using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway; using ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Recorder; using ZB.MOM.WW.OtOpcUa.Core.Abstractions; using ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer; using ZB.MOM.WW.OtOpcUa.Host.Configuration; using ZB.MOM.WW.OtOpcUa.Runtime.Historian; namespace ZB.MOM.WW.OtOpcUa.Host.Tests.Configuration; public sealed class HistorianBackendRegistryTests { private static readonly IConfiguration Cfg = new ConfigurationBuilder().Build(); private static ServerHistorianOptions Gateway(string backend = "Gateway") => new() { Backend = backend, Enabled = true, Endpoint = "http://localhost:5222", ApiKey = "histgw_id_secret", UseTls = false, }; [Fact] public void Default_backend_is_Gateway_and_resolves_the_gateway_provider() { new ServerHistorianOptions().Backend.ShouldBe("Gateway"); HistorianBackendRegistry.Resolve(new ServerHistorianOptions(), Cfg).ShouldBeOfType(); } [Theory] [InlineData("gateway")] [InlineData("GATEWAY")] [InlineData("Gateway")] public void Resolve_is_case_insensitive(string name) => HistorianBackendRegistry.Resolve(Gateway(name), Cfg).Name.ShouldBe("Gateway"); [Fact] public void Unknown_backend_throws_naming_the_value_and_the_allowed_names() { var ex = Should.Throw( () => HistorianBackendRegistry.Resolve(Gateway("Nope"), Cfg)); var msg = string.Join(" ", ex.Failures); msg.ShouldContain("Nope"); msg.ShouldContain("Gateway"); msg.ShouldContain("ServerHistorian:Backend"); } [Fact] public void KnownBackends_lists_Gateway() => HistorianBackendRegistry.KnownBackends.ShouldContain("Gateway"); [Fact] public void Gateway_provider_builds_the_same_concrete_seams_Program_used_to_build() { var sp = new ServiceCollection().BuildServiceProvider(); var p = HistorianBackendRegistry.Resolve(Gateway(), Cfg); p.CreateDataSource(sp).ShouldBeOfType(); p.CreateValueWriter(sp).ShouldBeOfType(); p.CreateAlarmWriter(sp).ShouldBeOfType(); p.CreateProvisioning(sp).ShouldBeOfType(); p.CreateUpdater(sp).ShouldBeNull(); } private static IConfiguration SqlCfg() => new ConfigurationBuilder().AddInMemoryCollection(new Dictionary { ["ServerHistorian:SqlServer:ConnectionString"] = "Server=localhost;User Id=sa;Password=x;TrustServerCertificate=True", }).Build(); [Fact] public void SqlServer_backend_resolves_and_builds_the_sql_seams() { var sp = new ServiceCollection().BuildServiceProvider(); var p = HistorianBackendRegistry.Resolve(new ServerHistorianOptions { Backend = "sqlserver", Enabled = true }, SqlCfg()); p.ShouldBeOfType(); HistorianBackendRegistry.KnownBackends.ShouldContain("SqlServer"); p.SupportedKinds.Count.ShouldBe(6); p.SupportedKinds.ShouldContain(HistorianValueKind.String); p.SupportedKinds.ShouldContain(HistorianValueKind.Empty); p.CreateDataSource(sp).ShouldBeOfType(); p.CreateValueWriter(sp).GetType().Name.ShouldBe("SqlServerHistorianValueWriter"); p.CreateAlarmWriter(sp).GetType().Name.ShouldBe("SqlServerAlarmHistorianWriter"); p.CreateProvisioning(sp).GetType().Name.ShouldBe("SqlServerTagProvisioner"); var holder = new HistorianUpdaterHolder(p.CreateUpdater(sp)); holder.Updater.ShouldNotBeNull(); holder.Updater!.GetType().Name.ShouldBe("SqlServerHistorianDataUpdater"); } }