Refactor code structure for improved readability and maintainability; optimize performance in key functions.

This commit is contained in:
master
2025-12-22 19:06:31 +02:00
parent dfaa2079aa
commit 0536a4f7d4
1443 changed files with 109671 additions and 7840 deletions

View File

@@ -0,0 +1,129 @@
namespace StellaOps.Interop.Tests.CycloneDx;
[Trait("Category", "Interop")]
[Trait("Format", "CycloneDX")]
public class CycloneDxRoundTripTests : IClassFixture<InteropTestHarness>
{
private readonly InteropTestHarness _harness;
public CycloneDxRoundTripTests(InteropTestHarness harness)
{
_harness = harness;
}
[Theory]
[MemberData(nameof(TestImages))]
public async Task Syft_GeneratesCycloneDx_GrypeCanConsume(string imageRef)
{
// Generate SBOM with Syft
var sbomResult = await _harness.GenerateSbomWithSyft(
imageRef, SbomFormat.CycloneDx16);
sbomResult.Success.Should().BeTrue("Syft should generate CycloneDX SBOM");
// Scan from SBOM with Grype
var grypeResult = await _harness.ScanWithGrypeFromSbom(sbomResult.Path!);
grypeResult.Success.Should().BeTrue("Grype should consume Syft-generated CycloneDX SBOM");
// Grype should be able to parse and find vulnerabilities
grypeResult.Findings.Should().NotBeNull();
}
[Theory]
[MemberData(nameof(TestImages))]
public async Task Stella_GeneratesCycloneDx_GrypeCanConsume(string imageRef)
{
// Generate SBOM with Stella
var sbomResult = await _harness.GenerateSbomWithStella(
imageRef, SbomFormat.CycloneDx16);
sbomResult.Success.Should().BeTrue("Stella should generate CycloneDX SBOM");
// Scan from SBOM with Grype
var grypeResult = await _harness.ScanWithGrypeFromSbom(sbomResult.Path!);
grypeResult.Success.Should().BeTrue("Grype should consume Stella-generated CycloneDX SBOM");
}
[Theory]
[MemberData(nameof(TestImages))]
[Trait("Category", "Parity")]
public async Task Stella_And_Grype_FindingsParity_Above95Percent(string imageRef)
{
// Generate SBOM with Stella
var stellaSbom = await _harness.GenerateSbomWithStella(
imageRef, SbomFormat.CycloneDx16);
stellaSbom.Success.Should().BeTrue();
// TODO: Get Stella findings from scan result
var stellaFindings = new List<Finding>();
// Scan SBOM with Grype
var grypeResult = await _harness.ScanWithGrypeFromSbom(stellaSbom.Path!);
grypeResult.Success.Should().BeTrue();
// Compare findings
var comparison = _harness.CompareFindings(
stellaFindings,
grypeResult.Findings!,
tolerancePercent: 5);
comparison.ParityPercent.Should().BeGreaterOrEqualTo(95,
$"Findings parity {comparison.ParityPercent:F2}% is below 95% threshold. " +
$"Only in Stella: {comparison.OnlyInStella}, Only in Grype: {comparison.OnlyInGrype}");
}
[Theory]
[MemberData(nameof(TestImages))]
[Trait("Category", "Attestation")]
public async Task CycloneDx_Attestation_RoundTrip(string imageRef)
{
// Skip if not in CI - cosign requires credentials
if (string.IsNullOrEmpty(Environment.GetEnvironmentVariable("CI")))
{
// Skip in local dev
return;
}
// Generate SBOM
var sbomResult = await _harness.GenerateSbomWithStella(
imageRef, SbomFormat.CycloneDx16);
sbomResult.Success.Should().BeTrue();
// Attest with cosign
var attestResult = await _harness.AttestWithCosign(
sbomResult.Path!, imageRef);
attestResult.Success.Should().BeTrue("Cosign should attest SBOM");
// TODO: Verify attestation
// var verifyResult = await _harness.VerifyCosignAttestation(imageRef);
// verifyResult.Success.Should().BeTrue();
// Digest should match
// var attestedDigest = verifyResult.PredicateDigest;
// attestedDigest.Should().Be(sbomResult.Digest);
}
[Fact]
[Trait("Category", "Schema")]
public async Task Stella_CycloneDx_ValidatesAgainstSchema()
{
var imageRef = "alpine:3.18";
// Generate SBOM
var sbomResult = await _harness.GenerateSbomWithStella(
imageRef, SbomFormat.CycloneDx16);
sbomResult.Success.Should().BeTrue();
// TODO: Validate against CycloneDX 1.6 JSON schema
sbomResult.Content.Should().NotBeNullOrEmpty();
sbomResult.Content.Should().Contain("\"bomFormat\": \"CycloneDX\"");
sbomResult.Content.Should().Contain("\"specVersion\": \"1.6\"");
}
public static IEnumerable<object[]> TestImages =>
[
["alpine:3.18"],
["debian:12-slim"],
["node:20-alpine"],
["python:3.12-slim"],
["golang:1.22-alpine"]
];
}