up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
SDK Publish & Sign / sdk-publish (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-11-25 22:09:44 +02:00
parent 6bee1fdcf5
commit 9f6e6f7fb3
116 changed files with 4495 additions and 730 deletions

View File

@@ -0,0 +1,90 @@
using System;
using System.Collections.Immutable;
using StellaOps.Excititor.Core;
using StellaOps.Excititor.Core.Observations;
using StellaOps.Excititor.WebService.Graph;
using Xunit;
namespace StellaOps.Excititor.WebService.Tests;
public sealed class GraphStatusFactoryTests
{
[Fact]
public void Build_ProjectsOverlaySummariesAndProvenance()
{
var now = DateTimeOffset.UtcNow;
var observations = new[]
{
CreateObservation(
providerId: "ubuntu",
createdAt: now,
purls: new[] { "pkg:rpm/redhat/openssl@1.1.1" },
statements: new[]
{
new VexObservationStatement(
vulnerabilityId: "CVE-2025-1001",
productKey: "pkg:rpm/redhat/openssl@1.1.1",
status: VexClaimStatus.NotAffected,
lastObserved: now,
justification: VexJustification.ComponentNotPresent,
purl: "pkg:rpm/redhat/openssl@1.1.1")
},
contentHash: "hash-new"),
CreateObservation(
providerId: "oracle",
createdAt: now.AddMinutes(-2),
purls: new[] { "pkg:rpm/redhat/openssl@1.1.1" },
statements: Array.Empty<VexObservationStatement>(),
contentHash: "hash-old")
};
var items = GraphStatusFactory.Build(
orderedPurls: new[] { "pkg:rpm/redhat/openssl@1.1.1" },
observations: observations);
var item = Assert.Single(items);
Assert.Equal("pkg:rpm/redhat/openssl@1.1.1", item.Purl);
Assert.Equal(0, item.Summary.Open);
Assert.Equal(1, item.Summary.NotAffected);
Assert.Equal(0, item.Summary.UnderInvestigation);
Assert.Equal(1, item.Summary.NoStatement);
Assert.Equal(now, item.LatestModifiedAt);
Assert.Equal("hash-new", item.LastEvidenceHash);
Assert.Equal(new[] { "oracle", "ubuntu" }, item.Sources);
}
private static VexObservation CreateObservation(
string providerId,
DateTimeOffset createdAt,
string[] purls,
VexObservationStatement[] statements,
string contentHash)
{
return new VexObservation(
observationId: $"obs-{providerId}-{createdAt.ToUnixTimeMilliseconds()}",
tenant: "tenant-a",
providerId: providerId,
streamId: "csaf",
upstream: new VexObservationUpstream(
upstreamId: Guid.NewGuid().ToString("N"),
documentVersion: "1",
fetchedAt: createdAt,
receivedAt: createdAt,
contentHash: contentHash,
signature: new VexObservationSignature(present: true, format: "sig", keyId: null, signature: null)),
statements: statements.ToImmutableArray(),
content: new VexObservationContent(
format: "csaf",
specVersion: "1",
raw: System.Text.Json.Nodes.JsonValue.Create("raw")!,
metadata: ImmutableDictionary<string, string>.Empty),
linkset: new VexObservationLinkset(
aliases: Array.Empty<string>(),
purls: purls,
cpes: Array.Empty<string>(),
references: Array.Empty<VexObservationReference>()),
createdAt: createdAt,
supersedes: ImmutableArray<string>.Empty,
attributes: ImmutableDictionary<string, string>.Empty);
}
}

View File

@@ -0,0 +1,137 @@
using System;
using System.Collections.Immutable;
using System.Linq;
using StellaOps.Excititor.Core;
using StellaOps.Excititor.Core.Observations;
using StellaOps.Excititor.WebService.Graph;
using Xunit;
namespace StellaOps.Excititor.WebService.Tests;
public sealed class GraphTooltipFactoryTests
{
[Fact]
public void Build_OrdersByNewestAndTruncatesPerPurl()
{
var now = DateTimeOffset.UtcNow;
var observations = new[]
{
CreateObservation(
providerId: "ubuntu",
createdAt: now,
purls: new[] { "pkg:rpm/openssl@1.1.1" },
statements: new[]
{
new VexObservationStatement(
vulnerabilityId: "CVE-2025-1000",
productKey: "pkg:rpm/openssl@1.1.1",
status: VexClaimStatus.NotAffected,
lastObserved: now,
justification: VexJustification.ComponentNotPresent,
purl: "pkg:rpm/openssl@1.1.1")
},
contentHash: "hash-ubuntu"),
CreateObservation(
providerId: "redhat",
createdAt: now.AddMinutes(-1),
purls: new[] { "pkg:rpm/openssl@1.1.1" },
statements: new[]
{
new VexObservationStatement(
vulnerabilityId: "CVE-2025-1000",
productKey: "pkg:rpm/openssl@1.1.1",
status: VexClaimStatus.UnderInvestigation,
lastObserved: now.AddMinutes(-1),
justification: null,
purl: "pkg:rpm/openssl@1.1.1")
},
contentHash: "hash-redhat")
};
var items = GraphTooltipFactory.Build(
orderedPurls: new[] { "pkg:rpm/openssl@1.1.1" },
observations: observations,
includeJustifications: true,
maxItemsPerPurl: 1);
var item = Assert.Single(items);
Assert.True(item.Truncated);
var obs = Assert.Single(item.Observations);
Assert.Equal("CVE-2025-1000", obs.AdvisoryId);
Assert.Equal("notaffected", obs.Status);
Assert.Equal("ComponentNotPresent", obs.Justification);
Assert.Equal("ubuntu", obs.ProviderId);
Assert.Equal("hash-ubuntu", obs.EvidenceHash);
}
[Fact]
public void Build_UsesLinksetPurlsWhenStatementMissing()
{
var now = DateTimeOffset.UtcNow;
var observations = new[]
{
CreateObservation(
providerId: "oracle",
createdAt: now,
purls: new[] { "pkg:rpm/httpd@2.4.0" },
statements: new[]
{
new VexObservationStatement(
vulnerabilityId: "CVE-2025-2000",
productKey: "pkg:rpm/httpd@2.4.0",
status: VexClaimStatus.Affected,
lastObserved: now,
justification: null,
purl: null)
},
contentHash: "hash-oracle")
};
var items = GraphTooltipFactory.Build(
orderedPurls: new[] { "pkg:rpm/httpd@2.4.0" },
observations: observations,
includeJustifications: false,
maxItemsPerPurl: 5);
var item = Assert.Single(items);
var observation = Assert.Single(item.Observations);
Assert.Null(observation.Justification);
Assert.Equal("oracle", observation.ProviderId);
Assert.Equal("CVE-2025-2000", observation.AdvisoryId);
}
private static VexObservation CreateObservation(
string providerId,
DateTimeOffset createdAt,
string[] purls,
VexObservationStatement[] statements,
string contentHash)
{
return new VexObservation(
observationId: $"obs-{providerId}-{createdAt.ToUnixTimeMilliseconds()}",
tenant: "tenant-a",
providerId: providerId,
streamId: "csaf",
upstream: new VexObservationUpstream(
upstreamId: Guid.NewGuid().ToString("N"),
documentVersion: "1",
fetchedAt: createdAt,
receivedAt: createdAt,
contentHash: contentHash,
signature: new VexObservationSignature(present: true, format: "sig", keyId: null, signature: null)),
statements: statements.ToImmutableArray(),
content: new VexObservationContent(
format: "csaf",
specVersion: "1",
raw: System.Text.Json.Nodes.JsonValue.Create("raw")!,
metadata: ImmutableDictionary<string, string>.Empty),
linkset: new VexObservationLinkset(
aliases: Array.Empty<string>(),
purls: purls,
cpes: Array.Empty<string>(),
references: Array.Empty<VexObservationReference>()),
createdAt: createdAt,
supersedes: ImmutableArray<string>.Empty,
attributes: ImmutableDictionary<string, string>.Empty);
}
}

View File

@@ -37,6 +37,8 @@
<Compile Include="TestServiceOverrides.cs" />
<Compile Include="TestWebApplicationFactory.cs" />
<Compile Include="GraphOverlayFactoryTests.cs" />
<Compile Include="GraphStatusFactoryTests.cs" />
<Compile Include="GraphTooltipFactoryTests.cs" />
<Compile Include="AttestationVerifyEndpointTests.cs" />
</ItemGroup>
</Project>