save checkpoint: save features

This commit is contained in:
master
2026-02-12 10:27:23 +02:00
parent dca86e1248
commit 5bca406787
8837 changed files with 1796879 additions and 5294 deletions

View File

@@ -187,9 +187,123 @@ public sealed class PostgresVexObservationStoreTests : IAsyncLifetime
count.Should().Be(3);
}
private VexObservation CreateObservation(string observationId, string providerId, string vulnId, string productKey)
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task UpdateRekorLinkageAsync_RoundTripsLinkageAndLookupByUuid()
{
var now = DateTimeOffset.UtcNow;
// Arrange
var observation = CreateObservation(
"obs-rekor-1",
"provider-a",
"CVE-REKOR-1",
"pkg:rekor/one@1.0.0",
createdAt: new DateTimeOffset(2026, 1, 17, 8, 0, 0, TimeSpan.Zero));
await _store.InsertAsync(observation, CancellationToken.None);
var linkage = new RekorLinkage
{
Uuid = "rekor-uuid-obs-rekor-1",
LogIndex = 4242,
IntegratedTime = new DateTimeOffset(2026, 1, 17, 8, 5, 0, TimeSpan.Zero),
LogUrl = "https://rekor.local.test",
TreeRoot = "tree-root-001",
TreeSize = 9001,
EntryBodyHash = "sha256:entry-body-001",
EntryKind = "dsse",
InclusionProof = new VexInclusionProof
{
LeafIndex = 4242,
TreeSize = 9001,
Hashes = ["hash-a", "hash-b"],
RootHash = "root-hash-001"
}
};
// Act
var updated = await _store.UpdateRekorLinkageAsync(
_tenantId,
"obs-rekor-1",
linkage,
CancellationToken.None);
var fetched = await _store.GetByRekorUuidAsync(
_tenantId,
"rekor-uuid-obs-rekor-1",
CancellationToken.None);
// Assert
updated.Should().BeTrue();
fetched.Should().NotBeNull();
fetched!.ObservationId.Should().Be("obs-rekor-1");
fetched.HasRekorLinkage.Should().BeTrue();
fetched.RekorUuid.Should().Be("rekor-uuid-obs-rekor-1");
fetched.RekorLogIndex.Should().Be(4242);
fetched.RekorLogUrl.Should().Be("https://rekor.local.test");
fetched.RekorIntegratedTime.Should().Be(new DateTimeOffset(2026, 1, 17, 8, 5, 0, TimeSpan.Zero));
fetched.RekorInclusionProof.Should().NotBeNull();
fetched.RekorInclusionProof!.LeafIndex.Should().Be(4242);
fetched.RekorInclusionProof.TreeSize.Should().Be(9001);
fetched.RekorInclusionProof.Hashes.Should().Equal("hash-a", "hash-b");
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task UpdateRekorLinkageAsync_ReturnsFalseForUnknownObservation()
{
// Arrange
var linkage = new RekorLinkage
{
Uuid = "missing-observation-rekor-uuid",
LogIndex = 1,
IntegratedTime = new DateTimeOffset(2026, 1, 17, 9, 0, 0, TimeSpan.Zero)
};
// Act
var updated = await _store.UpdateRekorLinkageAsync(
_tenantId,
"missing-observation-id",
linkage,
CancellationToken.None);
// Assert
updated.Should().BeFalse();
}
[Trait("Category", TestCategories.Unit)]
[Fact]
public async Task GetPendingRekorAttestationAsync_ReturnsOnlyUnlinkedObservationsOrderedByCreatedAt()
{
// Arrange
var start = new DateTimeOffset(2026, 1, 17, 10, 0, 0, TimeSpan.Zero);
await _store.InsertAsync(CreateObservation("obs-pending-1", "provider-a", "CVE-PEND-1", "pkg:pending/one@1.0.0", start), CancellationToken.None);
await _store.InsertAsync(CreateObservation("obs-pending-2", "provider-a", "CVE-PEND-2", "pkg:pending/two@1.0.0", start.AddMinutes(1)), CancellationToken.None);
await _store.InsertAsync(CreateObservation("obs-pending-3", "provider-a", "CVE-PEND-3", "pkg:pending/three@1.0.0", start.AddMinutes(2)), CancellationToken.None);
var linkage = new RekorLinkage
{
Uuid = "rekor-uuid-linked-obs-pending-2",
LogIndex = 2002,
IntegratedTime = start.AddMinutes(3)
};
await _store.UpdateRekorLinkageAsync(_tenantId, "obs-pending-2", linkage, CancellationToken.None);
// Act
var pending = await _store.GetPendingRekorAttestationAsync(_tenantId, 10, CancellationToken.None);
var limited = await _store.GetPendingRekorAttestationAsync(_tenantId, 1, CancellationToken.None);
// Assert
pending.Select(o => o.ObservationId).Should().Equal("obs-pending-1", "obs-pending-3");
pending.Should().OnlyContain(o => !o.HasRekorLinkage);
limited.Select(o => o.ObservationId).Should().Equal("obs-pending-1");
}
private VexObservation CreateObservation(
string observationId,
string providerId,
string vulnId,
string productKey,
DateTimeOffset? createdAt = null)
{
var now = createdAt ?? DateTimeOffset.UtcNow;
var statement = new VexObservationStatement(
vulnId,
@@ -235,4 +349,3 @@ public sealed class PostgresVexObservationStoreTests : IAsyncLifetime
}

View File

@@ -8,3 +8,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
| AUDIT-0324-M | DONE | Revalidated 2026-01-07; maintainability audit for Excititor.Persistence.Tests. |
| AUDIT-0324-T | DONE | Revalidated 2026-01-07; test coverage audit for Excititor.Persistence.Tests. |
| AUDIT-0324-A | DONE | Waived (test project; revalidated 2026-01-07). |
| QA-DEVOPS-VERIFY-002-T | DONE | 2026-02-11: Added Rekor linkage behavioral tests (round-trip, pending ordering, missing-observation negative path) for `vex-rekor-linkage` run-001. |