fix(audit-log): explicit long CommandTimeout on partition-switch and per-channel purge maintenance paths
This commit is contained in:
@@ -474,4 +474,54 @@ WHERE name = 'UX_AuditLog_EventId'
|
||||
Assert.Contains(rows, r => r.EventId == dbOldId);
|
||||
Assert.Contains(rows, r => r.EventId == dbRecentId);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// 5. SwitchOut_WithExplicitCommandTimeout_Succeeds (Task 4)
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Task 4 (arch-review 04, S2): proves the explicit-<see cref="TimeSpan"/> maintenance-timeout
|
||||
/// overload of <see cref="IAuditLogRepository.SwitchOutPartitionAsync"/> runs the real
|
||||
/// drop-and-rebuild dance to completion against SQL Server — the old row is purged, the kept row
|
||||
/// survives, and the returned sampled row-count reflects the switched partition. Exercising the
|
||||
/// timeout path end-to-end guards against a regression that only sets the timeout on the sample
|
||||
/// command and forgets the DDL batch (or vice versa).
|
||||
/// </summary>
|
||||
[SkippableFact]
|
||||
public async Task SwitchOut_WithExplicitCommandTimeout_Succeeds()
|
||||
{
|
||||
Skip.IfNot(_fixture.Available, _fixture.SkipReason);
|
||||
|
||||
var siteId = "switch-timeout-" + Guid.NewGuid().ToString("N").Substring(0, 8);
|
||||
var oldEventId = Guid.NewGuid();
|
||||
var keptEventId = Guid.NewGuid();
|
||||
var (oldOccurred, keptOccurred, _, _) = SeedOccurredAt();
|
||||
|
||||
await using (var seedConn = _fixture.OpenConnection())
|
||||
{
|
||||
await DirectInsertAsync(seedConn, oldEventId, oldOccurred, siteId);
|
||||
await DirectInsertAsync(seedConn, keptEventId, keptOccurred, siteId);
|
||||
}
|
||||
|
||||
var janBoundary = new DateTime(2026, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
|
||||
await using (var ctx = CreateContext())
|
||||
{
|
||||
var repo = new AuditLogRepository(ctx);
|
||||
var rowsDeleted = await repo.SwitchOutPartitionAsync(janBoundary, TimeSpan.FromMinutes(30));
|
||||
Assert.True(rowsDeleted >= 1,
|
||||
$"Expected the Jan-2026 partition switch-out to report >= 1 sampled row; got {rowsDeleted}.");
|
||||
}
|
||||
|
||||
await using var verify = CreateContext();
|
||||
var rows = await verify.Set<AuditLogRow>()
|
||||
.Where(e => e.SourceSiteId == siteId)
|
||||
.ToListAsync();
|
||||
Assert.DoesNotContain(rows, r => r.EventId == oldEventId);
|
||||
Assert.Contains(rows, r => r.EventId == keptEventId);
|
||||
|
||||
// The dance must leave the idempotency-supporting unique index rebuilt.
|
||||
await using var check = _fixture.OpenConnection();
|
||||
await AssertUxIndexExistsAsync(check);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user