IMPL-12: 完善端到端集成测试基础设施和修复递归问题
- 更新 TestFixture 添加 Mock Redis 和内存数据库配置 - 修复 DynamicProxyConfigProvider 中的递归问题 - 添加 GwPendingServiceDiscovery 实体模型 - 修复测试数据模型与实际代码的匹配问题 37/44 集成测试通过,失败测试主要由于测试间状态共享
This commit is contained in:
parent
9b77169b80
commit
faba26043f
@ -32,7 +32,7 @@ public class DynamicProxyConfigProvider : IProxyConfigProvider
|
|||||||
{
|
{
|
||||||
lock (_lock)
|
lock (_lock)
|
||||||
{
|
{
|
||||||
_cts?.Cancel();
|
var oldCts = _cts;
|
||||||
_cts = new CancellationTokenSource();
|
_cts = new CancellationTokenSource();
|
||||||
|
|
||||||
var routes = _routeProvider.GetRoutes();
|
var routes = _routeProvider.GetRoutes();
|
||||||
@ -44,6 +44,9 @@ public class DynamicProxyConfigProvider : IProxyConfigProvider
|
|||||||
Array.Empty<IReadOnlyDictionary<string, string>>(),
|
Array.Empty<IReadOnlyDictionary<string, string>>(),
|
||||||
_cts.Token
|
_cts.Token
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// 在设置新配置后再取消旧的 token,避免递归
|
||||||
|
oldCts?.Cancel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,8 @@ using Microsoft.EntityFrameworkCore;
|
|||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||||
|
using Moq;
|
||||||
|
using StackExchange.Redis;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using YarpGateway.Data;
|
using YarpGateway.Data;
|
||||||
using YarpGateway.DynamicProxy;
|
using YarpGateway.DynamicProxy;
|
||||||
@ -27,23 +29,18 @@ public class TestFixture : IAsyncLifetime
|
|||||||
.WithWebHostBuilder(builder =>
|
.WithWebHostBuilder(builder =>
|
||||||
{
|
{
|
||||||
builder.UseEnvironment("Testing");
|
builder.UseEnvironment("Testing");
|
||||||
builder.ConfigureServices(services =>
|
builder.ConfigureServices((context, services) =>
|
||||||
{
|
{
|
||||||
// 移除 PostgreSQL 数据库上下文
|
// 移除所有与 GatewayDbContext 相关的服务
|
||||||
var descriptor = services.SingleOrDefault(
|
var descriptorsToRemove = services
|
||||||
d => d.ServiceType == typeof(IDbContextFactory<GatewayDbContext>));
|
.Where(d => d.ServiceType.Name.Contains("DbContext") ||
|
||||||
if (descriptor != null)
|
d.ServiceType.Name.Contains("GatewayDbContext"))
|
||||||
|
.ToList();
|
||||||
|
foreach (var descriptor in descriptorsToRemove)
|
||||||
{
|
{
|
||||||
services.Remove(descriptor);
|
services.Remove(descriptor);
|
||||||
}
|
}
|
||||||
|
|
||||||
var dbContextDescriptor = services.SingleOrDefault(
|
|
||||||
d => d.ServiceType == typeof(DbContextOptions<GatewayDbContext>));
|
|
||||||
if (dbContextDescriptor != null)
|
|
||||||
{
|
|
||||||
services.Remove(dbContextDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 使用内存数据库替换
|
// 使用内存数据库替换
|
||||||
services.AddDbContextFactory<GatewayDbContext>(options =>
|
services.AddDbContextFactory<GatewayDbContext>(options =>
|
||||||
{
|
{
|
||||||
@ -63,6 +60,18 @@ public class TestFixture : IAsyncLifetime
|
|||||||
services.RemoveAll(typeof(StackExchange.Redis.IConnectionMultiplexer));
|
services.RemoveAll(typeof(StackExchange.Redis.IConnectionMultiplexer));
|
||||||
services.RemoveAll(typeof(IRedisConnectionManager));
|
services.RemoveAll(typeof(IRedisConnectionManager));
|
||||||
|
|
||||||
|
// 移除分布式负载均衡策略(需要 Redis)
|
||||||
|
services.RemoveAll(typeof(Yarp.ReverseProxy.LoadBalancing.ILoadBalancingPolicy));
|
||||||
|
|
||||||
|
// 添加 Mock Redis 连接
|
||||||
|
var mockRedis = new Mock<IConnectionMultiplexer>();
|
||||||
|
var mockDb = new Mock<IDatabase>();
|
||||||
|
mockDb.Setup(db => db.StringSet(It.IsAny<RedisKey>(), It.IsAny<RedisValue>(), It.IsAny<TimeSpan?>(), It.IsAny<When>(), It.IsAny<CommandFlags>())).Returns(true);
|
||||||
|
mockDb.Setup(db => db.StringGet(It.IsAny<RedisKey>(), It.IsAny<CommandFlags>())).Returns(RedisValue.Null);
|
||||||
|
mockDb.Setup(db => db.ScriptEvaluate(It.IsAny<string>(), It.IsAny<RedisKey[]>(), It.IsAny<RedisValue[]>(), It.IsAny<CommandFlags>())).Returns(RedisResult.Create(1));
|
||||||
|
mockRedis.Setup(r => r.GetDatabase(It.IsAny<int>(), It.IsAny<object?>())).Returns(mockDb.Object);
|
||||||
|
services.AddSingleton(mockRedis.Object);
|
||||||
|
|
||||||
// 添加内存缓存
|
// 添加内存缓存
|
||||||
services.AddMemoryCache();
|
services.AddMemoryCache();
|
||||||
|
|
||||||
@ -152,13 +161,11 @@ public class TestFixture : IAsyncLifetime
|
|||||||
|
|
||||||
await dbContext.SaveChangesAsync();
|
await dbContext.SaveChangesAsync();
|
||||||
|
|
||||||
// 初始化 RouteCache
|
// 初始化 RouteCache(注意:不要在初始化后调用 UpdateConfig,
|
||||||
|
// 因为 DynamicProxyConfigProvider 构造函数中已经调用了它,
|
||||||
|
// 额外的调用可能导致 YARP 配置管理器的递归问题)
|
||||||
var routeCache = scope.ServiceProvider.GetRequiredService<IRouteCache>();
|
var routeCache = scope.ServiceProvider.GetRequiredService<IRouteCache>();
|
||||||
await routeCache.InitializeAsync();
|
await routeCache.InitializeAsync();
|
||||||
|
|
||||||
// 初始化配置提供程序
|
|
||||||
var configProvider = scope.ServiceProvider.GetRequiredService<DynamicProxyConfigProvider>();
|
|
||||||
configProvider.UpdateConfig();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user