diff --git a/src/Netclaw.Cli.Tests/Doctor/MemoryCurationLlmDoctorCheckTests.cs b/src/Netclaw.Cli.Tests/Doctor/MemoryCurationLlmDoctorCheckTests.cs new file mode 100644 index 000000000..220d3b8a8 --- /dev/null +++ b/src/Netclaw.Cli.Tests/Doctor/MemoryCurationLlmDoctorCheckTests.cs @@ -0,0 +1,48 @@ +// ----------------------------------------------------------------------- +// +// Copyright (C) 2026 - 2026 Petabridge, LLC +// +// ----------------------------------------------------------------------- +using Microsoft.Extensions.Time.Testing; +using Netclaw.Cli.Doctor; +using Netclaw.Configuration; +using Netclaw.Tests.Utilities; +using Xunit; + +namespace Netclaw.Cli.Tests.Doctor; + +public sealed class MemoryCurationLlmDoctorCheckTests : IDisposable +{ + private readonly DisposableTempDir _temp = new(); + + public void Dispose() => _temp.Dispose(); + + [Fact] + public async Task Reads_and_classifies_log_while_daemon_keeps_it_open_for_append() + { + var paths = new NetclawPaths(_temp.Path); + paths.EnsureDirectoriesExist(); + + var logPath = Path.Combine(paths.LogsDirectory, "daemon-2026-05-20.log"); + using var writerStream = new FileStream( + logPath, + FileMode.Append, + FileAccess.Write, + FileShare.ReadWrite | FileShare.Delete); + using var writer = new StreamWriter(writerStream); + writer.WriteLine("curation_llm_decision"); + writer.WriteLine("curation_llm_timeout"); + writer.Flush(); + + var time = new FakeTimeProvider( + new DateTimeOffset(2026, 5, 20, 12, 0, 0, TimeSpan.Zero)); + var result = await new MemoryCurationLlmDoctorCheck(paths, time) + .RunAsync(TestContext.Current.CancellationToken); + + Assert.Equal("Memory Curation LLM", result.Name); + Assert.Equal(DoctorSeverity.Warning, result.Severity); + // The percent text follows the current culture ("50%" or "50 %"), so + // check the counts, which do not change with the culture. + Assert.Contains("(1/2)", result.Message); + } +} diff --git a/src/Netclaw.Cli/Doctor/MemoryCurationLlmDoctorCheck.cs b/src/Netclaw.Cli/Doctor/MemoryCurationLlmDoctorCheck.cs index 0237fb14e..d5b7920b6 100644 --- a/src/Netclaw.Cli/Doctor/MemoryCurationLlmDoctorCheck.cs +++ b/src/Netclaw.Cli/Doctor/MemoryCurationLlmDoctorCheck.cs @@ -60,7 +60,12 @@ private async Task RunCoreAsync(CancellationToken cancellatio continue; cancellationToken.ThrowIfCancellationRequested(); - using var reader = new StreamReader(file); + using var stream = new FileStream( + file, + FileMode.Open, + FileAccess.Read, + FileShare.ReadWrite | FileShare.Delete); + using var reader = new StreamReader(stream); while (await reader.ReadLineAsync(cancellationToken) is { } line) { // Failure markers first: none of them contains the success