Refactor code structure for improved readability and maintainability; optimize performance in key functions.
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
using System.Collections.Immutable;
|
||||
using System.Text;
|
||||
using FluentAssertions;
|
||||
using StellaOps.DeltaVerdict.Engine;
|
||||
using StellaOps.DeltaVerdict.Models;
|
||||
using StellaOps.DeltaVerdict.Policy;
|
||||
using StellaOps.DeltaVerdict.Serialization;
|
||||
using StellaOps.DeltaVerdict.Signing;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.DeltaVerdict.Tests;
|
||||
|
||||
public class DeltaVerdictTests
|
||||
{
|
||||
[Fact]
|
||||
public void ComputeDelta_TracksComponentAndVulnerabilityChanges()
|
||||
{
|
||||
var baseVerdict = CreateVerdict(
|
||||
verdictId: "base",
|
||||
riskScore: 10,
|
||||
components:
|
||||
[
|
||||
new Component("pkg:apk/openssl@1.0", "openssl", "1.0", "apk", ["CVE-1"])
|
||||
],
|
||||
vulnerabilities:
|
||||
[
|
||||
new Vulnerability("CVE-1", "high", 7.1m, "pkg:apk/openssl@1.0", "reachable", "open")
|
||||
]);
|
||||
|
||||
var headVerdict = CreateVerdict(
|
||||
verdictId: "head",
|
||||
riskScore: 20,
|
||||
components:
|
||||
[
|
||||
new Component("pkg:apk/openssl@1.1", "openssl", "1.1", "apk", ["CVE-2"]),
|
||||
new Component("pkg:apk/zlib@2.0", "zlib", "2.0", "apk", [])
|
||||
],
|
||||
vulnerabilities:
|
||||
[
|
||||
new Vulnerability("CVE-2", "critical", 9.5m, "pkg:apk/openssl@1.1", "reachable", "open")
|
||||
]);
|
||||
|
||||
var engine = new DeltaComputationEngine(new FakeTimeProvider());
|
||||
var delta = engine.ComputeDelta(baseVerdict, headVerdict);
|
||||
|
||||
delta.AddedComponents.Should().Contain(c => c.Purl == "pkg:apk/zlib@2.0");
|
||||
delta.RemovedComponents.Should().Contain(c => c.Purl == "pkg:apk/openssl@1.0");
|
||||
delta.ChangedComponents.Should().Contain(c => c.Purl == "pkg:apk/openssl@1.0");
|
||||
delta.AddedVulnerabilities.Should().Contain(v => v.VulnerabilityId == "CVE-2");
|
||||
delta.RemovedVulnerabilities.Should().Contain(v => v.VulnerabilityId == "CVE-1");
|
||||
delta.RiskScoreDelta.Change.Should().Be(10);
|
||||
delta.Summary.TotalChanges.Should().BeGreaterThan(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RiskBudgetEvaluator_FlagsCriticalViolations()
|
||||
{
|
||||
var delta = new DeltaVerdict.Models.DeltaVerdict
|
||||
{
|
||||
DeltaId = "delta",
|
||||
SchemaVersion = "1.0.0",
|
||||
BaseVerdict = new VerdictReference("base", null, null, DateTimeOffset.UnixEpoch),
|
||||
HeadVerdict = new VerdictReference("head", null, null, DateTimeOffset.UnixEpoch),
|
||||
AddedVulnerabilities = [new VulnerabilityDelta("CVE-9", "critical", 9.9m, null, "reachable")],
|
||||
RemovedVulnerabilities = [],
|
||||
AddedComponents = [],
|
||||
RemovedComponents = [],
|
||||
ChangedComponents = [],
|
||||
ChangedVulnerabilityStatuses = [],
|
||||
RiskScoreDelta = new RiskScoreDelta(10, 15, 5, 50, RiskTrend.Degraded),
|
||||
Summary = new DeltaSummary(0, 0, 0, 1, 0, 0, 1, DeltaMagnitude.Minimal),
|
||||
ComputedAt = DateTimeOffset.UnixEpoch
|
||||
};
|
||||
|
||||
var budget = new RiskBudget
|
||||
{
|
||||
MaxNewCriticalVulnerabilities = 0,
|
||||
MaxRiskScoreIncrease = 2
|
||||
};
|
||||
|
||||
var evaluator = new RiskBudgetEvaluator();
|
||||
var result = evaluator.Evaluate(delta, budget);
|
||||
|
||||
result.IsWithinBudget.Should().BeFalse();
|
||||
result.Violations.Should().NotBeEmpty();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SigningService_RoundTrip_VerifiesEnvelope()
|
||||
{
|
||||
var delta = new DeltaVerdict.Models.DeltaVerdict
|
||||
{
|
||||
DeltaId = "delta",
|
||||
SchemaVersion = "1.0.0",
|
||||
BaseVerdict = new VerdictReference("base", null, null, DateTimeOffset.UnixEpoch),
|
||||
HeadVerdict = new VerdictReference("head", null, null, DateTimeOffset.UnixEpoch),
|
||||
AddedComponents = [],
|
||||
RemovedComponents = [],
|
||||
ChangedComponents = [],
|
||||
AddedVulnerabilities = [],
|
||||
RemovedVulnerabilities = [],
|
||||
ChangedVulnerabilityStatuses = [],
|
||||
RiskScoreDelta = new RiskScoreDelta(0, 0, 0, 0, RiskTrend.Stable),
|
||||
Summary = new DeltaSummary(0, 0, 0, 0, 0, 0, 0, DeltaMagnitude.None),
|
||||
ComputedAt = DateTimeOffset.UnixEpoch
|
||||
};
|
||||
|
||||
var service = new DeltaSigningService();
|
||||
var options = new SigningOptions
|
||||
{
|
||||
KeyId = "test-key",
|
||||
SecretBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes("delta-secret"))
|
||||
};
|
||||
|
||||
var signed = await service.SignAsync(delta, options);
|
||||
var verify = await service.VerifyAsync(signed, new VerificationOptions
|
||||
{
|
||||
KeyId = "test-key",
|
||||
SecretBase64 = options.SecretBase64
|
||||
});
|
||||
|
||||
verify.IsValid.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Serializer_ComputesDeterministicDigest()
|
||||
{
|
||||
var verdict = CreateVerdict(
|
||||
verdictId: "verdict",
|
||||
riskScore: 0,
|
||||
components: [],
|
||||
vulnerabilities: []);
|
||||
|
||||
var withDigest = VerdictSerializer.WithDigest(verdict);
|
||||
withDigest.Digest.Should().NotBeNullOrWhiteSpace();
|
||||
}
|
||||
|
||||
private static Verdict CreateVerdict(
|
||||
string verdictId,
|
||||
decimal riskScore,
|
||||
ImmutableArray<Component> components,
|
||||
ImmutableArray<Vulnerability> vulnerabilities)
|
||||
{
|
||||
return new Verdict
|
||||
{
|
||||
VerdictId = verdictId,
|
||||
Digest = null,
|
||||
ArtifactRef = "local",
|
||||
ScannedAt = DateTimeOffset.UnixEpoch,
|
||||
RiskScore = riskScore,
|
||||
Components = components,
|
||||
Vulnerabilities = vulnerabilities
|
||||
};
|
||||
}
|
||||
|
||||
private sealed class FakeTimeProvider : TimeProvider
|
||||
{
|
||||
public override DateTimeOffset GetUtcNow() => DateTimeOffset.UnixEpoch;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||
<PackageReference Include="xunit" Version="2.9.0" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.7">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\StellaOps.DeltaVerdict\StellaOps.DeltaVerdict.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user