using Grpc.Net.Client; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using ZB.MOM.WW.ScadaBridge.Communication.Grpc; namespace ZB.MOM.WW.ScadaBridge.Communication.Tests.Grpc; /// /// Every production builder of a PSK-credentialed control-plane channel must accept an /// https:// endpoint (ScadaBridge#64). Before the endpoint was threaded into /// , each composed its credentials over /// insecure channel credentials and Grpc.Net.Client threw at construction for any https address — /// in that throw was caught and the site address logged as /// malformed, so a TLS site was silently undialable. /// public class HttpsEndpointChannelTests { private const string Site = "site-a"; /// Verifies central's per-site pair provider builds a channel for an https site address. /// A task that represents the asynchronous operation. [Fact] public async Task SitePairChannelProvider_builds_an_https_site_channel() { using var provider = new SitePairChannelProvider( new FixedKeyProvider(), Options.Create(new CommunicationOptions()), NullLogger.Instance, handlerFactory: null, reachabilityProbe: (_, _) => Task.FromResult(false)); provider.UpdateSite(Site, "https://site-a-node-a:8083", nodeBEndpoint: null); var target = await provider.ExecuteAsync( Site, (channel, _) => Task.FromResult(channel.Target), CancellationToken.None); Assert.Equal("site-a-node-a:8083", target); } /// Verifies a site's central channel provider builds https channels for both centrals. [Fact] public void CentralChannelProvider_builds_https_central_channels() { using var provider = new CentralChannelProvider( new[] { "https://central-a:8083", "https://central-b:8083" }, new FixedKeyProvider(), Site, new CommunicationOptions(), NullLogger.Instance); } /// Verifies the site stream client builds an https channel with credentials. [Fact] public void SiteStreamGrpcClient_builds_an_https_channel() { using var client = new SiteStreamGrpcClient( "https://site-a-node-a:8083", NullLogger.Instance, new CommunicationOptions(), new FixedKeyProvider(), Site); Assert.Equal("https://site-a-node-a:8083", client.Endpoint); } /// Verifies the scheme check behind the composition choice. /// The endpoint. /// Whether it is TLS. [Theory] [InlineData("https://host:8083", true)] [InlineData("HTTPS://host:8083", true)] [InlineData("http://host:8083", false)] [InlineData(null, false)] [InlineData("", false)] [InlineData("not a url", false)] public void IsTlsEndpoint_matches_only_absolute_https(string? endpoint, bool expected) { Assert.Equal(expected, ControlPlaneCredentials.IsTlsEndpoint(endpoint)); } private sealed class FixedKeyProvider : ISitePskProvider { /// public ValueTask GetAsync(string siteId, CancellationToken ct) => new("k"); /// public void Invalidate(string siteId) { } } }