Files
git.stella-ops.org/src/StellaOps.Policy.Tests/PolicyBinderTests.cs
master 730354a1af
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
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

158 lines
4.6 KiB
C#

using System;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
namespace StellaOps.Policy.Tests;
public sealed class PolicyBinderTests
{
[Fact]
public void Bind_ValidYaml_ReturnsSuccess()
{
const string yaml = """
version: "1.0"
rules:
- name: Block Critical
severity: [Critical]
sources: [NVD]
action: block
""";
var result = PolicyBinder.Bind(yaml, PolicyDocumentFormat.Yaml);
Assert.True(result.Success);
Assert.Equal("1.0", result.Document.Version);
Assert.Single(result.Document.Rules);
Assert.Empty(result.Issues);
}
[Fact]
public void Bind_ExceptionsConfigured_ParsesDefinitions()
{
const string yaml = """
version: "1.0"
exceptions:
effects:
- id: suppress-temp
name: Temporary Suppress
effect: suppress
routingTemplate: secops
maxDurationDays: 30
- id: downgrade-ops
name: Downgrade To Low
effect: downgrade
downgradeSeverity: Low
routingTemplates:
- id: secops
authorityRouteId: route-secops
requireMfa: true
rules:
- name: Allow
action: ignore
""";
var result = PolicyBinder.Bind(yaml, PolicyDocumentFormat.Yaml);
Assert.True(result.Success);
var effects = result.Document.Exceptions.Effects;
Assert.Equal(2, effects.Length);
var suppress = effects.Single(effect => effect.Id == "suppress-temp");
Assert.Equal(PolicyExceptionEffectType.Suppress, suppress.Effect);
Assert.Equal("Temporary Suppress", suppress.Name);
Assert.Equal("secops", suppress.RoutingTemplate);
Assert.Equal(30, suppress.MaxDurationDays);
var downgrade = effects.Single(effect => effect.Id == "downgrade-ops");
Assert.Equal(PolicyExceptionEffectType.Downgrade, downgrade.Effect);
Assert.Equal("Downgrade To Low", downgrade.Name);
Assert.Equal(PolicySeverity.Low, downgrade.DowngradeSeverity);
var routing = result.Document.Exceptions.RoutingTemplates;
Assert.Single(routing);
Assert.Equal("secops", routing[0].Id);
Assert.Equal("route-secops", routing[0].AuthorityRouteId);
Assert.True(routing[0].RequireMfa);
}
[Fact]
public void Bind_ExceptionDowngradeMissingSeverity_ReturnsError()
{
const string yaml = """
version: "1.0"
exceptions:
effects:
- id: downgrade-invalid
effect: downgrade
routingTemplates: []
rules:
- name: Allow
action: ignore
""";
var result = PolicyBinder.Bind(yaml, PolicyDocumentFormat.Yaml);
Assert.False(result.Success);
Assert.Contains(result.Issues, issue => issue.Code == "policy.exceptions.effect.downgrade.missingSeverity");
}
[Fact]
public void Bind_InvalidSeverity_ReturnsError()
{
const string yaml = """
version: "1.0"
rules:
- name: Invalid Severity
severity: [Nope]
action: block
""";
var result = PolicyBinder.Bind(yaml, PolicyDocumentFormat.Yaml);
Assert.False(result.Success);
Assert.Contains(result.Issues, issue => issue.Code == "policy.severity.invalid");
}
[Fact]
public async Task Cli_StrictMode_FailsOnWarnings()
{
const string yaml = """
version: "1.0"
rules:
- name: Quiet Warning
sources: ["", "NVD"]
action: ignore
""";
var path = Path.Combine(Path.GetTempPath(), $"policy-{Guid.NewGuid():N}.yaml");
await File.WriteAllTextAsync(path, yaml);
try
{
using var output = new StringWriter();
using var error = new StringWriter();
var cli = new PolicyValidationCli(output, error);
var options = new PolicyValidationCliOptions
{
Inputs = new[] { path },
Strict = true,
};
var exitCode = await cli.RunAsync(options, CancellationToken.None);
Assert.Equal(2, exitCode);
Assert.Contains("WARNING", output.ToString());
}
finally
{
if (File.Exists(path))
{
File.Delete(path);
}
}
}
}