up
This commit is contained in:
@@ -5,6 +5,7 @@ using StellaOps.Policy.Engine.Caching;
|
||||
using StellaOps.Policy.Engine.Compilation;
|
||||
using StellaOps.Policy.Engine.Domain;
|
||||
using StellaOps.Policy.Engine.Evaluation;
|
||||
using StellaOps.Policy.Engine.ReachabilityFacts;
|
||||
using StellaOps.Policy.Engine.Options;
|
||||
using StellaOps.Policy.Engine.Services;
|
||||
using StellaOps.PolicyDsl;
|
||||
@@ -180,6 +181,55 @@ public sealed class PolicyRuntimeEvaluationServiceTests
|
||||
Assert.NotEqual(response1.CorrelationId, response2.CorrelationId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EvaluateAsync_EnrichesReachabilityFromFacts()
|
||||
{
|
||||
const string policy = """
|
||||
policy "Reachability policy" syntax "stella-dsl@1" {
|
||||
rule reachable_then_warn priority 5 {
|
||||
when reachability.state == "reachable"
|
||||
then status := "warn"
|
||||
because "reachable path detected"
|
||||
}
|
||||
|
||||
rule default priority 100 {
|
||||
when true
|
||||
then status := "affected"
|
||||
because "default"
|
||||
}
|
||||
}
|
||||
""";
|
||||
|
||||
var harness = CreateHarness();
|
||||
await harness.StoreTestPolicyAsync("pack-2", 1, policy);
|
||||
|
||||
var fact = new ReachabilityFact
|
||||
{
|
||||
Id = "fact-1",
|
||||
TenantId = "tenant-1",
|
||||
ComponentPurl = "pkg:npm/lodash@4.17.21",
|
||||
AdvisoryId = "CVE-2024-0001",
|
||||
State = ReachabilityState.Reachable,
|
||||
Confidence = 0.92m,
|
||||
Score = 0.85m,
|
||||
HasRuntimeEvidence = true,
|
||||
Source = "graph-analyzer",
|
||||
Method = AnalysisMethod.Hybrid,
|
||||
EvidenceRef = "evidence/callgraph.json",
|
||||
ComputedAt = new DateTimeOffset(2025, 1, 1, 0, 0, 0, TimeSpan.Zero),
|
||||
ExpiresAt = null,
|
||||
Metadata = new Dictionary<string, object?>()
|
||||
};
|
||||
|
||||
await harness.ReachabilityStore.SaveAsync(fact, CancellationToken.None);
|
||||
|
||||
var request = CreateRequest("pack-2", 1, severity: "Low");
|
||||
|
||||
var response = await harness.Service.EvaluateAsync(request, CancellationToken.None);
|
||||
|
||||
Assert.Equal("warn", response.Status);
|
||||
}
|
||||
|
||||
private static RuntimeEvaluationRequest CreateRequest(
|
||||
string packId,
|
||||
int version,
|
||||
@@ -213,16 +263,28 @@ public sealed class PolicyRuntimeEvaluationServiceTests
|
||||
var cache = new InMemoryPolicyEvaluationCache(cacheLogger, TimeProvider.System, options);
|
||||
var evaluator = new PolicyEvaluator();
|
||||
|
||||
var reachabilityStore = new InMemoryReachabilityFactsStore(TimeProvider.System);
|
||||
var reachabilityCache = new InMemoryReachabilityFactsOverlayCache(
|
||||
NullLogger<InMemoryReachabilityFactsOverlayCache>.Instance,
|
||||
TimeProvider.System,
|
||||
Microsoft.Extensions.Options.Options.Create(new PolicyEngineOptions()));
|
||||
var reachabilityService = new ReachabilityFactsJoiningService(
|
||||
reachabilityStore,
|
||||
reachabilityCache,
|
||||
NullLogger<ReachabilityFactsJoiningService>.Instance,
|
||||
TimeProvider.System);
|
||||
|
||||
var compilationService = CreateCompilationService();
|
||||
|
||||
var service = new PolicyRuntimeEvaluationService(
|
||||
repository,
|
||||
cache,
|
||||
evaluator,
|
||||
reachabilityService,
|
||||
TimeProvider.System,
|
||||
serviceLogger);
|
||||
|
||||
return new TestHarness(service, repository, compilationService);
|
||||
return new TestHarness(service, repository, compilationService, reachabilityStore);
|
||||
}
|
||||
|
||||
private static PolicyCompilationService CreateCompilationService()
|
||||
@@ -238,7 +300,8 @@ public sealed class PolicyRuntimeEvaluationServiceTests
|
||||
private sealed record TestHarness(
|
||||
PolicyRuntimeEvaluationService Service,
|
||||
InMemoryPolicyPackRepository Repository,
|
||||
PolicyCompilationService CompilationService)
|
||||
PolicyCompilationService CompilationService,
|
||||
InMemoryReachabilityFactsStore ReachabilityStore)
|
||||
{
|
||||
public async Task StoreTestPolicyAsync(string packId, int version, string dsl)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user