using Fleet.Core; using Fleet.Hosting; namespace Fleet.Tests; public sealed class BufferedNodeLogTests { [Fact] public void Summary_CountsByLevelAndTypeWithoutText_AndResetsAfterEachTake() { var log = new BufferedNodeLog(NullNodeLog.Instance, TimeProvider.System); for (int i = 0; i < 5; i++) { log.Warn("peer control handshake failed", ("attempt", i)); } log.Info("link up"); log.Error("MsQuic QUIC transport shutdown"); NodeLogSummary first = log.TakeSummary(); Assert.Equal((1L, 5L, 1L), (first.Info, first.Warn, first.Error)); Assert.Equal(7, first.LastId); NodeLogTypeCount top = first.Types[0]; Assert.Equal((BufferedNodeLog.TypeOf("peer control handshake failed"), "warn", 5L), (top.Type, top.Level, top.Count)); NodeLogSummary second = log.TakeSummary(); Assert.Equal((0L, 0L, 0L), (second.Info, second.Warn, second.Error)); Assert.Empty(second.Types); Assert.Equal(7, second.LastId); } [Fact] public void Read_ReturnsLinesAfterAnIdAtOrAboveALevel_OldestFirst_AndTheRingKeepsTheNewest() { var log = new BufferedNodeLog(NullNodeLog.Instance, TimeProvider.System); log.Info("one"); log.Warn("two"); log.Error("three"); log.Info("four"); Assert.Equal(["two", "three"], log.Read(1, 2, null).Items.Select(e => e.Record.Message)); Assert.Equal(["three"], log.Read(0, 10, "error").Items.Select(e => e.Record.Message)); Assert.Equal(["two", "three"], log.Read(0, 10, "warn").Items.Select(e => e.Record.Message)); for (int i = 0; i < 3000; i++) { log.Info("filler", ("n", i)); } NodeLogPage page = log.Read(0, 200, null); Assert.Equal(200, page.Items.Count); Assert.True(page.Items[0].Id > 4); // 最早的几条已经被环挤掉 Assert.Equal(3004, page.LastId); } [Fact] public void SensitiveFieldsAreRedacted() { var log = new BufferedNodeLog(NullNodeLog.Instance, TimeProvider.System); log.Info("auth", ("token", "abc"), ("agent", "agt_x")); NodeLogEntry entry = Assert.Single(log.Read(0, 10, null).Items); Assert.Equal("[redacted]", entry.Record.Fields["token"]); Assert.Equal("agt_x", entry.Record.Fields["agent"]); } }