feat: Implement Policy Engine Evaluation Service and Cache with unit tests
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Temp commit to debug
This commit is contained in:
@@ -54,10 +54,10 @@ public sealed class ScansEndpointsTests
|
||||
Assert.Equal(payload.ScanId, status!.ScanId);
|
||||
Assert.Equal("Pending", status.Status);
|
||||
Assert.Equal("ghcr.io/demo/app:1.0.0", status.Image.Reference);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SubmitScanIsDeterministicForIdenticalPayloads()
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SubmitScanIsDeterministicForIdenticalPayloads()
|
||||
{
|
||||
using var factory = new ScannerApplicationFactory();
|
||||
using var client = factory.CreateClient();
|
||||
@@ -81,11 +81,98 @@ public sealed class ScansEndpointsTests
|
||||
Assert.Equal(firstPayload!.ScanId, secondPayload!.ScanId);
|
||||
Assert.True(firstPayload.Created);
|
||||
Assert.False(secondPayload.Created);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SubmitScanValidatesImageDescriptor()
|
||||
{
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ScanStatusIncludesSurfacePointersWhenArtifactsExist()
|
||||
{
|
||||
const string digest = "sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef";
|
||||
var digestValue = digest.Split(':', 2)[1];
|
||||
|
||||
using var factory = new ScannerApplicationFactory();
|
||||
|
||||
using (var scope = factory.Services.CreateScope())
|
||||
{
|
||||
var artifactRepository = scope.ServiceProvider.GetRequiredService<ArtifactRepository>();
|
||||
var linkRepository = scope.ServiceProvider.GetRequiredService<LinkRepository>();
|
||||
var artifactId = CatalogIdFactory.CreateArtifactId(ArtifactDocumentType.ImageBom, digest);
|
||||
|
||||
var artifact = new ArtifactDocument
|
||||
{
|
||||
Id = artifactId,
|
||||
Type = ArtifactDocumentType.ImageBom,
|
||||
Format = ArtifactDocumentFormat.CycloneDxJson,
|
||||
MediaType = "application/vnd.cyclonedx+json; version=1.6; view=inventory",
|
||||
BytesSha256 = digest,
|
||||
SizeBytes = 2048,
|
||||
Immutable = true,
|
||||
RefCount = 1,
|
||||
TtlClass = "default",
|
||||
CreatedAtUtc = DateTime.UtcNow,
|
||||
UpdatedAtUtc = DateTime.UtcNow
|
||||
};
|
||||
|
||||
await artifactRepository.UpsertAsync(artifact, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
var link = new LinkDocument
|
||||
{
|
||||
Id = CatalogIdFactory.CreateLinkId(LinkSourceType.Image, digest, artifactId),
|
||||
FromType = LinkSourceType.Image,
|
||||
FromDigest = digest,
|
||||
ArtifactId = artifactId,
|
||||
CreatedAtUtc = DateTime.UtcNow
|
||||
};
|
||||
|
||||
await linkRepository.UpsertAsync(link, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
var submitRequest = new ScanSubmitRequest
|
||||
{
|
||||
Image = new ScanImageDescriptor
|
||||
{
|
||||
Digest = digest
|
||||
}
|
||||
};
|
||||
|
||||
var submitResponse = await client.PostAsJsonAsync("/api/v1/scans", submitRequest);
|
||||
submitResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var submission = await submitResponse.Content.ReadFromJsonAsync<ScanSubmitResponse>();
|
||||
Assert.NotNull(submission);
|
||||
|
||||
var statusResponse = await client.GetAsync($"/api/v1/scans/{submission!.ScanId}");
|
||||
statusResponse.EnsureSuccessStatusCode();
|
||||
|
||||
var status = await statusResponse.Content.ReadFromJsonAsync<ScanStatusResponse>();
|
||||
Assert.NotNull(status);
|
||||
Assert.NotNull(status!.Surface);
|
||||
|
||||
var surface = status.Surface!;
|
||||
Assert.Equal("default", surface.Tenant);
|
||||
Assert.False(string.IsNullOrWhiteSpace(surface.ManifestDigest));
|
||||
Assert.NotNull(surface.ManifestUri);
|
||||
Assert.Contains("cas://scanner-artifacts/", surface.ManifestUri, StringComparison.Ordinal);
|
||||
|
||||
var manifest = surface.Manifest;
|
||||
Assert.Equal(digest, manifest.ImageDigest);
|
||||
Assert.Equal(surface.Tenant, manifest.Tenant);
|
||||
Assert.NotEqual(default, manifest.GeneratedAt);
|
||||
var manifestArtifact = Assert.Single(manifest.Artifacts);
|
||||
Assert.Equal("sbom-inventory", manifestArtifact.Kind);
|
||||
Assert.Equal("cdx-json", manifestArtifact.Format);
|
||||
Assert.Equal(digest, manifestArtifact.Digest);
|
||||
Assert.Equal("application/vnd.cyclonedx+json; version=1.6; view=inventory", manifestArtifact.MediaType);
|
||||
Assert.Equal("inventory", manifestArtifact.View);
|
||||
|
||||
var expectedUri = $"cas://scanner-artifacts/scanner/images/{digestValue}/sbom.cdx.json";
|
||||
Assert.Equal(expectedUri, manifestArtifact.Uri);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SubmitScanValidatesImageDescriptor()
|
||||
{
|
||||
using var factory = new ScannerApplicationFactory();
|
||||
using var client = factory.CreateClient();
|
||||
|
||||
@@ -462,7 +549,7 @@ public sealed class ScansEndpointsTests
|
||||
var storedResult = new EntryTraceResult(scanId, "sha256:test", generatedAt, graph, ndjson);
|
||||
|
||||
using var factory = new ScannerApplicationFactory(
|
||||
configuration: null,
|
||||
configureConfiguration: null,
|
||||
services =>
|
||||
{
|
||||
services.AddSingleton<IEntryTraceResultStore>(new StubEntryTraceResultStore(storedResult));
|
||||
@@ -485,7 +572,7 @@ public sealed class ScansEndpointsTests
|
||||
public async Task GetEntryTraceReturnsNotFoundWhenMissing()
|
||||
{
|
||||
using var factory = new ScannerApplicationFactory(
|
||||
configuration: null,
|
||||
configureConfiguration: null,
|
||||
services =>
|
||||
{
|
||||
services.AddSingleton<IEntryTraceResultStore>(new StubEntryTraceResultStore(null));
|
||||
|
||||
Reference in New Issue
Block a user