feature: In-App Simulation Runner (Backend)
CI / frontend (push) Canceled after 0s
CI / backend (push) Canceled after 8m32s

This commit is contained in:
voltsrage
2026-08-06 01:52:53 +08:00
parent 943d41339c
commit 24f45851e9
83 changed files with 3974 additions and 120 deletions
@@ -1,9 +1,11 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using StackExchange.Redis;
@@ -24,6 +26,12 @@ public class ApiFixture : WebApplicationFactory<Program>, IAsyncLifetime
public static int RabbitPort { get; } =
int.TryParse(Environment.GetEnvironmentVariable("RabbitMq__Port"), out var p) ? p : 5674;
public static string SimulationScenarioDirectory { get; } = Path.GetFullPath(Path.Combine(
AppContext.BaseDirectory, "Fixtures", "Scenarios"));
public TestSimulationClientFactory SimulationClientFactory =>
Services.GetRequiredService<TestSimulationClientFactory>();
// Override configuration to point at a test database — never run tests against
// the development database; a botched rollback could corrupt seed data.
protected override void ConfigureWebHost(IWebHostBuilder builder)
@@ -62,6 +70,16 @@ public class ApiFixture : WebApplicationFactory<Program>, IAsyncLifetime
});
config.AddJsonFile("appsettings.Testing.json", optional: true, reloadOnChange: false);
// Win over appsettings.Testing.json catalogue path / concurrency defaults.
config.AddInMemoryCollection(new Dictionary<string, string?>
{
["Simulation:Enabled"] = "true",
["Simulation:ScenarioDirectory"] = SimulationScenarioDirectory,
["Simulation:MaxConcurrentRuns"] = "2",
["Simulation:MaxSpeed"] = "600",
["Simulation:RunHistoryLimit"] = "50",
});
});
builder.ConfigureServices(services =>
@@ -77,6 +95,15 @@ public class ApiFixture : WebApplicationFactory<Program>, IAsyncLifetime
.AddScheme<AuthenticationSchemeOptions, TestingAuthHandler>(
TestingAuthHandler.SchemeName, _ => { });
});
builder.ConfigureTestServices(services =>
{
services.RemoveAll<ISimulationClientFactory>();
services.AddSingleton<TestSimulationClientFactory>(_ =>
new TestSimulationClientFactory(this));
services.AddSingleton<ISimulationClientFactory>(sp =>
sp.GetRequiredService<TestSimulationClientFactory>());
});
}
public async Task InitializeAsync()