60 lines
2.6 KiB
C#
60 lines
2.6 KiB
C#
using System.Collections.Immutable;
|
|
using System.IO.Abstractions.TestingHelpers;
|
|
using System.Linq;
|
|
using System.Text.Json;
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
using Microsoft.Extensions.Options;
|
|
using StellaOps.Excititor.Core;
|
|
using StellaOps.Excititor.Export;
|
|
|
|
namespace StellaOps.Excititor.Export.Tests;
|
|
|
|
public sealed class OfflineBundleArtifactStoreTests
|
|
{
|
|
[Fact]
|
|
public async Task SaveAsync_WritesArtifactAndManifest()
|
|
{
|
|
var fs = new MockFileSystem();
|
|
var options = Options.Create(new OfflineBundleArtifactStoreOptions { RootPath = "/offline" });
|
|
var store = new OfflineBundleArtifactStore(options, NullLogger<OfflineBundleArtifactStore>.Instance, fs);
|
|
|
|
var content = new byte[] { 1, 2, 3 };
|
|
var digest = "sha256:" + Convert.ToHexString(System.Security.Cryptography.SHA256.HashData(content)).ToLowerInvariant();
|
|
var artifact = new VexExportArtifact(
|
|
new VexContentAddress("sha256", digest.Split(':')[1]),
|
|
VexExportFormat.Json,
|
|
content,
|
|
ImmutableDictionary<string, string>.Empty);
|
|
|
|
var stored = await store.SaveAsync(artifact, CancellationToken.None);
|
|
|
|
var artifactPath = fs.Path.Combine(options.Value.RootPath, stored.Location);
|
|
Assert.True(fs.FileExists(artifactPath));
|
|
|
|
var manifestPath = fs.Path.Combine(options.Value.RootPath, options.Value.ManifestFileName);
|
|
Assert.True(fs.FileExists(manifestPath));
|
|
await using var manifestStream = fs.File.OpenRead(manifestPath);
|
|
using var document = await JsonDocument.ParseAsync(manifestStream);
|
|
var artifacts = document.RootElement.GetProperty("artifacts");
|
|
Assert.True(artifacts.GetArrayLength() >= 1);
|
|
var first = artifacts.EnumerateArray().First();
|
|
Assert.Equal(digest, first.GetProperty("digest").GetString());
|
|
}
|
|
|
|
[Fact]
|
|
public async Task SaveAsync_ThrowsOnDigestMismatch()
|
|
{
|
|
var fs = new MockFileSystem();
|
|
var options = Options.Create(new OfflineBundleArtifactStoreOptions { RootPath = "/offline" });
|
|
var store = new OfflineBundleArtifactStore(options, NullLogger<OfflineBundleArtifactStore>.Instance, fs);
|
|
|
|
var artifact = new VexExportArtifact(
|
|
new VexContentAddress("sha256", "deadbeef"),
|
|
VexExportFormat.Json,
|
|
new byte[] { 0x01, 0x02 },
|
|
ImmutableDictionary<string, string>.Empty);
|
|
|
|
await Assert.ThrowsAsync<InvalidOperationException>(() => store.SaveAsync(artifact, CancellationToken.None).AsTask());
|
|
}
|
|
}
|