| File: PassThroughServiceEndpointResolverTests.cs | Web Access |
| Project: src\test\Libraries\Microsoft.Extensions.ServiceDiscovery.Tests\Microsoft.Extensions.ServiceDiscovery.Tests.csproj (Microsoft.Extensions.ServiceDiscovery.Tests) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Net; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration.Memory; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.ServiceDiscovery.Internal; using Microsoft.Extensions.ServiceDiscovery.PassThrough; using Xunit; namespace Microsoft.Extensions.ServiceDiscovery.Tests; /// <summary> /// Tests for <see cref="PassThroughServiceEndpointProviderFactory"/>. /// These also cover <see cref="ServiceEndpointWatcher"/> and <see cref="ServiceEndpointWatcherFactory"/> by extension. /// </summary> public class PassThroughServiceEndpointResolverTests { [Fact] public async Task ResolveServiceEndpoint_PassThrough() { var services = new ServiceCollection() .AddServiceDiscoveryCore() .AddPassThroughServiceEndpointProvider() .BuildServiceProvider(); var watcherFactory = services.GetRequiredService<ServiceEndpointWatcherFactory>(); ServiceEndpointWatcher watcher; await using ((watcher = watcherFactory.CreateWatcher("http://basket")).ConfigureAwait(false)) { Assert.NotNull(watcher); var tcs = new TaskCompletionSource<ServiceEndpointResolverResult>(); watcher.OnEndpointsUpdated = tcs.SetResult; watcher.Start(); var initialResult = await tcs.Task; Assert.NotNull(initialResult); Assert.True(initialResult.ResolvedSuccessfully); var ep = Assert.Single(initialResult.EndpointSource.Endpoints); Assert.Equal(new DnsEndPoint("basket", 80), ep.EndPoint); } } [Fact] public async Task ResolveServiceEndpoint_Superseded() { var configSource = new MemoryConfigurationSource { InitialData = new Dictionary<string, string?> { ["services:basket:http:0"] = "http://localhost:8080", } }; var config = new ConfigurationBuilder().Add(configSource); var services = new ServiceCollection() .AddSingleton<IConfiguration>(config.Build()) .AddServiceDiscovery() // Adds the configuration and pass-through providers. .BuildServiceProvider(); var watcherFactory = services.GetRequiredService<ServiceEndpointWatcherFactory>(); ServiceEndpointWatcher watcher; await using ((watcher = watcherFactory.CreateWatcher("http://basket")).ConfigureAwait(false)) { Assert.NotNull(watcher); var tcs = new TaskCompletionSource<ServiceEndpointResolverResult>(); watcher.OnEndpointsUpdated = tcs.SetResult; watcher.Start(); var initialResult = await tcs.Task; Assert.NotNull(initialResult); Assert.True(initialResult.ResolvedSuccessfully); // We expect the basket service to be resolved from Configuration, not the pass-through provider. Assert.Single(initialResult.EndpointSource.Endpoints); Assert.Equal(new UriEndPoint(new Uri("http://localhost:8080")), initialResult.EndpointSource.Endpoints[0].EndPoint); } } [Fact] public async Task ResolveServiceEndpoint_Fallback() { var configSource = new MemoryConfigurationSource { InitialData = new Dictionary<string, string?> { ["services:basket:default:0"] = "http://localhost:8080", } }; var config = new ConfigurationBuilder().Add(configSource); var services = new ServiceCollection() .AddSingleton<IConfiguration>(config.Build()) .AddServiceDiscovery() // Adds the configuration and pass-through providers. .BuildServiceProvider(); var watcherFactory = services.GetRequiredService<ServiceEndpointWatcherFactory>(); ServiceEndpointWatcher watcher; await using ((watcher = watcherFactory.CreateWatcher("http://catalog")).ConfigureAwait(false)) { Assert.NotNull(watcher); var tcs = new TaskCompletionSource<ServiceEndpointResolverResult>(); watcher.OnEndpointsUpdated = tcs.SetResult; watcher.Start(); var initialResult = await tcs.Task; Assert.NotNull(initialResult); Assert.True(initialResult.ResolvedSuccessfully); // We expect the CATALOG service to be resolved from the pass-through provider. Assert.Single(initialResult.EndpointSource.Endpoints); Assert.Equal(new DnsEndPoint("catalog", 80), initialResult.EndpointSource.Endpoints[0].EndPoint); } } // Ensures that pass-through resolution succeeds in scenarios where no scheme is specified during resolution. [Fact] public async Task ResolveServiceEndpoint_Fallback_NoScheme() { var configSource = new MemoryConfigurationSource { InitialData = new Dictionary<string, string?> { ["services:basket:default:0"] = "http://localhost:8080", } }; var config = new ConfigurationBuilder().Add(configSource); var services = new ServiceCollection() .AddSingleton<IConfiguration>(config.Build()) .AddServiceDiscovery() // Adds the configuration and pass-through providers. .BuildServiceProvider(); var resolver = services.GetRequiredService<ServiceEndpointResolver>(); var result = await resolver.GetEndpointsAsync("catalog", default); Assert.Equal(new DnsEndPoint("catalog", 0), result.Endpoints[0].EndPoint); } }