CounterDroneBackend/test/unit/CounterDrone.Core.Tests/ConfigServiceTests.cs
tian 36ab4fad7b 配置运行时重载 IConfigService + 防御推荐 + 文档更新
新增:
- IConfigService / ConfigService:读写 defaults.json / planner_config.json
- SavePlannerConfig / SaveDefaults / Reload,无需重启 Unity
- PlannerConfigReloaded 事件 → ScenarioManager 自动重建 planner
- SimulationEngine.UpdatePlanner / ScenarioService.UpdatePlanner
- SimulationRunner.ReloadPlanner 桥接
- DefenseRecommendation / RecommendOption 返回类型
- IScenarioService.GetDefenseRecommendation(配置阶段生成最佳抛撒参数)
- ConfigServiceTests 5 个测试 + DefenseRecommendationTests 3 个测试

修复:
- 云团间距半径基准不一致(间距用 R30、穿越用 R27 → 统一用 effectiveRadius)
- 消除硬编码 30f(DefensePlanner + GaussianPuffDispersion 读 Phase2Duration)
- TryGenerateFireEvents 复用 ComputeEffectiveRadius,消除重复计算
- 概率计算间距加重叠系数
- DatabaseManager 不再 DROP SimulationReport(保留历史报告)
- 清理迁移代码(MetaEntry / 旧表 DROP / 版本检查)

文档:
- 对接文档 V2.1:加 IConfigService API + 配置重载用法 + 修正 DLL 更新说明
- 实施跟踪 V1.8:8.2.1 更新 + 新增 8.2.3/8.2.4 + M14 里程碑
- 270 测试通过,Unity 编译通过
2026-06-25 22:10:22 +08:00

119 lines
4.1 KiB
C#

using System;
using System.IO;
using System.Text.Json;
using CounterDrone.Core;
using CounterDrone.Core.Algorithms;
using CounterDrone.Core.Services;
using Xunit;
namespace CounterDrone.Core.Tests
{
public class ConfigServiceTests : IDisposable
{
private readonly string _testDir;
private readonly IPathProvider _paths;
private readonly ConfigService _config;
private readonly SQLite.SQLiteConnection _db;
public ConfigServiceTests()
{
_testDir = Path.Combine(Path.GetTempPath(), $"cd_cfg_{Guid.NewGuid():N}");
_paths = new TestPathProvider(_testDir);
var dbm = new DatabaseManager(_paths);
_db = dbm.OpenMainDb();
_config = new ConfigService(_paths, _db);
}
public void Dispose()
{
_db?.Close();
if (Directory.Exists(_testDir)) Directory.Delete(_testDir, true);
}
[Fact]
public void GetPlannerConfigJson_ReturnsValidJson()
{
var json = _config.GetPlannerConfigJson();
var cfg = JsonSerializer.Deserialize<PlannerConfig>(json, new JsonSerializerOptions
{
Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() },
PropertyNameCaseInsensitive = true,
});
Assert.NotNull(cfg);
Assert.True(cfg.CloudOverlapRatio >= 0);
}
[Fact]
public void SavePlannerConfig_PersistsAndReloads()
{
var original = _config.GetPlannerConfigJson();
var cfg = JsonSerializer.Deserialize<PlannerConfig>(original, new JsonSerializerOptions
{
Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() },
PropertyNameCaseInsensitive = true,
})!;
cfg.CloudOverlapRatio = 0.3f;
var modifiedJson = JsonSerializer.Serialize(cfg, new JsonSerializerOptions
{
Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() },
});
_config.SavePlannerConfig(modifiedJson);
var reloaded = _config.GetPlannerConfigJson();
var reloadedCfg = JsonSerializer.Deserialize<PlannerConfig>(reloaded, new JsonSerializerOptions
{
Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() },
PropertyNameCaseInsensitive = true,
})!;
Assert.Equal(0.3f, reloadedCfg.CloudOverlapRatio);
}
[Fact]
public void PlannerConfigReloaded_EventFires()
{
PlannerConfig? received = null;
_config.PlannerConfigReloaded += cfg => received = cfg;
var json = _config.GetPlannerConfigJson();
_config.SavePlannerConfig(json);
Assert.NotNull(received);
Assert.True(received.CloudOverlapRatio >= 0);
}
[Fact]
public void Reload_FromDiskRefreshesConfig()
{
// 直接改文件
var path = Path.Combine(_testDir, "planner_config.json");
var json = File.ReadAllText(path);
var cfg = JsonSerializer.Deserialize<PlannerConfig>(json, new JsonSerializerOptions
{
Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() },
PropertyNameCaseInsensitive = true,
})!;
cfg.ExpansionFactor = 0.8f;
File.WriteAllText(path, JsonSerializer.Serialize(cfg, new JsonSerializerOptions
{
Converters = { new System.Text.Json.Serialization.JsonStringEnumConverter() },
}));
PlannerConfig? received = null;
_config.PlannerConfigReloaded += cfg => received = cfg;
_config.Reload();
Assert.NotNull(received);
Assert.Equal(0.8f, received.ExpansionFactor);
}
[Fact]
public void GetDefaultsJson_ReturnsValidJson()
{
var json = _config.GetDefaultsJson();
Assert.Contains("ammunition", json.ToLower());
}
}
}