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
- 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.
149 lines
5.7 KiB
C#
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; }
|
|
}
|