up
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using FluentAssertions;
|
||||
using StellaOps.Policy;
|
||||
using Xunit;
|
||||
|
||||
@@ -42,10 +41,10 @@ public class PolicyValidationCliTests
|
||||
|
||||
var exit = await cli.RunAsync(options);
|
||||
|
||||
exit.Should().Be(0);
|
||||
Assert.Equal(0, exit);
|
||||
var text = output.ToString();
|
||||
text.Should().Contain("OK");
|
||||
text.Should().Contain("canonical.spl.digest:");
|
||||
Assert.Contains("OK", text, StringComparison.Ordinal);
|
||||
Assert.Contains("canonical.spl.digest:", text, StringComparison.Ordinal);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Policy.Tests.Scoring;
|
||||
|
||||
public sealed class EvidenceFreshnessCalculatorTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData(0, 10000)]
|
||||
[InlineData(7, 10000)]
|
||||
[InlineData(8, 9000)]
|
||||
[InlineData(30, 9000)]
|
||||
[InlineData(31, 7500)]
|
||||
[InlineData(90, 7500)]
|
||||
[InlineData(91, 6000)]
|
||||
[InlineData(180, 6000)]
|
||||
[InlineData(181, 4000)]
|
||||
[InlineData(365, 4000)]
|
||||
[InlineData(366, 2000)]
|
||||
public void CalculateMultiplierBps_UsesExpectedBucketBoundaries(int ageDays, int expectedMultiplierBps)
|
||||
{
|
||||
var calculator = new StellaOps.Policy.Scoring.EvidenceFreshnessCalculator();
|
||||
var asOf = new DateTimeOffset(2025, 01, 01, 0, 0, 0, TimeSpan.Zero);
|
||||
var evidenceTimestamp = asOf.AddDays(-ageDays);
|
||||
|
||||
var multiplier = calculator.CalculateMultiplierBps(evidenceTimestamp, asOf);
|
||||
|
||||
Assert.Equal(expectedMultiplierBps, multiplier);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CalculateMultiplierBps_FutureTimestampReturnsMaxFreshness()
|
||||
{
|
||||
var calculator = new StellaOps.Policy.Scoring.EvidenceFreshnessCalculator();
|
||||
var asOf = new DateTimeOffset(2025, 01, 01, 0, 0, 0, TimeSpan.Zero);
|
||||
var evidenceTimestamp = asOf.AddDays(1);
|
||||
|
||||
var multiplier = calculator.CalculateMultiplierBps(evidenceTimestamp, asOf);
|
||||
|
||||
Assert.Equal(10000, multiplier);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ApplyFreshness_UsesBasisPointMath()
|
||||
{
|
||||
var calculator = new StellaOps.Policy.Scoring.EvidenceFreshnessCalculator();
|
||||
var asOf = new DateTimeOffset(2025, 01, 01, 0, 0, 0, TimeSpan.Zero);
|
||||
var evidenceTimestamp = asOf.AddDays(-30);
|
||||
|
||||
var adjusted = calculator.ApplyFreshness(100, evidenceTimestamp, asOf);
|
||||
|
||||
Assert.Equal(90, adjusted);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Policy.Tests.Scoring;
|
||||
|
||||
public sealed class ScoreExplainBuilderTests
|
||||
{
|
||||
[Fact]
|
||||
public void Build_SortsDeterministically()
|
||||
{
|
||||
var builder = new StellaOps.Policy.Scoring.ScoreExplainBuilder()
|
||||
.Add("provenance", 10, "p", digests: new[] { "sha256:b" })
|
||||
.Add("reachability", 90, "r", digests: new[] { "sha256:c" })
|
||||
.Add("evidence", 20, "e", digests: new[] { "sha256:a" })
|
||||
.Add("evidence", 21, "e2", digests: new[] { "sha256:0", "sha256:z" });
|
||||
|
||||
var explanations = builder.Build();
|
||||
|
||||
Assert.Collection(explanations,
|
||||
item => Assert.Equal("evidence", item.Factor),
|
||||
item => Assert.Equal("evidence", item.Factor),
|
||||
item => Assert.Equal("provenance", item.Factor),
|
||||
item => Assert.Equal("reachability", item.Factor));
|
||||
Assert.Equal("sha256:0", explanations[0].ContributingDigests?[0]);
|
||||
Assert.Equal("sha256:a", explanations[1].ContributingDigests?[0]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AddEvidence_ComputesAdjustedValueDeterministically()
|
||||
{
|
||||
var builder = new StellaOps.Policy.Scoring.ScoreExplainBuilder()
|
||||
.AddEvidence(points: 80, freshnessMultiplierBps: 7500, ageDays: 90);
|
||||
|
||||
var explanations = builder.Build();
|
||||
|
||||
Assert.Single(explanations);
|
||||
Assert.Equal("evidence", explanations[0].Factor);
|
||||
Assert.Equal(60, explanations[0].Value);
|
||||
Assert.Contains("90 days old", explanations[0].Reason);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user