using System.Text.Json;
using Serilog.Events;
using YZWater.Core.Models;
using YZWater.Core.Services;
namespace YZWater.Core.Tests.Services;
///
/// 日志级别运行时开关的回归测试。
/// 背景:轮询诊断降到 Debug 之后,如果级别不可调,现场遇到"某个值不对"就没有任何手段
/// 把它临时开回来取证,只能停下来重新发布 —— 降级就变成了丢能力。
///
// 本类会改 LogService.MinimumLevel(静态),必须与同样改它的测试类串行,否则默认值断言偶发失败
[Collection("Serilog minimum level")]
public class LogLevelSwitchTests : IDisposable
{
private readonly LogEventLevel _original = LogService.MinimumLevel;
[Fact]
public void Default_MinimumLevel_IsInformation()
{
Assert.Equal(LogEventLevel.Information, _original);
}
[Fact]
public void ApplyMinimumLevel_Debug_TakesEffect()
{
LogService.ApplyMinimumLevel("Debug");
Assert.Equal(LogEventLevel.Debug, LogService.MinimumLevel);
}
[Fact]
public void ApplyMinimumLevel_IsCaseInsensitive()
{
LogService.ApplyMinimumLevel("warning");
Assert.Equal(LogEventLevel.Warning, LogService.MinimumLevel);
}
[Theory]
[InlineData(null)]
[InlineData("")]
[InlineData(" ")]
[InlineData("banana")]
[InlineData("Infos")]
public void ApplyMinimumLevel_InvalidValue_KeepsCurrentLevel(string? level)
{
LogService.ApplyMinimumLevel("Debug");
var before = LogService.MinimumLevel;
LogService.ApplyMinimumLevel(level);
Assert.Equal(before, LogService.MinimumLevel);
}
[Theory]
[InlineData("Debug", true)]
[InlineData("debug", true)]
[InlineData("Information", true)]
[InlineData("Verbose", true)]
[InlineData("Fatal", true)]
[InlineData("Trace", false)]
// 手改配置文件容易多敲空格,Enum.TryParse 本身容忍首尾空白 —— 这里把它钉住
[InlineData("Debug ", true)]
[InlineData(" Debug", true)]
public void TryParseLevel_MatchesSerilogVocabulary(string level, bool expected)
{
Assert.Equal(expected, LogService.TryParseLevel(level, out _));
}
[Fact]
public void SystemConfig_LogKnobs_DefaultToProductionValues()
{
var config = new SystemConfig();
Assert.Equal("Information", config.MinimumLogLevel);
Assert.Equal(60, config.LogSnapshotIntervalSeconds);
}
[Fact]
public void SystemConfig_LogKnobs_RoundTripThroughJson()
{
// 现场排障就是改这两行文本,键名必须能被反序列化认出来
const string json = """{"MinimumLogLevel":"Debug","LogSnapshotIntervalSeconds":10}""";
var config = JsonSerializer.Deserialize(json);
Assert.Equal("Debug", config?.MinimumLogLevel);
Assert.Equal(10, config?.LogSnapshotIntervalSeconds);
}
[Fact]
public void PlcPollingService_SnapshotInterval_DefaultsTo60Seconds()
{
// 0 会让快照静默关闭,默认值必须是有证据的那一档
Assert.Equal(60, PlcPollingService.Instance.LogSnapshotIntervalSeconds);
}
public void Dispose() => LogService.ApplyMinimumLevel(_original.ToString());
}