using ClawdDotNet.Core.Config; using ClawdDotNet.Core.Storage; using Shouldly; namespace ClawdDotNet.App.Tests; /// /// #375: Die Einstellungsseite zeigte ein Log-Verzeichnis, das nie galt. /// /// InstanceConfig.LogDirectory war mit "./Logs" vorbelegt und damit nie /// leer — der Zweig auf die Anwendungseinstellung war unerreichbar. Aufgelöst wurde der /// Wert zudem mit Path.GetFullPath ohne Basis, also gegen das Arbeitsverzeichnis /// des Prozesses: Wo die Logs landeten, hing davon ab, aus welchem Verzeichnis jemand /// gestartet hatte. Für den Zielbetrieb (systemd-Dienst, startet in /) war das /// /Logs — für ein Dienstkonto nicht anlegbar. /// public sealed class LogDirectoryResolutionTests { private static readonly string InstancePath = Path.GetFullPath(Path.Combine(Path.GetTempPath(), "clawd-tests", "Instance-Test")); private static readonly string ApplicationLogDirectory = Path.Combine(AppPaths.DataDirectory, "Logs"); private static InstanceConfig Instance(string logDirectory, string? workingDirectory = null) => new() { LogDirectory = logDirectory, WorkingDirectory = workingDirectory ?? InstancePath }; [Fact] public void Die_Vorbelegung_ist_leer() { // Der Kern des Befunds: Solange hier "./Logs" stand, konnte die // Anwendungseinstellung nicht greifen. new InstanceConfig().LogDirectory.ShouldBe(""); } [Fact] public void Ohne_Angabe_in_der_Instanz_gilt_die_Anwendungseinstellung() { AppHost.ResolveLogDirectory(Instance(""), ApplicationLogDirectory, InstancePath) .ShouldBe(Path.GetFullPath(ApplicationLogDirectory)); } [Fact] public void Ein_absoluter_Wert_in_der_Instanz_geht_vor() { var eigen = Path.GetFullPath(Path.Combine(Path.GetTempPath(), "clawd-eigene-logs")); AppHost.ResolveLogDirectory(Instance(eigen), ApplicationLogDirectory, InstancePath) .ShouldBe(eigen); } [Fact] public void Ein_relativer_Wert_zaehlt_gegen_das_Instanzverzeichnis() { // Nicht gegen das Arbeitsverzeichnis des Prozesses — das war der Fehler. AppHost.ResolveLogDirectory(Instance("./Logs"), ApplicationLogDirectory, InstancePath) .ShouldBe(Path.Combine(InstancePath, "Logs")); } [Fact] public void Ein_relativer_Wert_haengt_nicht_am_Arbeitsverzeichnis_des_Prozesses() { AppHost.ResolveLogDirectory(Instance("./Logs"), ApplicationLogDirectory, InstancePath) .ShouldNotBe(Path.GetFullPath("./Logs")); } [Fact] public void Ein_leeres_WorkingDirectory_faellt_auf_den_Instanzpfad_zurueck() { // Das Feld steht seit CreateInstance absolut in der Datei, kann aber von Hand // geleert worden sein. Dann trägt der Ort, aus dem geladen wurde. AppHost.ResolveLogDirectory( Instance("Logs", workingDirectory: ""), ApplicationLogDirectory, InstancePath) .ShouldBe(Path.Combine(InstancePath, "Logs")); } [Fact] public void Ein_relatives_WorkingDirectory_faellt_ebenfalls_auf_den_Instanzpfad_zurueck() { // "./data/" ist die alte Vorbelegung des Feldes und wäre wieder gegen das // Arbeitsverzeichnis des Prozesses aufgelöst worden. AppHost.ResolveLogDirectory( Instance("Logs", workingDirectory: "./data/"), ApplicationLogDirectory, InstancePath) .ShouldBe(Path.Combine(InstancePath, "Logs")); } [Fact] public void Nur_Leerzeichen_gelten_als_keine_Angabe() { AppHost.ResolveLogDirectory(Instance(" "), ApplicationLogDirectory, InstancePath) .ShouldBe(Path.GetFullPath(ApplicationLogDirectory)); } }