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 4602ccc3a3
1444 changed files with 109919 additions and 8058 deletions

View File

@@ -0,0 +1,165 @@
using FluentAssertions;
using Microsoft.Extensions.Options;
using StellaOps.Policy.Confidence.Configuration;
using StellaOps.Policy.Confidence.Models;
using StellaOps.Policy.Confidence.Services;
using Xunit;
namespace StellaOps.Policy.Tests.Confidence;
public sealed class ConfidenceCalculatorTests
{
private static readonly DateTimeOffset FixedTimestamp = new(2025, 12, 22, 12, 0, 0, TimeSpan.Zero);
[Fact]
public void Calculate_AllHighFactors_ReturnsVeryHighConfidence()
{
var calculator = CreateCalculator();
var input = CreateInput(
reachability: ReachabilityState.ConfirmedUnreachable,
runtime: RuntimePosture.Supports,
vex: VexStatus.NotAffected,
provenance: ProvenanceLevel.SlsaLevel3,
policyStrength: 1.0m);
var result = calculator.Calculate(input);
result.Tier.Should().Be(ConfidenceTier.VeryHigh);
result.Value.Should().BeGreaterThanOrEqualTo(0.9m);
}
[Fact]
public void Calculate_AllLowFactors_ReturnsLowConfidence()
{
var calculator = CreateCalculator();
var input = CreateInput(
reachability: ReachabilityState.Unknown,
runtime: RuntimePosture.Contradicts,
vex: VexStatus.UnderInvestigation,
provenance: ProvenanceLevel.Unsigned,
policyStrength: 0.3m);
var result = calculator.Calculate(input);
result.Tier.Should().Be(ConfidenceTier.Low);
}
[Fact]
public void Calculate_MissingEvidence_UsesFallbackValues()
{
var calculator = CreateCalculator();
var input = new ConfidenceInput();
var result = calculator.Calculate(input);
result.Value.Should().BeApproximately(0.47m, 0.05m);
result.Factors.Should().AllSatisfy(f => f.Reason.Should().Contain("No"));
}
[Fact]
public void Calculate_GeneratesImprovements_ForLowFactors()
{
var calculator = CreateCalculator();
var input = CreateInput(reachability: ReachabilityState.Unknown);
var result = calculator.Calculate(input);
result.Improvements.Should().Contain(i => i.Factor == ConfidenceFactorType.Reachability);
}
[Fact]
public void Calculate_WeightsSumToOne()
{
var options = new ConfidenceWeightOptions();
options.Validate().Should().BeTrue();
}
[Fact]
public void Calculate_FactorContributions_SumToValue()
{
var calculator = CreateCalculator();
var input = CreateInput();
var result = calculator.Calculate(input);
var sumOfContributions = result.Factors.Sum(f => f.Contribution);
result.Value.Should().BeApproximately(sumOfContributions, 0.001m);
}
private static ConfidenceInput CreateInput(
ReachabilityState reachability = ReachabilityState.StaticUnreachable,
RuntimePosture runtime = RuntimePosture.Supports,
VexStatus vex = VexStatus.NotAffected,
ProvenanceLevel provenance = ProvenanceLevel.Signed,
decimal policyStrength = 0.8m)
{
return new ConfidenceInput
{
Reachability = new ReachabilityEvidence
{
State = reachability,
AnalysisConfidence = 1.0m,
GraphDigests = ["sha256:reachability"]
},
Runtime = new RuntimeEvidence
{
Posture = runtime,
ObservationCount = 3,
LastObserved = FixedTimestamp,
SessionDigests = ["sha256:runtime"]
},
Vex = new VexEvidence
{
Statements =
[
new VexStatement
{
Status = vex,
Issuer = "NVD",
TrustScore = 0.95m,
Timestamp = FixedTimestamp,
StatementDigest = "sha256:vex"
}
]
},
Provenance = new ProvenanceEvidence
{
Level = provenance,
SbomCompleteness = 0.95m,
AttestationDigests = ["sha256:attestation"]
},
Policy = new PolicyEvidence
{
RuleName = "rule-1",
MatchStrength = policyStrength,
EvaluationDigest = "sha256:policy"
},
EvaluationTimestamp = FixedTimestamp
};
}
private static ConfidenceCalculator CreateCalculator()
{
return new ConfidenceCalculator(new StaticOptionsMonitor<ConfidenceWeightOptions>(new ConfidenceWeightOptions()));
}
private sealed class StaticOptionsMonitor<T> : IOptionsMonitor<T>
{
private readonly T _value;
public StaticOptionsMonitor(T value) => _value = value;
public T CurrentValue => _value;
public T Get(string? name) => _value;
public IDisposable OnChange(Action<T, string> listener) => NullDisposable.Instance;
private sealed class NullDisposable : IDisposable
{
public static readonly NullDisposable Instance = new();
public void Dispose() { }
}
}
}

View File

@@ -0,0 +1,208 @@
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using StellaOps.Policy.Freshness;
using Xunit;
namespace StellaOps.Policy.Tests.Freshness;
public sealed class EvidenceTtlEnforcerTests
{
private readonly EvidenceTtlEnforcer _enforcer;
private readonly EvidenceTtlOptions _options;
public EvidenceTtlEnforcerTests()
{
_options = new EvidenceTtlOptions();
_enforcer = new EvidenceTtlEnforcer(
Options.Create(_options),
NullLogger<EvidenceTtlEnforcer>.Instance);
}
[Fact]
public void CheckFreshness_AllFresh_ReturnsFresh()
{
var now = DateTimeOffset.UtcNow;
var bundle = new EvidenceBundle
{
Reachability = new ReachabilityEvidence { ComputedAt = now.AddHours(-1) },
VexStatus = new VexEvidence { Timestamp = now.AddHours(-1) },
Provenance = new ProvenanceEvidence { BuildTime = now.AddDays(-1) }
};
var result = _enforcer.CheckFreshness(bundle, now);
Assert.Equal(FreshnessStatus.Fresh, result.OverallStatus);
Assert.True(result.IsAcceptable);
Assert.False(result.HasWarnings);
}
[Fact]
public void CheckFreshness_ReachabilityNearExpiry_ReturnsWarning()
{
var now = DateTimeOffset.UtcNow;
var bundle = new EvidenceBundle
{
// 7 day TTL, 20% warning threshold = warn after 5.6 days
// At 6 days old, should be in warning state
Reachability = new ReachabilityEvidence { ComputedAt = now.AddDays(-6) }
};
var result = _enforcer.CheckFreshness(bundle, now);
Assert.Equal(FreshnessStatus.Warning, result.OverallStatus);
Assert.True(result.IsAcceptable);
Assert.True(result.HasWarnings);
var reachabilityCheck = result.Checks.First(c => c.Type == EvidenceType.Reachability);
Assert.Equal(FreshnessStatus.Warning, reachabilityCheck.Status);
}
[Fact]
public void CheckFreshness_BoundaryExpired_ReturnsStale()
{
var now = DateTimeOffset.UtcNow;
var bundle = new EvidenceBundle
{
// 72 hour TTL, so 5 days is definitely expired
Boundary = new BoundaryEvidence { ObservedAt = now.AddDays(-5) }
};
var result = _enforcer.CheckFreshness(bundle, now);
Assert.Equal(FreshnessStatus.Stale, result.OverallStatus);
Assert.False(result.IsAcceptable);
var boundaryCheck = result.Checks.First(c => c.Type == EvidenceType.Boundary);
Assert.Equal(FreshnessStatus.Stale, boundaryCheck.Status);
Assert.True(boundaryCheck.Remaining == TimeSpan.Zero);
}
[Theory]
[InlineData(EvidenceType.Sbom, 30)]
[InlineData(EvidenceType.Boundary, 3)]
[InlineData(EvidenceType.Reachability, 7)]
[InlineData(EvidenceType.Vex, 14)]
[InlineData(EvidenceType.PolicyDecision, 1)]
[InlineData(EvidenceType.HumanApproval, 30)]
[InlineData(EvidenceType.CallStack, 7)]
public void GetTtl_ReturnsConfiguredValue(EvidenceType type, int expectedDays)
{
var ttl = _enforcer.GetTtl(type);
Assert.Equal(expectedDays, ttl.TotalDays, precision: 1);
}
[Fact]
public void CheckFreshness_MixedStates_ReturnsStaleOverall()
{
var now = DateTimeOffset.UtcNow;
var bundle = new EvidenceBundle
{
Reachability = new ReachabilityEvidence { ComputedAt = now.AddHours(-1) }, // Fresh
Boundary = new BoundaryEvidence { ObservedAt = now.AddDays(-5) }, // Stale (72h TTL)
VexStatus = new VexEvidence { Timestamp = now.AddDays(-2) } // Fresh
};
var result = _enforcer.CheckFreshness(bundle, now);
Assert.Equal(FreshnessStatus.Stale, result.OverallStatus);
Assert.False(result.IsAcceptable);
Assert.Equal(3, result.Checks.Count);
var freshChecks = result.Checks.Where(c => c.Status == FreshnessStatus.Fresh).ToList();
var staleChecks = result.Checks.Where(c => c.Status == FreshnessStatus.Stale).ToList();
Assert.Equal(2, freshChecks.Count);
Assert.Single(staleChecks);
Assert.Equal(EvidenceType.Boundary, staleChecks[0].Type);
}
[Fact]
public void ComputeExpiration_CalculatesCorrectly()
{
var createdAt = new DateTimeOffset(2025, 1, 1, 0, 0, 0, TimeSpan.Zero);
var expiresAt = _enforcer.ComputeExpiration(EvidenceType.Boundary, createdAt);
// Boundary TTL is 72 hours = 3 days
Assert.Equal(createdAt.AddHours(72), expiresAt);
}
[Fact]
public void CheckFreshness_EmptyBundle_ReturnsEmptyChecks()
{
var now = DateTimeOffset.UtcNow;
var bundle = new EvidenceBundle();
var result = _enforcer.CheckFreshness(bundle, now);
Assert.Equal(FreshnessStatus.Fresh, result.OverallStatus);
Assert.Empty(result.Checks);
}
[Fact]
public void CheckFreshness_CustomOptions_UsesCustomTtl()
{
var customOptions = new EvidenceTtlOptions
{
BoundaryTtl = TimeSpan.FromDays(1), // Custom: 1 day instead of default 3 days
WarningThresholdPercent = 0.5 // Custom: 50% instead of default 20%
};
var customEnforcer = new EvidenceTtlEnforcer(
Options.Create(customOptions),
NullLogger<EvidenceTtlEnforcer>.Instance);
var now = DateTimeOffset.UtcNow;
var bundle = new EvidenceBundle
{
// 1 day TTL with 50% warning threshold = warn after 12 hours
// At 16 hours old, should be in warning state
Boundary = new BoundaryEvidence { ObservedAt = now.AddHours(-16) }
};
var result = customEnforcer.CheckFreshness(bundle, now);
Assert.Equal(FreshnessStatus.Warning, result.OverallStatus);
}
[Fact]
public void CheckType_GeneratesCorrectMessage()
{
var now = DateTimeOffset.UtcNow;
var bundle = new EvidenceBundle
{
Reachability = new ReachabilityEvidence { ComputedAt = now.AddDays(-8) } // Expired (7 day TTL)
};
var result = _enforcer.CheckFreshness(bundle, now);
var check = result.Checks.First();
Assert.Equal(EvidenceType.Reachability, check.Type);
Assert.Contains("expired", check.Message, StringComparison.OrdinalIgnoreCase);
Assert.Contains("ago", check.Message, StringComparison.OrdinalIgnoreCase);
}
[Fact]
public void CheckFreshness_RecommendedAction_BasedOnConfiguration()
{
var blockOptions = new EvidenceTtlOptions
{
StaleAction = StaleEvidenceAction.Block
};
var blockEnforcer = new EvidenceTtlEnforcer(
Options.Create(blockOptions),
NullLogger<EvidenceTtlEnforcer>.Instance);
var now = DateTimeOffset.UtcNow;
var bundle = new EvidenceBundle
{
Boundary = new BoundaryEvidence { ObservedAt = now.AddDays(-5) } // Stale
};
var result = blockEnforcer.CheckFreshness(bundle, now);
Assert.Equal(StaleEvidenceAction.Block, result.RecommendedAction);
}
}

View File

@@ -0,0 +1,98 @@
using FluentAssertions;
using StellaOps.Policy.TrustLattice;
using VexStatus = StellaOps.Policy.Confidence.Models.VexStatus;
using Xunit;
namespace StellaOps.Policy.Tests.TrustLattice;
public sealed class ClaimScoreMergerTests
{
[Fact]
public void Merge_SelectsHighestScore()
{
var claims = new List<(VexClaim, ClaimScoreResult)>
{
(new VexClaim
{
SourceId = "source-a",
Status = VexStatus.NotAffected,
ScopeSpecificity = 2,
IssuedAt = DateTimeOffset.Parse("2025-01-01T00:00:00Z"),
}, new ClaimScoreResult { Score = 0.7, BaseTrust = 0.7, StrengthMultiplier = 1, FreshnessMultiplier = 1 }),
(new VexClaim
{
SourceId = "source-b",
Status = VexStatus.NotAffected,
ScopeSpecificity = 3,
IssuedAt = DateTimeOffset.Parse("2025-01-02T00:00:00Z"),
}, new ClaimScoreResult { Score = 0.9, BaseTrust = 0.9, StrengthMultiplier = 1, FreshnessMultiplier = 1 }),
};
var merger = new ClaimScoreMerger();
var result = merger.Merge(claims, new MergePolicy());
result.Status.Should().Be(VexStatus.NotAffected);
result.WinningClaim.SourceId.Should().Be("source-b");
result.Confidence.Should().Be(0.9);
}
[Fact]
public void Merge_AppliesConflictPenalty()
{
var claims = new List<(VexClaim, ClaimScoreResult)>
{
(new VexClaim
{
SourceId = "source-a",
Status = VexStatus.NotAffected,
ScopeSpecificity = 2,
IssuedAt = DateTimeOffset.Parse("2025-01-01T00:00:00Z"),
}, new ClaimScoreResult { Score = 0.8, BaseTrust = 0.8, StrengthMultiplier = 1, FreshnessMultiplier = 1 }),
(new VexClaim
{
SourceId = "source-b",
Status = VexStatus.Affected,
ScopeSpecificity = 1,
IssuedAt = DateTimeOffset.Parse("2025-01-01T00:00:00Z"),
}, new ClaimScoreResult { Score = 0.7, BaseTrust = 0.7, StrengthMultiplier = 1, FreshnessMultiplier = 1 }),
};
var merger = new ClaimScoreMerger();
var result = merger.Merge(claims, new MergePolicy { ConflictPenalty = 0.25 });
result.HasConflicts.Should().BeTrue();
result.RequiresReplayProof.Should().BeTrue();
result.Conflicts.Should().HaveCount(1);
result.AllClaims.Should().Contain(c => c.SourceId == "source-b" && c.AdjustedScore == 0.525);
}
[Fact]
public void Merge_IsDeterministic()
{
var claims = new List<(VexClaim, ClaimScoreResult)>
{
(new VexClaim
{
SourceId = "source-a",
Status = VexStatus.Fixed,
ScopeSpecificity = 1,
IssuedAt = DateTimeOffset.Parse("2025-01-01T00:00:00Z"),
}, new ClaimScoreResult { Score = 0.6, BaseTrust = 0.6, StrengthMultiplier = 1, FreshnessMultiplier = 1 }),
(new VexClaim
{
SourceId = "source-b",
Status = VexStatus.Fixed,
ScopeSpecificity = 1,
IssuedAt = DateTimeOffset.Parse("2025-01-01T00:00:00Z"),
}, new ClaimScoreResult { Score = 0.6, BaseTrust = 0.6, StrengthMultiplier = 1, FreshnessMultiplier = 1 }),
};
var merger = new ClaimScoreMerger();
var expected = merger.Merge(claims, new MergePolicy());
for (var i = 0; i < 1000; i++)
{
merger.Merge(claims, new MergePolicy()).WinningClaim.SourceId.Should().Be(expected.WinningClaim.SourceId);
}
}
}

View File

@@ -0,0 +1,98 @@
using System.Collections.Immutable;
using FluentAssertions;
using StellaOps.Policy.Gates;
using StellaOps.Policy.TrustLattice;
using VexStatus = StellaOps.Policy.Confidence.Models.VexStatus;
using Xunit;
namespace StellaOps.Policy.Tests.TrustLattice;
public sealed class PolicyGateRegistryTests
{
[Fact]
public async Task Registry_StopsOnFirstFailure()
{
var registry = new PolicyGateRegistry(new StubServiceProvider(), new PolicyGateRegistryOptions { StopOnFirstFailure = true });
registry.Register<FailingGate>("fail");
registry.Register<PassingGate>("pass");
var mergeResult = CreateMergeResult();
var context = new PolicyGateContext();
var evaluation = await registry.EvaluateAsync(mergeResult, context);
evaluation.Results.Should().HaveCount(1);
evaluation.Results[0].GateName.Should().Be("fail");
evaluation.AllPassed.Should().BeFalse();
}
[Fact]
public async Task Registry_CollectsAllWhenConfigured()
{
var registry = new PolicyGateRegistry(new StubServiceProvider(), new PolicyGateRegistryOptions { StopOnFirstFailure = false });
registry.Register<FailingGate>("fail");
registry.Register<PassingGate>("pass");
var mergeResult = CreateMergeResult();
var context = new PolicyGateContext();
var evaluation = await registry.EvaluateAsync(mergeResult, context);
evaluation.Results.Should().HaveCount(2);
evaluation.Results.Select(r => r.GateName).Should().ContainInOrder("fail", "pass");
}
private static MergeResult CreateMergeResult()
{
var winner = new ScoredClaim
{
SourceId = "source",
Status = VexStatus.NotAffected,
OriginalScore = 0.9,
AdjustedScore = 0.9,
ScopeSpecificity = 1,
Accepted = true,
Reason = "winner",
};
return new MergeResult
{
Status = VexStatus.NotAffected,
Confidence = 0.9,
HasConflicts = false,
RequiresReplayProof = false,
WinningClaim = winner,
AllClaims = ImmutableArray.Create(winner),
Conflicts = ImmutableArray<ConflictRecord>.Empty,
};
}
private sealed class StubServiceProvider : IServiceProvider
{
public object? GetService(Type serviceType) => null;
}
private sealed class FailingGate : IPolicyGate
{
public Task<GateResult> EvaluateAsync(MergeResult mergeResult, PolicyGateContext context, CancellationToken ct = default)
=> Task.FromResult(new GateResult
{
GateName = nameof(FailingGate),
Passed = false,
Reason = "fail",
Details = ImmutableDictionary<string, object>.Empty,
});
}
private sealed class PassingGate : IPolicyGate
{
public Task<GateResult> EvaluateAsync(MergeResult mergeResult, PolicyGateContext context, CancellationToken ct = default)
=> Task.FromResult(new GateResult
{
GateName = nameof(PassingGate),
Passed = true,
Reason = null,
Details = ImmutableDictionary<string, object>.Empty,
});
}
}

View File

@@ -0,0 +1,133 @@
using System.Collections.Immutable;
using FluentAssertions;
using StellaOps.Policy.Gates;
using StellaOps.Policy.TrustLattice;
using VexStatus = StellaOps.Policy.Confidence.Models.VexStatus;
using Xunit;
namespace StellaOps.Policy.Tests.TrustLattice;
public sealed class PolicyGatesTests
{
[Fact]
public async Task MinimumConfidenceGate_FailsBelowThreshold()
{
var gate = new MinimumConfidenceGate();
var mergeResult = CreateMergeResult(VexStatus.NotAffected, 0.7);
var context = new PolicyGateContext { Environment = "production" };
var result = await gate.EvaluateAsync(mergeResult, context);
result.Passed.Should().BeFalse();
result.Reason.Should().Be("confidence_below_threshold");
}
[Fact]
public async Task UnknownsBudgetGate_FailsWhenBudgetExceeded()
{
var gate = new UnknownsBudgetGate(new UnknownsBudgetGateOptions { MaxUnknownCount = 1, MaxCumulativeUncertainty = 0.5 });
var mergeResult = CreateMergeResult(VexStatus.NotAffected, 0.9);
var context = new PolicyGateContext
{
UnknownCount = 2,
UnknownClaimScores = new[] { 0.4, 0.3 }
};
var result = await gate.EvaluateAsync(mergeResult, context);
result.Passed.Should().BeFalse();
result.Reason.Should().Be("unknowns_budget_exceeded");
}
[Fact]
public async Task SourceQuotaGate_FailsWithoutCorroboration()
{
var gate = new SourceQuotaGate(new SourceQuotaGateOptions { MaxInfluencePercent = 60, CorroborationDelta = 0.10 });
var mergeResult = new MergeResult
{
Status = VexStatus.NotAffected,
Confidence = 0.8,
HasConflicts = false,
RequiresReplayProof = false,
WinningClaim = new ScoredClaim
{
SourceId = "source-a",
Status = VexStatus.NotAffected,
OriginalScore = 0.9,
AdjustedScore = 0.9,
ScopeSpecificity = 1,
Accepted = true,
Reason = "winner",
},
AllClaims = ImmutableArray.Create(
new ScoredClaim
{
SourceId = "source-a",
Status = VexStatus.NotAffected,
OriginalScore = 0.9,
AdjustedScore = 0.9,
ScopeSpecificity = 1,
Accepted = true,
Reason = "winner",
},
new ScoredClaim
{
SourceId = "source-b",
Status = VexStatus.NotAffected,
OriginalScore = 0.1,
AdjustedScore = 0.1,
ScopeSpecificity = 1,
Accepted = false,
Reason = "initial",
}),
Conflicts = ImmutableArray<ConflictRecord>.Empty,
};
var result = await gate.EvaluateAsync(mergeResult, new PolicyGateContext());
result.Passed.Should().BeFalse();
result.Reason.Should().Be("source_quota_exceeded");
}
[Fact]
public async Task ReachabilityRequirementGate_FailsWithoutProof()
{
var gate = new ReachabilityRequirementGate();
var mergeResult = CreateMergeResult(VexStatus.NotAffected, 0.9);
var context = new PolicyGateContext
{
Severity = "CRITICAL",
HasReachabilityProof = false,
};
var result = await gate.EvaluateAsync(mergeResult, context);
result.Passed.Should().BeFalse();
result.Reason.Should().Be("reachability_proof_missing");
}
private static MergeResult CreateMergeResult(VexStatus status, double confidence)
{
var winner = new ScoredClaim
{
SourceId = "source-a",
Status = status,
OriginalScore = confidence,
AdjustedScore = confidence,
ScopeSpecificity = 1,
Accepted = true,
Reason = "winner",
};
return new MergeResult
{
Status = status,
Confidence = confidence,
HasConflicts = false,
RequiresReplayProof = false,
WinningClaim = winner,
AllClaims = ImmutableArray.Create(winner),
Conflicts = ImmutableArray<ConflictRecord>.Empty,
};
}
}