56 lines
4.4 KiB
C#
56 lines
4.4 KiB
C#
using System.Security.Cryptography;
|
|
using Launcher.Next.Core;
|
|
using Launcher.Next.Infrastructure;
|
|
using Xunit;
|
|
|
|
namespace Launcher.Next.Tests;
|
|
|
|
public sealed class PackageLifecycleTests
|
|
{
|
|
private static PackageRequirement Req(string version) => new("Lifecycle.Package", "Plant3D", 2026, "x64", "pilot", version, "lifecycle-test", true);
|
|
private static PackageManifest Manifest(string version, byte[] a, byte[] b) => new(1, "Lifecycle.Package", version, "Plant3D", 2026, "x64", "entry.dll", [
|
|
new("entry.dll", a.Length, Convert.ToHexString(SHA256.HashData(a))),
|
|
new("payload.dat", b.Length, Convert.ToHexString(SHA256.HashData(b)))], new("none", ""), RolloutChannel: "pilot");
|
|
|
|
[Fact]
|
|
public async Task MaterializeDoesNotCreatePointersAndReturnsImmutableVersion()
|
|
{
|
|
var root = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); var source = Path.Combine(root, "catalog"); Directory.CreateDirectory(source);
|
|
var a = new byte[] { 1, 2 }; var b = new byte[] { 3, 4, 5 }; await File.WriteAllBytesAsync(Path.Combine(source, "entry.dll"), a); await File.WriteAllBytesAsync(Path.Combine(source, "payload.dat"), b);
|
|
var store = new LocalPackageStore(root, new Sha256FileHasher());
|
|
try
|
|
{
|
|
var result = await store.MaterializeAsync(Manifest("1.0.0", a, b), source, CancellationToken.None);
|
|
Assert.True(File.Exists(Path.Combine(result.LocalPackageRoot, "package.manifest.json")));
|
|
Assert.False(File.Exists(Path.Combine(root, "Applications", "Lifecycle.Package", "current.json")));
|
|
Assert.False(File.Exists(Path.Combine(root, "Applications", "Lifecycle.Package", "previous.json")));
|
|
Assert.DoesNotContain("staging", result.LocalPackageRoot, StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
finally { if (Directory.Exists(root)) Directory.Delete(root, true); }
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ActivationIsIdempotentAndRollbackRestoresPrevious()
|
|
{
|
|
var root = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); var source = Path.Combine(root, "catalog"); Directory.CreateDirectory(source); var store = new LocalPackageStore(root, new Sha256FileHasher());
|
|
var a = new byte[] { 1 }; var b = new byte[] { 2 }; var c = new byte[] { 3 }; await File.WriteAllBytesAsync(Path.Combine(source, "entry.dll"), a); await File.WriteAllBytesAsync(Path.Combine(source, "payload.dat"), b);
|
|
try
|
|
{
|
|
var pa = await store.MaterializeAsync(Manifest("1.0.0", a, b), source, CancellationToken.None); var aa = await store.ActivateImmutableAsync(pa, Req("1.0.0"), CancellationToken.None); Assert.Equal("Activated", aa.Outcome);
|
|
var again = await store.ActivateImmutableAsync(pa, Req("1.0.0"), CancellationToken.None); Assert.Equal("AlreadyActiveExact", again.Outcome);
|
|
await File.WriteAllBytesAsync(Path.Combine(source, "entry.dll"), c); var pb = await store.MaterializeAsync(Manifest("2.0.0", c, b), source, CancellationToken.None); var ab = await store.ActivateImmutableAsync(pb, Req("2.0.0"), CancellationToken.None); Assert.Equal("Activated", ab.Outcome);
|
|
var rollback = await store.RollbackAsync(ab.Receipt!, CancellationToken.None); Assert.Equal("RolledBack", rollback.Outcome); Assert.Equal("1.0.0", await store.GetCurrentVersionAsync("Lifecycle.Package", CancellationToken.None));
|
|
}
|
|
finally { if (Directory.Exists(root)) Directory.Delete(root, true); }
|
|
}
|
|
|
|
[Fact]
|
|
public async Task OldReceiptCannotRollbackNewerActivation()
|
|
{
|
|
var root = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); var source = Path.Combine(root, "catalog"); Directory.CreateDirectory(source); var store = new LocalPackageStore(root, new Sha256FileHasher());
|
|
var bytes = new byte[] { 1 }; await File.WriteAllBytesAsync(Path.Combine(source, "entry.dll"), bytes); await File.WriteAllBytesAsync(Path.Combine(source, "payload.dat"), bytes);
|
|
try { var a=await store.MaterializeAsync(Manifest("1.0.0",bytes,bytes),source,CancellationToken.None); await store.ActivateImmutableAsync(a,Req("1.0.0"),CancellationToken.None); var b=await store.MaterializeAsync(Manifest("2.0.0",bytes,bytes),source,CancellationToken.None); var rb=await store.ActivateImmutableAsync(b,Req("2.0.0"),CancellationToken.None); var r=await store.RollbackAsync(rb.Receipt!,CancellationToken.None); Assert.Equal("RolledBack",r.Outcome); }
|
|
finally { if (Directory.Exists(root)) Directory.Delete(root, true); }
|
|
}
|
|
}
|