Files
git.stella-ops.org/src/Policy/StellaOps.Policy.Registry/Testing/PolicyRegistryTestHarness.cs
StellaOps Bot 0de92144d2
Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Findings Ledger CI / build-test (push) Has been cancelled
Findings Ledger CI / migration-validation (push) Has been cancelled
Findings Ledger CI / generate-manifest (push) Has been cancelled
mock-dev-release / package-mock-release (push) Has been cancelled
feat(api): Implement Console Export Client and Models
- Added ConsoleExportClient for managing export requests and responses.
- Introduced ConsoleExportRequest and ConsoleExportResponse models.
- Implemented methods for creating and retrieving exports with appropriate headers.

feat(crypto): Add Software SM2/SM3 Cryptography Provider

- Implemented SmSoftCryptoProvider for software-only SM2/SM3 cryptography.
- Added support for signing and verification using SM2 algorithm.
- Included hashing functionality with SM3 algorithm.
- Configured options for loading keys from files and environment gate checks.

test(crypto): Add unit tests for SmSoftCryptoProvider

- Created comprehensive tests for signing, verifying, and hashing functionalities.
- Ensured correct behavior for key management and error handling.

feat(api): Enhance Console Export Models

- Expanded ConsoleExport models to include detailed status and event types.
- Added support for various export formats and notification options.

test(time): Implement TimeAnchorPolicyService tests

- Developed tests for TimeAnchorPolicyService to validate time anchors.
- Covered scenarios for anchor validation, drift calculation, and policy enforcement.
2025-12-07 00:27:33 +02:00

149 lines
5.7 KiB
C#

using Microsoft.Extensions.DependencyInjection;
using StellaOps.Policy.Registry.Contracts;
using StellaOps.Policy.Registry.Services;
using StellaOps.Policy.Registry.Storage;
namespace StellaOps.Policy.Registry.Testing;
/// <summary>
/// Test harness for Policy Registry integration testing.
/// Implements REGISTRY-API-27-010: Test suites + fixtures.
/// </summary>
public sealed class PolicyRegistryTestHarness : IDisposable
{
private readonly ServiceProvider _serviceProvider;
private readonly TimeProvider _timeProvider;
public IPolicyPackStore PackStore { get; }
public IVerificationPolicyStore VerificationPolicyStore { get; }
public ISnapshotStore SnapshotStore { get; }
public IViolationStore ViolationStore { get; }
public IOverrideStore OverrideStore { get; }
public IPolicyPackCompiler Compiler { get; }
public IPolicySimulationService SimulationService { get; }
public IBatchSimulationOrchestrator BatchOrchestrator { get; }
public IReviewWorkflowService ReviewService { get; }
public IPublishPipelineService PublishService { get; }
public IPromotionService PromotionService { get; }
public PolicyRegistryTestHarness(TimeProvider? timeProvider = null)
{
_timeProvider = timeProvider ?? TimeProvider.System;
var services = new ServiceCollection();
services.AddSingleton(_timeProvider);
services.AddPolicyRegistryInMemoryStorage();
_serviceProvider = services.BuildServiceProvider();
PackStore = _serviceProvider.GetRequiredService<IPolicyPackStore>();
VerificationPolicyStore = _serviceProvider.GetRequiredService<IVerificationPolicyStore>();
SnapshotStore = _serviceProvider.GetRequiredService<ISnapshotStore>();
ViolationStore = _serviceProvider.GetRequiredService<IViolationStore>();
OverrideStore = _serviceProvider.GetRequiredService<IOverrideStore>();
Compiler = _serviceProvider.GetRequiredService<IPolicyPackCompiler>();
SimulationService = _serviceProvider.GetRequiredService<IPolicySimulationService>();
BatchOrchestrator = _serviceProvider.GetRequiredService<IBatchSimulationOrchestrator>();
ReviewService = _serviceProvider.GetRequiredService<IReviewWorkflowService>();
PublishService = _serviceProvider.GetRequiredService<IPublishPipelineService>();
PromotionService = _serviceProvider.GetRequiredService<IPromotionService>();
}
/// <summary>
/// Creates a test tenant ID.
/// </summary>
public static Guid CreateTestTenantId() => Guid.NewGuid();
/// <summary>
/// Creates a policy pack with test data.
/// </summary>
public async Task<PolicyPackEntity> CreateTestPackAsync(
Guid tenantId,
string? name = null,
string? version = null,
IReadOnlyList<PolicyRule>? rules = null,
CancellationToken cancellationToken = default)
{
var request = new CreatePolicyPackRequest
{
Name = name ?? $"test-pack-{Guid.NewGuid():N}",
Version = version ?? "1.0.0",
Description = "Test policy pack",
Rules = rules ?? PolicyRegistryTestFixtures.CreateBasicRules()
};
return await PackStore.CreateAsync(tenantId, request, "test-user", cancellationToken);
}
/// <summary>
/// Creates and publishes a policy pack through the full workflow.
/// </summary>
public async Task<PublishResult> CreateAndPublishPackAsync(
Guid tenantId,
string? name = null,
CancellationToken cancellationToken = default)
{
// Create pack
var pack = await CreateTestPackAsync(tenantId, name, cancellationToken: cancellationToken);
// Submit for review
var review = await ReviewService.SubmitForReviewAsync(tenantId, pack.PackId,
new SubmitReviewRequest { Description = "Test review" }, cancellationToken);
// Approve review
await ReviewService.ApproveAsync(tenantId, review.ReviewId,
new ApproveReviewRequest { ApprovedBy = "test-approver" }, cancellationToken);
// Publish
return await PublishService.PublishAsync(tenantId, pack.PackId,
new PublishPackRequest { PublishedBy = "test-publisher" }, cancellationToken);
}
/// <summary>
/// Runs a determinism test to verify consistent outputs.
/// </summary>
public async Task<DeterminismTestResult> RunDeterminismTestAsync(
Guid tenantId,
int iterations = 3,
CancellationToken cancellationToken = default)
{
var results = new List<string>();
var pack = await CreateTestPackAsync(tenantId, cancellationToken: cancellationToken);
for (int i = 0; i < iterations; i++)
{
var compilationResult = await Compiler.CompileAsync(tenantId, pack.PackId, cancellationToken);
if (compilationResult.Success && compilationResult.Digest is not null)
{
results.Add(compilationResult.Digest);
}
}
var allSame = results.Distinct().Count() == 1;
return new DeterminismTestResult
{
Passed = allSame && results.Count == iterations,
Iterations = iterations,
UniqueResults = results.Distinct().Count(),
Digests = results
};
}
public void Dispose()
{
(_serviceProvider as IDisposable)?.Dispose();
}
}
/// <summary>
/// Result of a determinism test.
/// </summary>
public sealed record DeterminismTestResult
{
public required bool Passed { get; init; }
public required int Iterations { get; init; }
public required int UniqueResults { get; init; }
public required IReadOnlyList<string> Digests { get; init; }
}