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) { }
}
}