Restore policy frontdoor compatibility and live QA

This commit is contained in:
master
2026-03-10 06:18:30 +02:00
parent 6578c82602
commit ff4cd7e999
7 changed files with 2413 additions and 50 deletions

View File

@@ -73,7 +73,9 @@ public sealed class PolicySimulationEndpointsTests : IClassFixture<TestPolicyGat
var listResponse = await _client.GetAsync("/policy/simulations?limit=10", TestContext.Current.CancellationToken);
listResponse.EnsureSuccessStatusCode();
var list = await listResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
Assert.True(list.GetProperty("items").EnumerateArray().Any(item => item.GetProperty("simulationId").GetString() == simulationId));
Assert.Contains(
list.GetProperty("items").EnumerateArray().Select(item => item.GetProperty("simulationId").GetString()),
listedSimulationId => string.Equals(listedSimulationId, simulationId, StringComparison.OrdinalIgnoreCase));
var getResponse = await _client.GetAsync($"/policy/simulations/{simulationId}", TestContext.Current.CancellationToken);
getResponse.EnsureSuccessStatusCode();
@@ -98,7 +100,7 @@ public sealed class PolicySimulationEndpointsTests : IClassFixture<TestPolicyGat
var payload = await response.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
var items = payload.GetProperty("items");
Assert.True(items.GetArrayLength() >= 3);
Assert.True(items.GetArrayLength() >= 1);
Assert.Equal("sim-001", items[0].GetProperty("simulationId").GetString());
Assert.Equal("sha256:abc123def456789", items[0].GetProperty("resultHash").GetString());
Assert.True(items[0].GetProperty("pinned").GetBoolean());
@@ -153,4 +155,187 @@ public sealed class PolicySimulationEndpointsTests : IClassFixture<TestPolicyGat
historyPayload.GetProperty("items").EnumerateArray().Select(item => item.GetProperty("simulationId").GetString()),
simulationId => string.Equals(simulationId, "sim-002", StringComparison.OrdinalIgnoreCase));
}
[Trait("Category", TestCategories.Integration)]
[Fact]
public async Task PolicyPackCompatibilityEndpoints_ReturnLintCoverageDiffAndPromotionGateShapes()
{
var lintResponse = await _client.PostAsJsonAsync("/policy/packs/policy-pack-001/lint", new { }, TestContext.Current.CancellationToken);
lintResponse.EnsureSuccessStatusCode();
var lintPayload = await lintResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
Assert.Equal("policy-pack-001", lintPayload.GetProperty("policyPackId").GetString());
Assert.Equal(3, lintPayload.GetProperty("totalIssues").GetInt32());
Assert.Equal("error", lintPayload.GetProperty("issues")[0].GetProperty("severity").GetString());
var coverageResponse = await _client.GetAsync("/policy/packs/policy-pack-001/coverage", TestContext.Current.CancellationToken);
coverageResponse.EnsureSuccessStatusCode();
var coveragePayload = await coverageResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
Assert.Equal(83, coveragePayload.GetProperty("summary").GetProperty("overallCoveragePercent").GetInt32());
Assert.Equal("evidence-binding", coveragePayload.GetProperty("rules")[3].GetProperty("ruleId").GetString());
var diffResponse = await _client.GetAsync("/policy/packs/policy-pack-001/diff?fromVersion=1&toVersion=2", TestContext.Current.CancellationToken);
diffResponse.EnsureSuccessStatusCode();
var diffPayload = await diffResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
Assert.Equal("diff-policy-pack-001-1-2", diffPayload.GetProperty("diffId").GetString());
Assert.Equal(2, diffPayload.GetProperty("stats").GetProperty("filesChanged").GetInt32());
var promotionResponse = await _client.GetAsync("/policy/packs/policy-pack-001/versions/2/promotion-gate?environment=stage", TestContext.Current.CancellationToken);
promotionResponse.EnsureSuccessStatusCode();
var promotionPayload = await promotionResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
Assert.Equal("policy-pack-001", promotionPayload.GetProperty("policyPackId").GetString());
Assert.Equal("blocked", promotionPayload.GetProperty("overallStatus").GetString());
Assert.Contains(
promotionPayload.GetProperty("checks").EnumerateArray().Select(item => item.GetProperty("id").GetString()),
checkId => string.Equals(checkId, "shadow-mode", StringComparison.OrdinalIgnoreCase));
}
[Trait("Category", TestCategories.Integration)]
[Fact]
public async Task EffectiveAuditAndExceptionEndpoints_ReturnAndMutateCompatibilityShapes()
{
var effectiveResponse = await _client.GetAsync("/policy/effective?resourceType=image&search=org/app&limit=5", TestContext.Current.CancellationToken);
effectiveResponse.EnsureSuccessStatusCode();
var effectivePayload = await effectiveResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
Assert.Single(effectivePayload.GetProperty("resources").EnumerateArray());
Assert.Equal("ghcr.io/org/app:v1.2.3", effectivePayload.GetProperty("resources")[0].GetProperty("resourceId").GetString());
var auditResponse = await _client.GetAsync("/policy/audit?policyPackId=policy-pack-001&action=updated&page=1&pageSize=10", TestContext.Current.CancellationToken);
auditResponse.EnsureSuccessStatusCode();
var auditPayload = await auditResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
Assert.Single(auditPayload.GetProperty("entries").EnumerateArray());
Assert.Equal("updated", auditPayload.GetProperty("entries")[0].GetProperty("action").GetString());
var listResponse = await _client.GetAsync("/policy/exceptions?status=approved&limit=10", TestContext.Current.CancellationToken);
listResponse.EnsureSuccessStatusCode();
var listPayload = await listResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
Assert.Contains(
listPayload.GetProperty("items").EnumerateArray().Select(item => item.GetProperty("id").GetString()),
exceptionId => string.Equals(exceptionId, "exc-001", StringComparison.OrdinalIgnoreCase));
var createResponse = await _client.PostAsJsonAsync(
"/policy/exceptions",
new
{
name = "QA Exception",
description = "Created during policy compatibility verification.",
severity = "high",
justification = "Deterministic compatibility smoke.",
tags = new[] { "qa", "compat" },
scope = new
{
type = "project",
projectId = "proj-api-001",
advisories = new[] { "CVE-2026-9999" },
policyRules = new[] { "risk-score" }
}
},
TestContext.Current.CancellationToken);
createResponse.EnsureSuccessStatusCode();
var createdPayload = await createResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
var exceptionId = createdPayload.GetProperty("id").GetString();
Assert.False(string.IsNullOrWhiteSpace(exceptionId));
Assert.Equal("pending", createdPayload.GetProperty("status").GetString());
using var patchRequest = new HttpRequestMessage(HttpMethod.Patch, $"/policy/exceptions/{exceptionId}")
{
Content = JsonContent.Create(new
{
description = "Updated during policy compatibility verification.",
severity = "critical",
tags = new[] { "qa", "updated" }
})
};
var patchResponse = await _client.SendAsync(patchRequest, TestContext.Current.CancellationToken);
patchResponse.EnsureSuccessStatusCode();
var updatedPayload = await patchResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
Assert.Equal("critical", updatedPayload.GetProperty("severity").GetString());
Assert.Contains(
updatedPayload.GetProperty("tags").EnumerateArray().Select(item => item.GetString()),
tag => string.Equals(tag, "updated", StringComparison.OrdinalIgnoreCase));
var detailResponse = await _client.GetAsync($"/policy/exceptions/{exceptionId}", TestContext.Current.CancellationToken);
detailResponse.EnsureSuccessStatusCode();
var detailPayload = await detailResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
Assert.Equal(exceptionId, detailPayload.GetProperty("id").GetString());
var revokeResponse = await _client.PostAsJsonAsync(
$"/policy/exceptions/{exceptionId}/revoke",
new { reason = "Compatibility lifecycle completed." },
TestContext.Current.CancellationToken);
revokeResponse.EnsureSuccessStatusCode();
var revokedPayload = await revokeResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
Assert.Equal("revoked", revokedPayload.GetProperty("status").GetString());
}
[Trait("Category", TestCategories.Integration)]
[Fact]
public async Task MergeConflictAndBatchEndpoints_ReturnCompatibilityShapes()
{
var previewResponse = await _client.PostAsJsonAsync(
"/policy/merge/preview",
new
{
sourcePolicies = new[] { "policy-pack-001", "policy-pack-security" },
targetEnvironment = "stage"
},
TestContext.Current.CancellationToken);
previewResponse.EnsureSuccessStatusCode();
var previewPayload = await previewResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
Assert.Equal(1, previewPayload.GetProperty("conflictCount").GetInt32());
Assert.Equal("stage", previewPayload.GetProperty("targetEnvironment").GetString());
var conflictsResponse = await _client.PostAsJsonAsync(
"/policy/conflicts/detect?severityFilter=high",
new
{
policyIds = new[] { "policy-pack-001", "policy-pack-security" }
},
TestContext.Current.CancellationToken);
conflictsResponse.EnsureSuccessStatusCode();
var conflictsPayload = await conflictsResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
Assert.Single(conflictsPayload.GetProperty("conflicts").EnumerateArray());
Assert.Equal("conflict-001", conflictsPayload.GetProperty("conflicts")[0].GetProperty("id").GetString());
var batchCreateResponse = await _client.PostAsJsonAsync(
"/policy/batch-evaluations",
new
{
policyPackId = "policy-pack-001",
policyVersion = 2,
artifacts = new[]
{
new { artifactId = "artifact-qa-001", name = "api-gateway:v1.5.2", type = "sbom" },
new { artifactId = "artifact-qa-002", name = "worker:v1.5.2", type = "sbom" }
},
tags = new[] { "qa", "compat" }
},
TestContext.Current.CancellationToken);
batchCreateResponse.EnsureSuccessStatusCode();
var batchCreatedPayload = await batchCreateResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
var batchId = batchCreatedPayload.GetProperty("batchId").GetString();
Assert.False(string.IsNullOrWhiteSpace(batchId));
Assert.Equal("running", batchCreatedPayload.GetProperty("status").GetString());
var batchDetailResponse = await _client.GetAsync($"/policy/batch-evaluations/{batchId}", TestContext.Current.CancellationToken);
batchDetailResponse.EnsureSuccessStatusCode();
var batchDetailPayload = await batchDetailResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
Assert.Equal("completed", batchDetailPayload.GetProperty("status").GetString());
Assert.Equal(2, batchDetailPayload.GetProperty("results").GetArrayLength());
var batchHistoryResponse = await _client.GetAsync("/policy/batch-evaluations?policyPackId=policy-pack-001&page=1&pageSize=20", TestContext.Current.CancellationToken);
batchHistoryResponse.EnsureSuccessStatusCode();
var batchHistoryPayload = await batchHistoryResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
Assert.Contains(
batchHistoryPayload.GetProperty("items").EnumerateArray().Select(item => item.GetProperty("batchId").GetString()),
historyBatchId => string.Equals(historyBatchId, batchId, StringComparison.OrdinalIgnoreCase));
var cancelResponse = await _client.PostAsJsonAsync($"/policy/batch-evaluations/{batchId}/cancel", new { }, TestContext.Current.CancellationToken);
cancelResponse.EnsureSuccessStatusCode();
var cancelledResponse = await _client.GetAsync($"/policy/batch-evaluations/{batchId}", TestContext.Current.CancellationToken);
cancelledResponse.EnsureSuccessStatusCode();
var cancelledPayload = await cancelledResponse.Content.ReadFromJsonAsync<JsonElement>(TestContext.Current.CancellationToken);
Assert.Equal("cancelled", cancelledPayload.GetProperty("status").GetString());
}
}