stabilize tests

This commit is contained in:
master
2026-02-01 21:37:40 +02:00
parent 55744f6a39
commit 5d5e80b2e4
6435 changed files with 33984 additions and 13802 deletions

View File

@@ -0,0 +1,8 @@
# StellaOps.Attestor.Conformance.Tests Task Board
This board mirrors active sprint tasks for this module.
Source of truth: `docs/implplan/SPRINT_20260130_002_Tools_csproj_remediation_solid_review.md`.
| Task ID | Status | Notes |
| --- | --- | --- |
| REMED-05 | TODO | Remediation checklist: docs/implplan/audits/csproj-standards/remediation/checklists/src/Attestor/__Tests/StellaOps.Attestor.Conformance.Tests/StellaOps.Attestor.Conformance.Tests.md. |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -0,0 +1,8 @@
# StellaOps.Attestor.EvidencePack.IntegrationTests Task Board
This board mirrors active sprint tasks for this module.
Source of truth: `docs/implplan/SPRINT_20260130_002_Tools_csproj_remediation_solid_review.md`.
| Task ID | Status | Notes |
| --- | --- | --- |
| REMED-05 | TODO | Remediation checklist: docs/implplan/audits/csproj-standards/remediation/checklists/src/Attestor/__Tests/StellaOps.Attestor.EvidencePack.IntegrationTests/StellaOps.Attestor.EvidencePack.IntegrationTests.md. |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -0,0 +1,8 @@
# StellaOps.Attestor.EvidencePack.Tests Task Board
This board mirrors active sprint tasks for this module.
Source of truth: `docs/implplan/SPRINT_20260130_002_Tools_csproj_remediation_solid_review.md`.
| Task ID | Status | Notes |
| --- | --- | --- |
| REMED-05 | TODO | Remediation checklist: docs/implplan/audits/csproj-standards/remediation/checklists/src/Attestor/__Tests/StellaOps.Attestor.EvidencePack.Tests/StellaOps.Attestor.EvidencePack.Tests.md. |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -0,0 +1,8 @@
# StellaOps.Attestor.FixChain.Tests Task Board
This board mirrors active sprint tasks for this module.
Source of truth: `docs/implplan/SPRINT_20260130_002_Tools_csproj_remediation_solid_review.md`.
| Task ID | Status | Notes |
| --- | --- | --- |
| REMED-05 | TODO | Remediation checklist: docs/implplan/audits/csproj-standards/remediation/checklists/src/Attestor/__Tests/StellaOps.Attestor.FixChain.Tests/StellaOps.Attestor.FixChain.Tests.md. |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -0,0 +1,8 @@
# StellaOps.Attestor.GraphRoot.Tests Task Board
This board mirrors active sprint tasks for this module.
Source of truth: `docs/implplan/SPRINT_20260130_002_Tools_csproj_remediation_solid_review.md`.
| Task ID | Status | Notes |
| --- | --- | --- |
| REMED-05 | TODO | Remediation checklist: docs/implplan/audits/csproj-standards/remediation/checklists/src/Attestor/__Tests/StellaOps.Attestor.GraphRoot.Tests/StellaOps.Attestor.GraphRoot.Tests.md. |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |

View File

@@ -7,7 +7,7 @@
## Required Reading (treat as read before DOING)
- `docs/modules/attestor/architecture.md`
- `docs/product/advisories/14-Dec-2025 - Proof and Evidence Chain Technical Reference.md`
- `docs-archived/product/advisories/2025-12-21-moat-gap-closure/14-Dec-2025 - Proof and Evidence Chain Technical Reference.md`
- RFC 8785 (JSON Canonicalization Scheme)
- Relevant sprint files.
@@ -20,3 +20,4 @@
## Testing
- Use xUnit + FluentAssertions + TestKit; prefer deterministic data.
- Cover canonicalization numeric edge cases, schema validation, and proof signing/verification.

View File

@@ -7,7 +7,7 @@
## Required Reading (treat as read before DOING)
- `docs/modules/attestor/architecture.md`
- `docs/product/advisories/14-Dec-2025 - Proof and Evidence Chain Technical Reference.md`
- `docs-archived/product/advisories/2025-12-21-moat-gap-closure/14-Dec-2025 - Proof and Evidence Chain Technical Reference.md`
- RFC 8785 (JSON Canonicalization Scheme)
- SPDX 3.0.1, CycloneDX 1.6/1.7, and SLSA provenance v1.0 references
- Relevant sprint files.
@@ -21,3 +21,4 @@
## Testing
- Use xUnit + FluentAssertions + TestKit; prefer deterministic data.
- Cover canonicalization numeric edge cases, parser warnings/errors, and SBOM hash determinism.

View File

@@ -19,6 +19,7 @@ public sealed class GeneratorOutputTests
["stellaops-path-witness.v1.schema.json"] = "https://stella.ops/schemas/predicates/path-witness/v1",
["uncertainty-budget-statement.v1.schema.json"] = "https://stella-ops.org/schemas/attestation/uncertainty-budget-statement.v1.json",
["uncertainty-statement.v1.schema.json"] = "https://stella-ops.org/schemas/attestation/uncertainty-statement.v1.json",
["stellaops-binary-micro-witness.v1.schema.json"] = "https://stellaops.dev/schemas/predicates/binary-micro-witness.v1.schema.json",
["verification-policy.v1.schema.json"] = "https://stellaops.io/schemas/verification-policy.v1.json"
};

View File

@@ -235,7 +235,7 @@ public sealed class PatternCompilerTests
public void Performance_Match100EntriesUnder1Ms()
{
// Pre-compile 100 patterns of various modes
var patterns = new List<ICompiledPattern>();
var patterns = new List<CompiledPattern>();
for (int i = 0; i < 25; i++)
{
patterns.Add(_compiler.Compile($"issuer-{i}", WatchlistMatchMode.Exact));

View File

@@ -6,8 +6,8 @@
// -----------------------------------------------------------------------------
using FluentAssertions;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using StellaOps.Attestor.Watchlist.Events;
using StellaOps.Attestor.Watchlist.Matching;
using StellaOps.Attestor.Watchlist.Models;
@@ -35,19 +35,18 @@ public sealed class IdentityMonitorServiceIntegrationTests
_dedupRepository = new InMemoryAlertDedupRepository();
_alertPublisher = new InMemoryIdentityAlertPublisher();
var cache = new MemoryCache(new MemoryCacheOptions());
var patternCompiler = new PatternCompiler();
_matcher = new IdentityMatcher(
_watchlistRepository,
patternCompiler,
cache,
NullLogger<IdentityMatcher>.Instance);
_service = new IdentityMonitorService(
_matcher,
_dedupRepository,
_alertPublisher,
Options.Create(new WatchlistMonitorOptions()),
NullLogger<IdentityMonitorService>.Instance);
}
@@ -79,20 +78,17 @@ public sealed class IdentityMonitorServiceIntegrationTests
LogIndex = 99999,
ArtifactSha256 = "sha256:abcdef123456",
IntegratedTimeUtc = DateTimeOffset.UtcNow,
Identity = new SignerIdentityInput
{
Issuer = "https://token.actions.githubusercontent.com",
SubjectAlternativeName = "repo:org/repo:ref:refs/heads/main"
}
SignerIssuer = "https://token.actions.githubusercontent.com",
SignerSan = "repo:org/repo:ref:refs/heads/main"
};
// Act
await _service.ProcessEntryAsync(entryInfo, CancellationToken.None);
// Assert: Alert should be emitted
_alertPublisher.PublishedEvents.Should().HaveCount(1);
_alertPublisher.GetEvents().Should().HaveCount(1);
var alert = _alertPublisher.PublishedEvents[0];
var alert = _alertPublisher.GetEvents()[0];
alert.EventKind.Should().Be(IdentityAlertEventKinds.IdentityMatched);
alert.TenantId.Should().Be("tenant-1");
alert.WatchlistEntryId.Should().Be(watchlistEntry.Id);
@@ -131,18 +127,15 @@ public sealed class IdentityMonitorServiceIntegrationTests
LogIndex = 99998,
ArtifactSha256 = "sha256:different123",
IntegratedTimeUtc = DateTimeOffset.UtcNow,
Identity = new SignerIdentityInput
{
Issuer = "https://accounts.google.com", // Different issuer
SubjectAlternativeName = "user@example.com"
}
SignerIssuer = "https://accounts.google.com", // Different issuer
SignerSan = "user@example.com"
};
// Act
await _service.ProcessEntryAsync(entryInfo, CancellationToken.None);
// Assert: No alert should be emitted
_alertPublisher.PublishedEvents.Should().BeEmpty();
_alertPublisher.GetEvents().Should().BeEmpty();
}
[Fact]
@@ -173,10 +166,7 @@ public sealed class IdentityMonitorServiceIntegrationTests
LogIndex = 99997,
ArtifactSha256 = "sha256:first123",
IntegratedTimeUtc = DateTimeOffset.UtcNow,
Identity = new SignerIdentityInput
{
Issuer = "https://token.actions.githubusercontent.com"
}
SignerIssuer = "https://token.actions.githubusercontent.com"
};
// Act: Process the same identity twice
@@ -190,16 +180,13 @@ public sealed class IdentityMonitorServiceIntegrationTests
LogIndex = 99996,
ArtifactSha256 = "sha256:second123",
IntegratedTimeUtc = DateTimeOffset.UtcNow,
Identity = new SignerIdentityInput
{
Issuer = "https://token.actions.githubusercontent.com"
}
SignerIssuer = "https://token.actions.githubusercontent.com"
};
await _service.ProcessEntryAsync(entryInfo2, CancellationToken.None);
// Assert: Only first alert should be emitted (second is suppressed)
_alertPublisher.PublishedEvents.Should().HaveCount(1);
_alertPublisher.PublishedEvents[0].RekorEntry.Uuid.Should().Be("test-rekor-uuid-789");
_alertPublisher.GetEvents().Should().HaveCount(1);
_alertPublisher.GetEvents()[0].RekorEntry.Uuid.Should().Be("test-rekor-uuid-789");
}
[Fact]
@@ -231,19 +218,16 @@ public sealed class IdentityMonitorServiceIntegrationTests
LogIndex = 12345,
ArtifactSha256 = "sha256:glob123",
IntegratedTimeUtc = DateTimeOffset.UtcNow,
Identity = new SignerIdentityInput
{
Issuer = "https://token.actions.githubusercontent.com",
SubjectAlternativeName = "repo:org/my-repo:ref:refs/heads/main"
}
SignerIssuer = "https://token.actions.githubusercontent.com",
SignerSan = "repo:org/my-repo:ref:refs/heads/main"
};
// Act
await _service.ProcessEntryAsync(entryInfo, CancellationToken.None);
// Assert
_alertPublisher.PublishedEvents.Should().HaveCount(1);
_alertPublisher.PublishedEvents[0].MatchedIdentity.SubjectAlternativeName
_alertPublisher.GetEvents().Should().HaveCount(1);
_alertPublisher.GetEvents()[0].MatchedIdentity.SubjectAlternativeName
.Should().Be("repo:org/my-repo:ref:refs/heads/main");
}
@@ -274,17 +258,14 @@ public sealed class IdentityMonitorServiceIntegrationTests
LogIndex = 11111,
ArtifactSha256 = "sha256:disabled123",
IntegratedTimeUtc = DateTimeOffset.UtcNow,
Identity = new SignerIdentityInput
{
Issuer = "https://token.actions.githubusercontent.com"
}
SignerIssuer = "https://token.actions.githubusercontent.com"
};
// Act
await _service.ProcessEntryAsync(entryInfo, CancellationToken.None);
// Assert: No alert (entry is disabled)
_alertPublisher.PublishedEvents.Should().BeEmpty();
_alertPublisher.GetEvents().Should().BeEmpty();
}
[Fact]
@@ -315,17 +296,14 @@ public sealed class IdentityMonitorServiceIntegrationTests
LogIndex = 22222,
ArtifactSha256 = "sha256:global123",
IntegratedTimeUtc = DateTimeOffset.UtcNow,
Identity = new SignerIdentityInput
{
Issuer = "https://token.actions.githubusercontent.com"
}
SignerIssuer = "https://token.actions.githubusercontent.com"
};
// Act
await _service.ProcessEntryAsync(entryInfo, CancellationToken.None);
// Assert: Global entry should match across tenants
_alertPublisher.PublishedEvents.Should().HaveCount(1);
_alertPublisher.GetEvents().Should().HaveCount(1);
}
[Fact]
@@ -370,31 +348,15 @@ public sealed class IdentityMonitorServiceIntegrationTests
LogIndex = 33333,
ArtifactSha256 = "sha256:multi123",
IntegratedTimeUtc = DateTimeOffset.UtcNow,
Identity = new SignerIdentityInput
{
Issuer = "https://token.actions.githubusercontent.com"
}
SignerIssuer = "https://token.actions.githubusercontent.com"
};
// Act
await _service.ProcessEntryAsync(entryInfo, CancellationToken.None);
// Assert: Both entries should match and emit alerts
_alertPublisher.PublishedEvents.Should().HaveCount(2);
_alertPublisher.PublishedEvents.Should().Contain(e => e.WatchlistEntryName == "GitHub Watcher 1");
_alertPublisher.PublishedEvents.Should().Contain(e => e.WatchlistEntryName == "GitHub Watcher 2");
_alertPublisher.GetEvents().Should().HaveCount(2);
_alertPublisher.GetEvents().Should().Contain(e => e.WatchlistEntryName == "GitHub Watcher 1");
_alertPublisher.GetEvents().Should().Contain(e => e.WatchlistEntryName == "GitHub Watcher 2");
}
}
/// <summary>
/// Test helper: Attestor entry information for processing.
/// </summary>
public sealed record AttestorEntryInfo
{
public required string TenantId { get; init; }
public required string RekorUuid { get; init; }
public required long LogIndex { get; init; }
public required string ArtifactSha256 { get; init; }
public required DateTimeOffset IntegratedTimeUtc { get; init; }
public required SignerIdentityInput Identity { get; init; }
}

View File

@@ -10,7 +10,6 @@ using Microsoft.Extensions.Logging.Abstractions;
using Npgsql;
using StellaOps.Attestor.Infrastructure.Watchlist;
using StellaOps.Attestor.Watchlist.Models;
using StellaOps.Attestor.Watchlist.Storage;
using Xunit;
namespace StellaOps.Attestor.Watchlist.Tests.Storage;
@@ -200,7 +199,7 @@ public sealed class PostgresAlertDedupRepositoryTests : IAsyncLifetime
var result = await _repository.CheckAndUpdateAsync(
created.Id, "test-identity-hash", 60, CancellationToken.None);
result.ShouldSend.Should().BeTrue();
result.ShouldSuppress.Should().BeFalse();
}
[Fact]

View File

@@ -1,6 +1,7 @@
using Npgsql;
using Testcontainers.PostgreSql;
using Xunit;
using Xunit.Sdk;
namespace StellaOps.Attestor.Watchlist.Tests.Storage;

View File

@@ -0,0 +1,8 @@
# StellaOps.Attestor.Watchlist.Tests Task Board
This board mirrors active sprint tasks for this module.
Source of truth: `docs/implplan/SPRINT_20260130_002_Tools_csproj_remediation_solid_review.md`.
| Task ID | Status | Notes |
| --- | --- | --- |
| REMED-05 | TODO | Remediation checklist: docs/implplan/audits/csproj-standards/remediation/checklists/src/Attestor/__Tests/StellaOps.Attestor.Watchlist.Tests/StellaOps.Attestor.Watchlist.Tests.md. |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |