test: prove package lifecycle isolation and recovery
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
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); }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user