fix(deployment): pending-updates tick uses a slim instance projection, hash-only flatten, one untracked mismatch snapshot read and a per-tick secret lookup memo (review 2026-10-21 04/P2)
This commit is contained in:
@@ -745,6 +745,40 @@ public class ArtifactDeploymentServiceTests : TestKit
|
||||
Assert.DoesNotContain(capturingLogger.Messages, m => m.Contains(ciphertextHex, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// review 2026-10-21 04/P2: computing current artifact hashes for N sites that reference the
|
||||
/// same secret reads it from the central store ONCE per evaluation, not once per site — and
|
||||
/// both sites still hash identically to their own uncached computation.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
[Fact]
|
||||
public async Task ComputeCurrentArtifactHashes_SharedSecret_IsReadFromTheStoreOncePerEvaluation()
|
||||
{
|
||||
var siteA = new Site("Site A", "site-a") { Id = 1 };
|
||||
var siteB = new Site("Site B", "site-b") { Id = 2 };
|
||||
foreach (var id in new[] { 1, 2 })
|
||||
{
|
||||
_siteRepo.GetDataConnectionsBySiteIdAsync(id, Arg.Any<CancellationToken>())
|
||||
.Returns(new List<DataConnection>
|
||||
{
|
||||
new($"GW{id}", "MxGateway", id) { PrimaryConfiguration = """{"ApiKey":"secret:shared-key"}""" }
|
||||
});
|
||||
}
|
||||
_secretStore.GetAsync(Arg.Is<SecretName>(n => n.Value == "shared-key"), Arg.Any<CancellationToken>())
|
||||
.Returns(Task.FromResult<StoredSecret?>(SecretRow("shared-key", 3)));
|
||||
var service = CreateService();
|
||||
|
||||
var hashes = await service.ComputeCurrentArtifactHashesAsync([siteA, siteB]);
|
||||
|
||||
Assert.Equal(2, hashes.Count);
|
||||
await _secretStore.Received(1).GetAsync(
|
||||
Arg.Is<SecretName>(n => n.Value == "shared-key"), Arg.Any<CancellationToken>());
|
||||
|
||||
// Memoisation must not change the answer.
|
||||
var single = await service.ComputeCurrentArtifactHashesAsync([siteB]);
|
||||
Assert.Equal(single[2], hashes[2]);
|
||||
}
|
||||
|
||||
// ── Stamp gating on secret application + DeploySiteSecrets audit row ──
|
||||
|
||||
/// <summary>Verifies that an old site that reports no applied secrets fails and is not stamped when secrets were shipped.</summary>
|
||||
|
||||
Reference in New Issue
Block a user