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
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:
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user