From b14376906d82dde5efd484586f039600ca1b2155 Mon Sep 17 00:00:00 2001 From: Aqua Date: Tue, 10 Nov 2026 18:12:21 +0000 Subject: [PATCH] Daemon: POSIX artifact URIs, and tests name store files through StoreFileName ToArtifactUri prefixed a bare "file:///" so /tmp/x became file:////tmp/x, which Uri reads as a UNC host: the render receipts' Float32Uri/WavUri pointed at nothing on Linux. Separately, session and live-session receipts are written as StoreFileName.From(id).cc and the compile key is uppercase hex, so the name gains a hash suffix; four native-Faust daemon tests still looked for the raw id. Both only show where native Faust compiles (they return early when it does not), so they were red on every Linux host with Faust. Co-Authored-By: Claude Sonnet 5.5 --- src/AquaSynth.Faust/AquaSynthDaemonService.cs | 7 ++++++- tests/AquaSynth.Dsl.Tests/AquaSynthDaemonServiceTests.cs | 6 +++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/AquaSynth.Faust/AquaSynthDaemonService.cs b/src/AquaSynth.Faust/AquaSynthDaemonService.cs index 0021895..13c01f4 100644 --- a/src/AquaSynth.Faust/AquaSynthDaemonService.cs +++ b/src/AquaSynth.Faust/AquaSynthDaemonService.cs @@ -1132,7 +1132,12 @@ public sealed class AquaSynthDaemonService : IDisposable private static string SessionId(string patchId, string compileKey) => $"{StoreFileName.From(patchId)}-{compileKey[..Math.Min(12, compileKey.Length)]}"; - private static string ToArtifactUri(string path) => $"file:///{Path.GetFullPath(path).Replace('\\', '/')}"; + // `C:\a\b` -> file:///C:/a/b and `/a/b` -> file:///a/b; a bare "file:///" prefix made POSIX paths file:////a/b, which Uri reads as a UNC host. + private static string ToArtifactUri(string path) + { + var full = Path.GetFullPath(path).Replace('\\', '/'); + return full.StartsWith('/') ? $"file://{full}" : $"file:///{full}"; + } private static string Now() => DateTimeOffset.UtcNow.ToString("O"); diff --git a/tests/AquaSynth.Dsl.Tests/AquaSynthDaemonServiceTests.cs b/tests/AquaSynth.Dsl.Tests/AquaSynthDaemonServiceTests.cs index 129491f..89da3ad 100644 --- a/tests/AquaSynth.Dsl.Tests/AquaSynthDaemonServiceTests.cs +++ b/tests/AquaSynth.Dsl.Tests/AquaSynthDaemonServiceTests.cs @@ -52,7 +52,7 @@ public sealed class AquaSynthDaemonServiceTests Assert.True(File.Exists(UriToPath(result.RenderReceipt.Float32Uri))); Assert.True(File.Exists(UriToPath(result.RenderReceipt.WavUri))); Assert.Equal(result.RenderReceipt.SampleCount * sizeof(float), new FileInfo(UriToPath(result.RenderReceipt.Float32Uri)).Length); - Assert.True(File.Exists(Path.Combine(storeRoot, "sessions", $"{result.CompileReceipt.SessionId}.cc"))); + Assert.True(File.Exists(Path.Combine(storeRoot, "sessions", $"{StoreFileName.From(result.CompileReceipt.SessionId)}.cc"))); } [Fact] @@ -154,7 +154,7 @@ public sealed class AquaSynthDaemonServiceTests Assert.True(File.Exists(UriToPath(quiet.Float32Uri))); Assert.True(File.Exists(UriToPath(loud.Float32Uri))); Assert.Equal(128 * sizeof(float), new FileInfo(UriToPath(loud.Float32Uri)).Length); - Assert.True(File.Exists(Path.Combine(storeRoot, "live", $"{close.ReceiptId}.cc"))); + Assert.True(File.Exists(Path.Combine(storeRoot, "live", $"{StoreFileName.From(close.ReceiptId)}.cc"))); var liveState = await ReadLiveSessionStateAsync(storeRoot, open.SessionId); Assert.Equal(open.SessionId, liveState.SessionId); Assert.Equal("closed", liveState.Status); @@ -210,7 +210,7 @@ public sealed class AquaSynthDaemonServiceTests private static async Task ReadLiveSessionStateAsync(string storeRoot, string sessionId) { using var cache = await CultCacheMessagePack.OpenAsync( - Path.Combine(storeRoot, "live-sessions", $"{sessionId}.cc")).ConfigureAwait(false); + Path.Combine(storeRoot, "live-sessions", $"{StoreFileName.From(sessionId)}.cc")).ConfigureAwait(false); return Assert.Single(cache.GetAll()); } } -- 2.47.3