Files
git.stella-ops.org/src/StellaOps.Policy.Tests/PolicyEvaluationTests.cs
master 14617e9c3b feat: Implement Scheduler Worker Options and Planner Loop
- Added `SchedulerWorkerOptions` class to encapsulate configuration for the scheduler worker.
- Introduced `PlannerBackgroundService` to manage the planner loop, fetching and processing planning runs.
- Created `PlannerExecutionService` to handle the execution logic for planning runs, including impact targeting and run persistence.
- Developed `PlannerExecutionResult` and `PlannerExecutionStatus` to standardize execution outcomes.
- Implemented validation logic within `SchedulerWorkerOptions` to ensure proper configuration.
- Added documentation for the planner loop and impact targeting features.
- Established health check endpoints and authentication mechanisms for the Signals service.
- Created unit tests for the Signals API to ensure proper functionality and response handling.
- Configured options for authority integration and fallback authentication methods.
2025-10-27 09:46:31 +02:00

137 lines
5.2 KiB
C#

using System.Collections.Immutable;
using Xunit;
namespace StellaOps.Policy.Tests;
public sealed class PolicyEvaluationTests
{
[Fact]
public void EvaluateFinding_AppliesTrustAndReachabilityWeights()
{
var action = new PolicyAction(PolicyActionType.Block, null, null, null, false);
var rule = PolicyRule.Create(
"BlockMedium",
action,
ImmutableArray.Create(PolicySeverity.Medium),
ImmutableArray<string>.Empty,
ImmutableArray<string>.Empty,
ImmutableArray<string>.Empty,
ImmutableArray<string>.Empty,
ImmutableArray<string>.Empty,
PolicyRuleMatchCriteria.Empty,
expires: null,
justification: null);
var document = new PolicyDocument(
PolicySchema.CurrentVersion,
ImmutableArray.Create(rule),
ImmutableDictionary<string, string>.Empty,
PolicyExceptionConfiguration.Empty);
var config = PolicyScoringConfig.Default;
var finding = PolicyFinding.Create(
"finding-medium",
PolicySeverity.Medium,
source: "community",
tags: ImmutableArray.Create("reachability:indirect"));
var verdict = PolicyEvaluation.EvaluateFinding(document, config, finding);
Assert.Equal(PolicyVerdictStatus.Blocked, verdict.Status);
Assert.Equal(19.5, verdict.Score, 3);
var inputs = verdict.GetInputs();
Assert.Equal(50, inputs["severityWeight"]);
Assert.Equal(0.65, inputs["trustWeight"], 3);
Assert.Equal(0.6, inputs["reachabilityWeight"], 3);
Assert.Equal(19.5, inputs["baseScore"], 3);
}
[Fact]
public void EvaluateFinding_QuietWithRequireVexAppliesQuietPenalty()
{
var ignoreOptions = new PolicyIgnoreOptions(null, null);
var requireVexOptions = new PolicyRequireVexOptions(
ImmutableArray<string>.Empty,
ImmutableArray<string>.Empty);
var action = new PolicyAction(PolicyActionType.Ignore, ignoreOptions, null, requireVexOptions, true);
var rule = PolicyRule.Create(
"QuietIgnore",
action,
ImmutableArray.Create(PolicySeverity.Critical),
ImmutableArray<string>.Empty,
ImmutableArray<string>.Empty,
ImmutableArray<string>.Empty,
ImmutableArray<string>.Empty,
ImmutableArray<string>.Empty,
PolicyRuleMatchCriteria.Empty,
expires: null,
justification: null);
var document = new PolicyDocument(
PolicySchema.CurrentVersion,
ImmutableArray.Create(rule),
ImmutableDictionary<string, string>.Empty,
PolicyExceptionConfiguration.Empty);
var config = PolicyScoringConfig.Default;
var finding = PolicyFinding.Create(
"finding-critical",
PolicySeverity.Critical,
tags: ImmutableArray.Create("reachability:entrypoint"));
var verdict = PolicyEvaluation.EvaluateFinding(document, config, finding);
Assert.Equal(PolicyVerdictStatus.Ignored, verdict.Status);
Assert.True(verdict.Quiet);
Assert.Equal("QuietIgnore", verdict.QuietedBy);
Assert.Equal(10, verdict.Score, 3);
var inputs = verdict.GetInputs();
Assert.Equal(90, inputs["baseScore"], 3);
Assert.Equal(config.IgnorePenalty, inputs["ignorePenalty"]);
Assert.Equal(config.QuietPenalty, inputs["quietPenalty"]);
}
[Fact]
public void EvaluateFinding_UnknownSeverityComputesConfidence()
{
var action = new PolicyAction(PolicyActionType.Block, null, null, null, false);
var rule = PolicyRule.Create(
"BlockUnknown",
action,
ImmutableArray.Create(PolicySeverity.Unknown),
ImmutableArray<string>.Empty,
ImmutableArray<string>.Empty,
ImmutableArray<string>.Empty,
ImmutableArray<string>.Empty,
ImmutableArray<string>.Empty,
PolicyRuleMatchCriteria.Empty,
expires: null,
justification: null);
var document = new PolicyDocument(
PolicySchema.CurrentVersion,
ImmutableArray.Create(rule),
ImmutableDictionary<string, string>.Empty,
PolicyExceptionConfiguration.Empty);
var config = PolicyScoringConfig.Default;
var finding = PolicyFinding.Create(
"finding-unknown",
PolicySeverity.Unknown,
tags: ImmutableArray.Create("reachability:unknown", "unknown-age-days:5"));
var verdict = PolicyEvaluation.EvaluateFinding(document, config, finding);
Assert.Equal(PolicyVerdictStatus.Blocked, verdict.Status);
Assert.Equal(30, verdict.Score, 3); // 60 * 1 * 0.5
Assert.Equal(0.55, verdict.UnknownConfidence ?? 0, 3);
Assert.Equal("medium", verdict.ConfidenceBand);
Assert.Equal(5, verdict.UnknownAgeDays ?? 0, 3);
var inputs = verdict.GetInputs();
Assert.Equal(0.55, inputs["unknownConfidence"], 3);
Assert.Equal(5, inputs["unknownAgeDays"], 3);
}
}