using Bootstrap.Admin.HealthChecks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Diagnostics.HealthChecks; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Testing; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Hosting; using System.Net.Http; using System.Text.Json; using UnitTest; using Xunit; namespace Bootstrap.Admin.Api { public class HealthCheckTest : IClassFixture> { private HttpClient client; public HealthCheckTest(HealthCheckWebHost factory) { client = factory.CreateDefaultClient(); } [Fact] public async void Get_Ok() { var cates = await client.GetAsJsonAsync("/Healths"); Assert.NotNull(cates); } [Fact] public async void UI_Ok() { var cates = await client.GetStringAsync("/Healths"); Assert.Contains("TotalDuration", cates); // 测试数据库不能加载时健康检查 var config = HealthCheckStartup.Configuration; config["DB:0:Enabled"] = "false"; config["DB:4:Enabled"] = "true"; config["DB:4:Widget"] = "Bootstrap.DataAccess.MongoDB1"; cates = await client.GetStringAsync("/Healths"); Assert.Contains("TotalDuration", cates); // 测试数据库连接字符串未配置 config["DB:0:Enabled"] = "false"; config["DB:2:Enabled"] = "true"; config["DB:2:ConnectionStrings:ba"] = "Server=localhost;Database=UnitTest1;Uid=argozhang123;Pwd=argo@163.com;SslMode=none;"; config["DB:4:Enabled"] = "false"; config["DB:4:Widget"] = "Bootstrap.DataAccess.MongoDB"; cates = await client.GetStringAsync("/Healths"); Assert.Contains("TotalDuration", cates); config["DB:2:Enabled"] = "false"; config["DB:2:ConnectionStrings:ba"] = "Server=localhost;Database=UnitTest;Uid=argozhang123;Pwd=argo@163.com;SslMode=none;"; config["ConnectionStrings:ba"] = ""; cates = await client.GetStringAsync("/Healths"); Assert.Contains("TotalDuration", cates); } } public class HealthCheckStartup { /// /// 构造函数 /// /// public HealthCheckStartup(IConfiguration configuration) { Configuration = configuration; } /// /// 获得 系统配置项 Iconfiguration 实例 /// public static IConfiguration Configuration { get; private set; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddCacheManager(); services.AddDbAdapter(); services.AddHealthChecks().AddCheck("db"); services.AddControllers(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { app.UseRouting(); app.Use(async (context, next) => { context.User = new System.Security.Claims.ClaimsPrincipal(new System.Security.Principal.GenericIdentity("Argo")); await next(); }); app.UseEndpoints(builder => builder.MapHealthChecks("/Healths", new HealthCheckOptions() { ResponseWriter = async (context, report) => { context.Response.ContentType = "application/json"; await context.Response.WriteAsync(JsonSerializer.Serialize(new { report.Status, report.TotalDuration })); }, ResultStatusCodes = { [HealthStatus.Healthy] = StatusCodes.Status200OK, [HealthStatus.Degraded] = StatusCodes.Status200OK, [HealthStatus.Unhealthy] = StatusCodes.Status200OK } })); } } /// /// /// public class HealthCheckWebHost : WebApplicationFactory where TStartup : class { protected override void ConfigureWebHost(IWebHostBuilder builder) { base.ConfigureWebHost(builder); builder.UseContentRoot(TestHelper.RetrievePath($"UnitTest")); } /// /// /// /// protected override IHostBuilder CreateHostBuilder() => Host.CreateDefaultBuilder().ConfigureWebHostDefaults(builder => builder.UseStartup()); } }