Harden Surreal migration with retry/coverage fixes and XML docs cleanup
All checks were successful
NuGet Package Publish / nuget (push) Successful in 1m17s

This commit is contained in:
Joseph Doherty
2026-02-22 05:39:00 -05:00
parent 9c2a77dc3c
commit bd10914828
27 changed files with 1402 additions and 19 deletions

View File

@@ -13,6 +13,11 @@ namespace ZB.MOM.WW.CBDDC.Sample.Console.Tests;
public class SurrealCdcMatrixCompletionTests
{
/// <summary>
/// Verifies retention-boundary classifier behavior across expected exception message patterns.
/// </summary>
/// <param name="message">The exception message sample.</param>
/// <param name="expected">Expected classifier outcome.</param>
[Theory]
[InlineData("versionstamp is outside the configured retention window", true)]
[InlineData("change feed history since cursor is unavailable", true)]
@@ -29,6 +34,9 @@ public class SurrealCdcMatrixCompletionTests
actual.ShouldBe(expected);
}
/// <summary>
/// Verifies a local write produces exactly one oplog entry.
/// </summary>
[Fact]
public async Task LocalWrite_ShouldEmitExactlyOneOplogEntry()
{
@@ -63,6 +71,9 @@ public class SurrealCdcMatrixCompletionTests
}
}
/// <summary>
/// Verifies checkpoint persistence does not advance when atomic write fails.
/// </summary>
[Fact]
public async Task Checkpoint_ShouldNotAdvance_WhenAtomicWriteFails()
{
@@ -139,6 +150,14 @@ public class SurrealCdcMatrixCompletionTests
internal sealed class FailureInjectedDocumentStore : SurrealDocumentStore<object>
{
/// <summary>
/// Initializes a new instance of the <see cref="FailureInjectedDocumentStore" /> class.
/// </summary>
/// <param name="surrealEmbeddedClient">The embedded Surreal client provider.</param>
/// <param name="schemaInitializer">The schema initializer.</param>
/// <param name="configProvider">The node configuration provider.</param>
/// <param name="vectorClockService">The vector clock service.</param>
/// <param name="checkpointPersistence">The CDC checkpoint persistence dependency.</param>
public FailureInjectedDocumentStore(
ICBDDCSurrealEmbeddedClient surrealEmbeddedClient,
ICBDDCSurrealSchemaInitializer schemaInitializer,
@@ -158,6 +177,15 @@ internal sealed class FailureInjectedDocumentStore : SurrealDocumentStore<object
{
}
/// <summary>
/// Triggers local change handling for testing failure scenarios.
/// </summary>
/// <param name="collection">The collection name.</param>
/// <param name="key">The document key.</param>
/// <param name="operationType">The operation type.</param>
/// <param name="content">Optional document content payload.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>A task that completes when processing is finished.</returns>
public Task TriggerLocalChangeAsync(
string collection,
string key,
@@ -174,6 +202,7 @@ internal sealed class FailureInjectedDocumentStore : SurrealDocumentStore<object
cancellationToken);
}
/// <inheritdoc />
protected override Task ApplyContentToEntityAsync(
string collection,
string key,
@@ -183,6 +212,7 @@ internal sealed class FailureInjectedDocumentStore : SurrealDocumentStore<object
return Task.CompletedTask;
}
/// <inheritdoc />
protected override Task ApplyContentToEntitiesBatchAsync(
IEnumerable<(string Collection, string Key, JsonElement Content)> documents,
CancellationToken cancellationToken)
@@ -190,6 +220,7 @@ internal sealed class FailureInjectedDocumentStore : SurrealDocumentStore<object
return Task.CompletedTask;
}
/// <inheritdoc />
protected override Task<JsonElement?> GetEntityAsJsonAsync(
string collection,
string key,
@@ -198,11 +229,13 @@ internal sealed class FailureInjectedDocumentStore : SurrealDocumentStore<object
return Task.FromResult<JsonElement?>(null);
}
/// <inheritdoc />
protected override Task RemoveEntityAsync(string collection, string key, CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
/// <inheritdoc />
protected override Task RemoveEntitiesBatchAsync(
IEnumerable<(string Collection, string Key)> documents,
CancellationToken cancellationToken)
@@ -210,6 +243,7 @@ internal sealed class FailureInjectedDocumentStore : SurrealDocumentStore<object
return Task.CompletedTask;
}
/// <inheritdoc />
protected override Task<IEnumerable<(string Key, JsonElement Content)>> GetAllEntitiesAsJsonAsync(
string collection,
CancellationToken cancellationToken)