Implement MongoDB-based storage for Pack Run approval, artifact, log, and state management
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled

- Added MongoPackRunApprovalStore for managing approval states with MongoDB.
- Introduced MongoPackRunArtifactUploader for uploading and storing artifacts.
- Created MongoPackRunLogStore to handle logging of pack run events.
- Developed MongoPackRunStateStore for persisting and retrieving pack run states.
- Implemented unit tests for MongoDB stores to ensure correct functionality.
- Added MongoTaskRunnerTestContext for setting up MongoDB test environment.
- Enhanced PackRunStateFactory to correctly initialize state with gate reasons.
This commit is contained in:
master
2025-11-07 10:01:35 +02:00
parent e5ffcd6535
commit a1ce3f74fa
122 changed files with 8730 additions and 914 deletions

View File

@@ -0,0 +1,95 @@
using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using StellaOps.Scanner.Sbomer.BuildXPlugin.Surface;
using StellaOps.Scanner.Sbomer.BuildXPlugin.Tests.TestUtilities;
using Xunit;
namespace StellaOps.Scanner.Sbomer.BuildXPlugin.Tests.Surface;
public sealed class SurfaceManifestWriterTests
{
[Fact]
public async Task WriteAsync_PersistsArtifactsAndManifest()
{
await using var temp = new TempDirectory();
var fragmentsPath = Path.Combine(temp.Path, "layer-fragments.json");
await File.WriteAllTextAsync(fragmentsPath, "[]");
var graphPath = Path.Combine(temp.Path, "entrytrace-graph.json");
await File.WriteAllTextAsync(graphPath, "{\"nodes\":[],\"edges\":[]}");
var ndjsonPath = Path.Combine(temp.Path, "entrytrace.ndjson");
await File.WriteAllTextAsync(ndjsonPath, "{}\n{}");
var manifestOutputPath = Path.Combine(temp.Path, "out", "surface-manifest.json");
var options = new SurfaceOptions(
CacheRoot: temp.Path,
CacheBucket: "scanner-artifacts",
RootPrefix: "scanner",
Tenant: "tenant-a",
Component: "scanner.buildx",
ComponentVersion: "1.2.3",
WorkerInstance: "builder-01",
Attempt: 2,
ImageDigest: "sha256:feedface",
ScanId: "scan-123",
LayerFragmentsPath: fragmentsPath,
EntryTraceGraphPath: graphPath,
EntryTraceNdjsonPath: ndjsonPath,
ManifestOutputPath: manifestOutputPath);
var writer = new SurfaceManifestWriter(TimeProvider.System);
var result = await writer.WriteAsync(options, CancellationToken.None);
Assert.NotNull(result);
Assert.NotNull(result!.Document.Source);
Assert.Equal("tenant-a", result.Document.Tenant);
Assert.Equal("scanner.buildx", result.Document.Source!.Component);
Assert.Equal("1.2.3", result.Document.Source.Version);
Assert.Equal(3, result.Document.Artifacts.Count);
var kinds = result.Document.Artifacts.Select(a => a.Kind).ToHashSet();
Assert.Contains("entrytrace.graph", kinds);
Assert.Contains("entrytrace.ndjson", kinds);
Assert.Contains("layer.fragments", kinds);
Assert.True(File.Exists(result.ManifestPath));
Assert.True(File.Exists(manifestOutputPath));
foreach (var artifact in result.Artifacts)
{
Assert.True(File.Exists(artifact.FilePath));
Assert.False(string.IsNullOrWhiteSpace(artifact.ManifestArtifact.Uri));
Assert.StartsWith("cas://scanner-artifacts/", artifact.ManifestArtifact.Uri, StringComparison.Ordinal);
}
}
[Fact]
public async Task WriteAsync_NoArtifacts_ReturnsNull()
{
await using var temp = new TempDirectory();
var options = new SurfaceOptions(
CacheRoot: temp.Path,
CacheBucket: "scanner-artifacts",
RootPrefix: "scanner",
Tenant: "tenant-a",
Component: "scanner.buildx",
ComponentVersion: "1.0",
WorkerInstance: "builder-01",
Attempt: 1,
ImageDigest: "sha256:deadbeef",
ScanId: "scan-1",
LayerFragmentsPath: null,
EntryTraceGraphPath: null,
EntryTraceNdjsonPath: null,
ManifestOutputPath: null);
var writer = new SurfaceManifestWriter(TimeProvider.System);
var result = await writer.WriteAsync(options, CancellationToken.None);
Assert.Null(result);
}
}