| File: Acquisition\InstallSidecarWriterTests.cs | Web Access |
| Project: src\tests\Aspire.Cli.Tests\Aspire.Cli.Tests.csproj (Aspire.Cli.Tests) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Text.Json; using Aspire.Cli.Acquisition; namespace Aspire.Cli.Tests.Acquisition; public class InstallSidecarWriterTests(ITestOutputHelper outputHelper) { [Fact] public void PrepareForSelfUpdate_CommitUpdatesChannelRemovesExecutableIdentityAndPreservesOtherFields() { using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); var sidecarPath = Path.Combine(workspace.Path, InstallSidecarReader.SidecarFileName); File.WriteAllText( sidecarPath, """ { "source": "script", "channel": "stable", "version": "13.5.0", "commit": "0123456789abcdef", "futureField": { "enabled": true } } """); using var update = InstallSidecarWriter.PrepareForSelfUpdate(workspace.Path, "staging"); Assert.NotNull(update); using (var originalDocument = JsonDocument.Parse(File.ReadAllBytes(sidecarPath))) { Assert.Equal("stable", originalDocument.RootElement.GetProperty("channel").GetString()); } update.Commit(); using var document = JsonDocument.Parse(File.ReadAllBytes(sidecarPath)); Assert.Equal("script", document.RootElement.GetProperty("source").GetString()); Assert.Equal("staging", document.RootElement.GetProperty("channel").GetString()); Assert.False(document.RootElement.TryGetProperty("version", out _)); Assert.False(document.RootElement.TryGetProperty("commit", out _)); Assert.True(document.RootElement.GetProperty("futureField").GetProperty("enabled").GetBoolean()); Assert.Empty(Directory.GetFiles(workspace.Path, $"{InstallSidecarReader.SidecarFileName}.*.tmp")); } [Fact] public void PrepareForSelfUpdate_WhenSidecarIsMissing_LeavesSidecarAbsent() { using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); using var update = InstallSidecarWriter.PrepareForSelfUpdate(workspace.Path, "daily"); var sidecarPath = Path.Combine(workspace.Path, InstallSidecarReader.SidecarFileName); Assert.Null(update); Assert.False(File.Exists(sidecarPath)); } [Fact] public void PrepareForSelfUpdate_WhenSidecarIsMalformed_PreservesOriginalContent() { using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); var sidecarPath = Path.Combine(workspace.Path, InstallSidecarReader.SidecarFileName); const string malformedContent = """{"source":"script","channel":"""; File.WriteAllText(sidecarPath, malformedContent); Assert.ThrowsAny<JsonException>(() => InstallSidecarWriter.PrepareForSelfUpdate(workspace.Path, "staging")); Assert.Equal(malformedContent, File.ReadAllText(sidecarPath)); Assert.Empty(Directory.GetFiles(workspace.Path, $"{InstallSidecarReader.SidecarFileName}.*.tmp")); } [Fact] public void PrepareForSelfUpdate_WhenSerializedSidecarExceedsLimit_PreservesOriginalContent() { using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); var sidecarPath = Path.Combine(workspace.Path, InstallSidecarReader.SidecarFileName); // UTF-8 stores each U+00E9 character in two bytes, while Utf8JsonWriter's default encoder // emits "\u00E9" as six bytes. This keeps the input below 64 KiB but expands the output above it. var originalContent = $"{{\"source\":\"script\",\"futureField\":\"{new string('\u00E9', 11_000)}\"}}"; File.WriteAllText(sidecarPath, originalContent); Assert.InRange(new FileInfo(sidecarPath).Length, 1, InstallSidecarReader.MaxSidecarBytes); var exception = Assert.Throws<InvalidDataException>( () => InstallSidecarWriter.PrepareForSelfUpdate(workspace.Path, "staging")); Assert.Contains("exceeds", exception.Message); Assert.Equal(originalContent, File.ReadAllText(sidecarPath)); Assert.Empty(Directory.GetFiles(workspace.Path, $"{InstallSidecarReader.SidecarFileName}.*.tmp")); } [Fact] public void PrepareForSelfUpdate_DisposeWithoutCommitPreservesOriginalContent() { using var workspace = TemporaryWorkspace.CreateForCli(outputHelper); var sidecarPath = Path.Combine(workspace.Path, InstallSidecarReader.SidecarFileName); const string originalContent = """{"source":"script","channel":"stable"}"""; File.WriteAllText(sidecarPath, originalContent); InstallSidecarWriter.PrepareForSelfUpdate(workspace.Path, "staging")!.Dispose(); Assert.Equal(originalContent, File.ReadAllText(sidecarPath)); Assert.Empty(Directory.GetFiles(workspace.Path, $"{InstallSidecarReader.SidecarFileName}.*.tmp")); } }