Refactor code structure for improved readability and maintainability; optimize performance in key functions.
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
using FluentAssertions;
|
||||
using StellaOps.Attestor.ProofChain.Models;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Attestor.ProofChain.Tests.Models;
|
||||
|
||||
public class UnknownsSummaryTests
|
||||
{
|
||||
[Fact]
|
||||
public void Empty_ReturnsZeroCounts()
|
||||
{
|
||||
var summary = UnknownsSummary.Empty;
|
||||
|
||||
summary.Total.Should().Be(0);
|
||||
summary.ByReasonCode.Should().BeEmpty();
|
||||
summary.BlockingCount.Should().Be(0);
|
||||
summary.ExceptedCount.Should().Be(0);
|
||||
summary.PolicyThresholdsApplied.Should().BeEmpty();
|
||||
summary.ExceptionsApplied.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Empty_ProducesValidSummary()
|
||||
{
|
||||
var summary = UnknownsSummary.Empty;
|
||||
|
||||
summary.Should().NotBeNull();
|
||||
summary.ByReasonCode.Should().NotBeNull();
|
||||
summary.PolicyThresholdsApplied.Should().NotBeNull();
|
||||
summary.ExceptionsApplied.Should().NotBeNull();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
using FluentAssertions;
|
||||
using StellaOps.Attestor.ProofChain.Services;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Attestor.ProofChain.Tests.Services;
|
||||
|
||||
public class UnknownsAggregatorTests
|
||||
{
|
||||
private readonly IUnknownsAggregator _aggregator;
|
||||
|
||||
public UnknownsAggregatorTests()
|
||||
{
|
||||
_aggregator = new UnknownsAggregator();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Aggregate_EmptyList_ReturnsEmptySummary()
|
||||
{
|
||||
var unknowns = new List<UnknownItem>();
|
||||
|
||||
var summary = _aggregator.Aggregate(unknowns);
|
||||
|
||||
summary.Total.Should().Be(0);
|
||||
summary.ByReasonCode.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Aggregate_GroupsByReasonCode()
|
||||
{
|
||||
var unknowns = new List<UnknownItem>
|
||||
{
|
||||
new("pkg:npm/foo@1.0", null, "Reachability", null),
|
||||
new("pkg:npm/bar@1.0", null, "Reachability", null),
|
||||
new("pkg:npm/baz@1.0", null, "Identity", null)
|
||||
};
|
||||
|
||||
var summary = _aggregator.Aggregate(unknowns);
|
||||
|
||||
summary.Total.Should().Be(3);
|
||||
summary.ByReasonCode["Reachability"].Should().Be(2);
|
||||
summary.ByReasonCode["Identity"].Should().Be(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Aggregate_ComputesDeterministicDigest()
|
||||
{
|
||||
var unknowns = CreateUnknowns();
|
||||
|
||||
var summary1 = _aggregator.Aggregate(unknowns);
|
||||
var summary2 = _aggregator.Aggregate(unknowns.Reverse().ToList());
|
||||
|
||||
summary1.UnknownsDigest.Should().Be(summary2.UnknownsDigest);
|
||||
summary1.UnknownsDigest.Should().NotBeNullOrEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Aggregate_IncludesExceptionIds()
|
||||
{
|
||||
var unknowns = CreateUnknowns();
|
||||
var exceptions = new List<ExceptionRef>
|
||||
{
|
||||
new("EXC-001", "Approved", new[] { "Reachability" })
|
||||
};
|
||||
|
||||
var summary = _aggregator.Aggregate(unknowns, null, exceptions);
|
||||
|
||||
summary.ExceptionsApplied.Should().Contain("EXC-001");
|
||||
summary.ExceptedCount.Should().Be(1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Aggregate_IncludesBudgetViolations()
|
||||
{
|
||||
var unknowns = CreateUnknowns();
|
||||
var budgetResult = new BudgetCheckResult
|
||||
{
|
||||
Violations = new Dictionary<string, BudgetViolation>
|
||||
{
|
||||
["Reachability"] = new BudgetViolation(5, 3),
|
||||
["Identity"] = new BudgetViolation(2, 1)
|
||||
}
|
||||
};
|
||||
|
||||
var summary = _aggregator.Aggregate(unknowns, budgetResult);
|
||||
|
||||
summary.BlockingCount.Should().Be(7); // 5 + 2
|
||||
summary.PolicyThresholdsApplied.Should().HaveCount(2);
|
||||
}
|
||||
|
||||
private static IReadOnlyList<UnknownItem> CreateUnknowns()
|
||||
{
|
||||
return new List<UnknownItem>
|
||||
{
|
||||
new("pkg:npm/foo@1.0", "CVE-2024-001", "Reachability", "Run reachability analysis"),
|
||||
new("pkg:npm/bar@2.0", "CVE-2024-002", "Identity", "Add package digest"),
|
||||
new("pkg:npm/baz@3.0", null, "VexConflict", "Review VEX statements")
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
// SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
// Copyright (c) StellaOps Contributors
|
||||
|
||||
using System.Text.Json;
|
||||
using StellaOps.Attestor.ProofChain.Predicates;
|
||||
using StellaOps.Attestor.ProofChain.Statements;
|
||||
|
||||
namespace StellaOps.Attestor.ProofChain.Tests.Statements;
|
||||
|
||||
public sealed class DeltaVerdictStatementTests
|
||||
{
|
||||
private static readonly DateTimeOffset FixedTime = new(2025, 12, 22, 12, 0, 0, TimeSpan.Zero);
|
||||
|
||||
[Fact]
|
||||
public void DeltaVerdictStatement_HasPredicateTypeAndPayload()
|
||||
{
|
||||
var statement = new DeltaVerdictStatement
|
||||
{
|
||||
Subject =
|
||||
[
|
||||
new Subject
|
||||
{
|
||||
Name = "sha256:before",
|
||||
Digest = new Dictionary<string, string> { ["sha256"] = "before" }
|
||||
},
|
||||
new Subject
|
||||
{
|
||||
Name = "sha256:after",
|
||||
Digest = new Dictionary<string, string> { ["sha256"] = "after" }
|
||||
}
|
||||
],
|
||||
Predicate = new DeltaVerdictPredicate
|
||||
{
|
||||
BeforeRevisionId = "rev-before",
|
||||
AfterRevisionId = "rev-after",
|
||||
HasMaterialChange = true,
|
||||
PriorityScore = 1750,
|
||||
Changes =
|
||||
[
|
||||
new DeltaVerdictChange
|
||||
{
|
||||
Rule = "R1_ReachabilityFlip",
|
||||
FindingKey = new DeltaFindingKey
|
||||
{
|
||||
VulnId = "CVE-2025-1234",
|
||||
Purl = "pkg:npm/lodash@4.17.20"
|
||||
},
|
||||
Direction = "increased",
|
||||
Reason = "Reachability changed from false to true"
|
||||
}
|
||||
],
|
||||
ComparedAt = FixedTime
|
||||
}
|
||||
};
|
||||
|
||||
Assert.Equal("delta-verdict.stella/v1", statement.PredicateType);
|
||||
Assert.Equal(2, statement.Subject.Count);
|
||||
Assert.Equal("rev-before", statement.Predicate.BeforeRevisionId);
|
||||
Assert.True(statement.Predicate.HasMaterialChange);
|
||||
Assert.Single(statement.Predicate.Changes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ReachabilitySubgraphStatement_RoundTrips()
|
||||
{
|
||||
var statement = new ReachabilitySubgraphStatement
|
||||
{
|
||||
Subject =
|
||||
[
|
||||
new Subject
|
||||
{
|
||||
Name = "sha256:graph",
|
||||
Digest = new Dictionary<string, string> { ["sha256"] = "graph" }
|
||||
}
|
||||
],
|
||||
Predicate = new ReachabilitySubgraphPredicate
|
||||
{
|
||||
GraphDigest = "blake3:deadbeef",
|
||||
FindingKeys = ["CVE-2025-9999@pkg:npm/example@1.0.0"],
|
||||
Analysis = new ReachabilitySubgraphAnalysis
|
||||
{
|
||||
Analyzer = "reachability",
|
||||
AnalyzerVersion = "1.0.0",
|
||||
Confidence = 0.9,
|
||||
Completeness = "partial",
|
||||
GeneratedAt = FixedTime
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var json = JsonSerializer.Serialize(statement);
|
||||
var restored = JsonSerializer.Deserialize<ReachabilitySubgraphStatement>(json);
|
||||
|
||||
Assert.NotNull(restored);
|
||||
Assert.Equal("reachability-subgraph.stella/v1", restored!.PredicateType);
|
||||
Assert.Equal("blake3:deadbeef", restored.Predicate.GraphDigest);
|
||||
Assert.Single(restored.Predicate.FindingKeys);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user