fix(r2-02): range-clamp ResilienceConfig overrides in the parser (01/S-6) — timeout/retry/breaker clamped with diagnostics, never brick
This commit is contained in:
+112
@@ -222,4 +222,116 @@ public sealed class DriverResilienceOptionsParserTests
|
||||
options.RecycleIntervalSeconds.ShouldBeNull();
|
||||
diag.ShouldContain("must be positive");
|
||||
}
|
||||
|
||||
// ---- 01/S-6: range clamps (clamp + diagnostic, never brick) ----
|
||||
|
||||
/// <summary>A non-positive timeout is nonsense; it snaps to the capability's tier default with a diagnostic.</summary>
|
||||
[Fact]
|
||||
public void TimeoutSeconds_Zero_FallsBackToTierDefault_WithDiagnostic()
|
||||
{
|
||||
var options = DriverResilienceOptionsParser.ParseOrDefaults(
|
||||
DriverTier.A, "{\"capabilityPolicies\":{\"Read\":{\"timeoutSeconds\":0}}}", out var diag);
|
||||
|
||||
var tierDefault = DriverResilienceOptions.GetTierDefaults(DriverTier.A)[DriverCapability.Read];
|
||||
options.Resolve(DriverCapability.Read).TimeoutSeconds.ShouldBe(tierDefault.TimeoutSeconds);
|
||||
diag.ShouldNotBeNull();
|
||||
diag.ShouldContain("timeoutSeconds");
|
||||
}
|
||||
|
||||
/// <summary>A timeout above Polly's ceiling clamps to the max with a diagnostic.</summary>
|
||||
[Fact]
|
||||
public void TimeoutSeconds_AbovePollyMax_Clamped()
|
||||
{
|
||||
var options = DriverResilienceOptionsParser.ParseOrDefaults(
|
||||
DriverTier.A, "{\"capabilityPolicies\":{\"Read\":{\"timeoutSeconds\":999999}}}", out var diag);
|
||||
|
||||
options.Resolve(DriverCapability.Read).TimeoutSeconds.ShouldBe(ResiliencePolicyRanges.MaxTimeoutSeconds);
|
||||
diag.ShouldNotBeNull();
|
||||
diag.ShouldContain("timeoutSeconds");
|
||||
}
|
||||
|
||||
/// <summary>A negative retry count clamps to zero with a diagnostic.</summary>
|
||||
[Fact]
|
||||
public void RetryCount_Negative_ClampedToZero()
|
||||
{
|
||||
var options = DriverResilienceOptionsParser.ParseOrDefaults(
|
||||
DriverTier.A, "{\"capabilityPolicies\":{\"Read\":{\"retryCount\":-1}}}", out var diag);
|
||||
|
||||
options.Resolve(DriverCapability.Read).RetryCount.ShouldBe(0);
|
||||
diag.ShouldNotBeNull();
|
||||
diag.ShouldContain("retryCount");
|
||||
}
|
||||
|
||||
/// <summary>An absurd retry count clamps to the operational cap with a diagnostic.</summary>
|
||||
[Fact]
|
||||
public void RetryCount_AboveCap_ClampedTo100()
|
||||
{
|
||||
var options = DriverResilienceOptionsParser.ParseOrDefaults(
|
||||
DriverTier.A, "{\"capabilityPolicies\":{\"Read\":{\"retryCount\":2000000000}}}", out var diag);
|
||||
|
||||
options.Resolve(DriverCapability.Read).RetryCount.ShouldBe(ResiliencePolicyRanges.MaxRetryCount);
|
||||
diag.ShouldNotBeNull();
|
||||
diag.ShouldContain("retryCount");
|
||||
}
|
||||
|
||||
/// <summary>A breaker threshold of 1 (below Polly's MinimumThroughput floor) raises to 2 with a diagnostic.</summary>
|
||||
[Fact]
|
||||
public void BreakerThreshold_One_ClampedToTwo()
|
||||
{
|
||||
var options = DriverResilienceOptionsParser.ParseOrDefaults(
|
||||
DriverTier.A, "{\"capabilityPolicies\":{\"Read\":{\"breakerFailureThreshold\":1}}}", out var diag);
|
||||
|
||||
options.Resolve(DriverCapability.Read).BreakerFailureThreshold.ShouldBe(
|
||||
ResiliencePolicyRanges.MinEnabledBreakerFailureThreshold);
|
||||
diag.ShouldNotBeNull();
|
||||
diag.ShouldContain("breakerFailureThreshold");
|
||||
}
|
||||
|
||||
/// <summary>A negative breaker threshold disables the breaker (0) with a diagnostic.</summary>
|
||||
[Fact]
|
||||
public void BreakerThreshold_Negative_DisablesBreaker()
|
||||
{
|
||||
var options = DriverResilienceOptionsParser.ParseOrDefaults(
|
||||
DriverTier.A, "{\"capabilityPolicies\":{\"Read\":{\"breakerFailureThreshold\":-5}}}", out var diag);
|
||||
|
||||
options.Resolve(DriverCapability.Read).BreakerFailureThreshold.ShouldBe(0);
|
||||
diag.ShouldNotBeNull();
|
||||
diag.ShouldContain("breakerFailureThreshold");
|
||||
}
|
||||
|
||||
/// <summary>Multiple clamps in one policy all surface in the (appended) diagnostic string.</summary>
|
||||
[Fact]
|
||||
public void MultipleClamps_AllSurfaceInDiagnostic()
|
||||
{
|
||||
var options = DriverResilienceOptionsParser.ParseOrDefaults(
|
||||
DriverTier.A,
|
||||
"{\"capabilityPolicies\":{\"Read\":{\"timeoutSeconds\":0,\"retryCount\":-1,\"breakerFailureThreshold\":1}}}",
|
||||
out var diag);
|
||||
|
||||
diag.ShouldNotBeNull();
|
||||
diag.ShouldContain("timeoutSeconds");
|
||||
diag.ShouldContain("retryCount");
|
||||
diag.ShouldContain("breakerFailureThreshold");
|
||||
|
||||
var read = options.Resolve(DriverCapability.Read);
|
||||
read.TimeoutSeconds.ShouldBe(DriverResilienceOptions.GetTierDefaults(DriverTier.A)[DriverCapability.Read].TimeoutSeconds);
|
||||
read.RetryCount.ShouldBe(0);
|
||||
read.BreakerFailureThreshold.ShouldBe(ResiliencePolicyRanges.MinEnabledBreakerFailureThreshold);
|
||||
}
|
||||
|
||||
/// <summary>In-range overrides pass through untouched with no diagnostic.</summary>
|
||||
[Fact]
|
||||
public void InRangeOverrides_PassThrough_NoDiagnostic()
|
||||
{
|
||||
var options = DriverResilienceOptionsParser.ParseOrDefaults(
|
||||
DriverTier.A,
|
||||
"{\"capabilityPolicies\":{\"Read\":{\"timeoutSeconds\":5,\"retryCount\":3,\"breakerFailureThreshold\":4}}}",
|
||||
out var diag);
|
||||
|
||||
diag.ShouldBeNull();
|
||||
var read = options.Resolve(DriverCapability.Read);
|
||||
read.TimeoutSeconds.ShouldBe(5);
|
||||
read.RetryCount.ShouldBe(3);
|
||||
read.BreakerFailureThreshold.ShouldBe(4);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user