Add receipt input JSON and SHA256 hash for CVSS policy scoring tests

- Introduced a new JSON fixture `receipt-input.json` containing base, environmental, and threat metrics for CVSS scoring.
- Added corresponding SHA256 hash file `receipt-input.sha256` to ensure integrity of the JSON fixture.
This commit is contained in:
StellaOps Bot
2025-12-04 07:30:42 +02:00
parent 2d079d61ed
commit e1262eb916
91 changed files with 19493 additions and 187 deletions

View File

@@ -24,11 +24,15 @@ public sealed class EvaluationRunRepository : RepositoryBase<PolicyDataSource>,
const string sql = """
INSERT INTO policy.evaluation_runs (
id, tenant_id, project_id, artifact_id, pack_id, pack_version,
risk_profile_id, status, input_hash, metadata, created_by
risk_profile_id, status, result, score,
findings_count, critical_count, high_count, medium_count, low_count,
input_hash, metadata, duration_ms, error_message, created_by
)
VALUES (
@id, @tenant_id, @project_id, @artifact_id, @pack_id, @pack_version,
@risk_profile_id, @status, @input_hash, @metadata::jsonb, @created_by
@risk_profile_id, @status, @result, @score,
@findings_count, @critical_count, @high_count, @medium_count, @low_count,
@input_hash, @metadata::jsonb, @duration_ms, @error_message, @created_by
)
RETURNING *
""";
@@ -45,8 +49,17 @@ public sealed class EvaluationRunRepository : RepositoryBase<PolicyDataSource>,
AddParameter(command, "pack_version", run.PackVersion);
AddParameter(command, "risk_profile_id", run.RiskProfileId);
AddParameter(command, "status", StatusToString(run.Status));
AddParameter(command, "result", run.Result.HasValue ? ResultToString(run.Result.Value) : null);
AddParameter(command, "score", run.Score);
AddParameter(command, "findings_count", run.FindingsCount);
AddParameter(command, "critical_count", run.CriticalCount);
AddParameter(command, "high_count", run.HighCount);
AddParameter(command, "medium_count", run.MediumCount);
AddParameter(command, "low_count", run.LowCount);
AddParameter(command, "input_hash", run.InputHash);
AddJsonbParameter(command, "metadata", run.Metadata);
AddParameter(command, "duration_ms", run.DurationMs);
AddParameter(command, "error_message", run.ErrorMessage);
AddParameter(command, "created_by", run.CreatedBy);
await using var reader = await command.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false);

View File

@@ -12,7 +12,11 @@ public sealed class EvaluationRunRepositoryTests : IAsyncLifetime
{
private readonly PolicyPostgresFixture _fixture;
private readonly EvaluationRunRepository _repository;
private readonly PackRepository _packRepository;
private readonly PackVersionRepository _packVersionRepository;
private readonly string _tenantId = Guid.NewGuid().ToString();
private readonly Guid _packId = Guid.NewGuid();
private const int SeedPackVersion = 1;
public EvaluationRunRepositoryTests(PolicyPostgresFixture fixture)
{
@@ -21,10 +25,41 @@ public sealed class EvaluationRunRepositoryTests : IAsyncLifetime
var options = fixture.Fixture.CreateOptions();
options.SchemaName = fixture.SchemaName;
var dataSource = new PolicyDataSource(Options.Create(options), NullLogger<PolicyDataSource>.Instance);
_packRepository = new PackRepository(dataSource, NullLogger<PackRepository>.Instance);
_packVersionRepository = new PackVersionRepository(dataSource, NullLogger<PackVersionRepository>.Instance);
_repository = new EvaluationRunRepository(dataSource, NullLogger<EvaluationRunRepository>.Instance);
}
public Task InitializeAsync() => _fixture.TruncateAllTablesAsync();
public async Task InitializeAsync()
{
await _fixture.TruncateAllTablesAsync();
var pack = new PackEntity
{
Id = _packId,
TenantId = _tenantId,
Name = "eval-pack",
DisplayName = "Evaluation Pack",
ActiveVersion = SeedPackVersion,
CreatedAt = DateTimeOffset.UtcNow,
UpdatedAt = DateTimeOffset.UtcNow,
CreatedBy = "tests"
};
await _packRepository.CreateAsync(pack);
var packVersion = new PackVersionEntity
{
Id = Guid.NewGuid(),
PackId = _packId,
Version = SeedPackVersion,
RulesHash = "seed-hash",
IsPublished = true,
PublishedAt = DateTimeOffset.UtcNow,
PublishedBy = "tests",
CreatedBy = "tests"
};
await _packVersionRepository.CreateAsync(packVersion);
}
public Task DisposeAsync() => Task.CompletedTask;
[Fact]
@@ -37,8 +72,8 @@ public sealed class EvaluationRunRepositoryTests : IAsyncLifetime
TenantId = _tenantId,
ProjectId = "project-123",
ArtifactId = "registry.example.com/app:v1.0",
PackId = Guid.NewGuid(),
PackVersion = 1,
PackId = _packId,
PackVersion = SeedPackVersion,
Status = EvaluationStatus.Pending
};
@@ -204,6 +239,8 @@ public sealed class EvaluationRunRepositoryTests : IAsyncLifetime
{
Id = Guid.NewGuid(),
TenantId = _tenantId,
PackId = _packId,
PackVersion = SeedPackVersion,
Status = EvaluationStatus.Completed,
Result = EvaluationResult.Pass,
Score = 100,
@@ -215,6 +252,8 @@ public sealed class EvaluationRunRepositoryTests : IAsyncLifetime
{
Id = Guid.NewGuid(),
TenantId = _tenantId,
PackId = _packId,
PackVersion = SeedPackVersion,
Status = EvaluationStatus.Completed,
Result = EvaluationResult.Fail,
Score = 50,
@@ -245,6 +284,8 @@ public sealed class EvaluationRunRepositoryTests : IAsyncLifetime
Id = Guid.NewGuid(),
TenantId = _tenantId,
ProjectId = projectId,
PackId = _packId,
PackVersion = SeedPackVersion,
Status = EvaluationStatus.Pending
};
}

View File

@@ -170,6 +170,8 @@ public sealed class PolicyAuditRepositoryTests : IAsyncLifetime
public async Task DeleteOld_RemovesOldAudits()
{
// Arrange
// Clear any cross-test residue defensively.
await _repository.DeleteOldAsync(DateTimeOffset.MaxValue);
await _repository.CreateAsync(CreateAudit("old-action"));
// Act - Delete audits older than future date

View File

@@ -12,7 +12,11 @@ public sealed class RuleRepositoryTests : IAsyncLifetime
{
private readonly PolicyPostgresFixture _fixture;
private readonly RuleRepository _repository;
private readonly PackRepository _packRepository;
private readonly PackVersionRepository _packVersionRepository;
private readonly Guid _packId = Guid.NewGuid();
private readonly Guid _packVersionId = Guid.NewGuid();
private readonly string _tenantId = Guid.NewGuid().ToString();
public RuleRepositoryTests(PolicyPostgresFixture fixture)
{
@@ -21,10 +25,46 @@ public sealed class RuleRepositoryTests : IAsyncLifetime
var options = fixture.Fixture.CreateOptions();
options.SchemaName = fixture.SchemaName;
var dataSource = new PolicyDataSource(Options.Create(options), NullLogger<PolicyDataSource>.Instance);
_packRepository = new PackRepository(dataSource, NullLogger<PackRepository>.Instance);
_packVersionRepository = new PackVersionRepository(dataSource, NullLogger<PackVersionRepository>.Instance);
_repository = new RuleRepository(dataSource, NullLogger<RuleRepository>.Instance);
}
public Task InitializeAsync() => _fixture.TruncateAllTablesAsync();
public async Task InitializeAsync()
{
await _fixture.TruncateAllTablesAsync();
var pack = new PackEntity
{
Id = _packId,
TenantId = _tenantId,
Name = "test-pack",
DisplayName = "Test Pack",
Description = "Seed pack for rule tests",
ActiveVersion = 1,
CreatedAt = DateTimeOffset.UtcNow,
UpdatedAt = DateTimeOffset.UtcNow,
CreatedBy = "tests"
};
await _packRepository.CreateAsync(pack);
var packVersion = new PackVersionEntity
{
Id = _packVersionId,
PackId = _packId,
Version = 1,
Description = "seed version",
RulesHash = "hash",
IsPublished = true,
PublishedAt = DateTimeOffset.UtcNow,
PublishedBy = "tests",
CreatedBy = "tests"
};
await _packVersionRepository.CreateAsync(packVersion);
}
public Task DisposeAsync() => Task.CompletedTask;
[Fact]