fix(r2-02): pipeline Build clamps policy values — building a pipeline can never throw Polly ValidationException (01/S-6 belt-and-braces + brick repro)
This commit is contained in:
+31
@@ -325,6 +325,37 @@ public sealed class DriverResiliencePipelineBuilderTests
|
||||
e.Message.Contains("host-9"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 01/S-6 builder invariant: building a pipeline from a hostile, directly-constructed
|
||||
/// <see cref="CapabilityPolicy"/> (bypassing the parser) must NEVER throw Polly's
|
||||
/// <c>ValidationException</c>. Sweeps the full matrix of {int.MinValue, -1, 0, 1, int.MaxValue}
|
||||
/// across timeout/retry/breaker and asserts every built pipeline executes a trivial call.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public async Task Build_NeverThrows_ForHostileDirectOptions()
|
||||
{
|
||||
int[] hostile = { int.MinValue, -1, 0, 1, int.MaxValue };
|
||||
var host = 0;
|
||||
foreach (var t in hostile)
|
||||
foreach (var r in hostile)
|
||||
foreach (var b in hostile)
|
||||
{
|
||||
var options = new DriverResilienceOptions
|
||||
{
|
||||
Tier = DriverTier.A,
|
||||
CapabilityPolicies = new Dictionary<DriverCapability, CapabilityPolicy>
|
||||
{
|
||||
[DriverCapability.Read] = new(TimeoutSeconds: t, RetryCount: r, BreakerFailureThreshold: b),
|
||||
},
|
||||
};
|
||||
var builder = new DriverResiliencePipelineBuilder();
|
||||
var pipeline = builder.GetOrCreate("hostile", $"h{host++}", DriverCapability.Read, options);
|
||||
|
||||
var result = await pipeline.ExecuteAsync(_ => ValueTask.FromResult(1), CancellationToken.None);
|
||||
result.ShouldBe(1, $"pipeline built from hostile (t={t}, r={r}, b={b}) must execute, not throw");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Minimal in-memory <see cref="ILogger"/> capturing (level, formatted-message) pairs so the
|
||||
/// resilience logging contract can be asserted without a real logging provider.</summary>
|
||||
private sealed class CapturingLogger : ILogger
|
||||
|
||||
Reference in New Issue
Block a user