diff --git a/DevProxy.Integration.Tests/BehaviorPluginsIntegrationTests.cs b/DevProxy.Integration.Tests/BehaviorPluginsIntegrationTests.cs index 1e4fa357..3b0ee4b6 100644 --- a/DevProxy.Integration.Tests/BehaviorPluginsIntegrationTests.cs +++ b/DevProxy.Integration.Tests/BehaviorPluginsIntegrationTests.cs @@ -239,6 +239,47 @@ public void Latency_DelayRangeIncludesMaxMs() Assert.InRange(LatencyPlugin.GetDelay(random, int.MaxValue - 1, int.MaxValue), int.MaxValue - 1, int.MaxValue); } + [Fact] + public async Task Latency_InitializeFailsWhenMinMsGreaterThanMaxMs() + { + var config = PluginConfig.FromJson(""" + { "minMs": 500, "maxMs": 100 } + """); + var plugin = new LatencyPlugin( + SharedHttpClient, + NullLogger.Instance, + KestrelProxyHarness.BuildUrlsToWatch("localhost"), + ProxyConfig, + config); + + using var host = new PluginTestHost(ProxyConfig); + var ex = await Assert.ThrowsAsync( + () => plugin.InitializeAsync(host.CreateInitArgs(), CancellationToken.None)); + + Assert.Contains("minMs (500)", ex.Message, StringComparison.Ordinal); + Assert.Contains("maxMs (100)", ex.Message, StringComparison.Ordinal); + Assert.False(plugin.Enabled); + } + + [Fact] + public async Task Latency_InitializeSucceedsWhenMinMsEqualsMaxMs() + { + var config = PluginConfig.FromJson(""" + { "minMs": 100, "maxMs": 100 } + """); + var plugin = new LatencyPlugin( + SharedHttpClient, + NullLogger.Instance, + KestrelProxyHarness.BuildUrlsToWatch("localhost"), + ProxyConfig, + config); + + using var host = new PluginTestHost(ProxyConfig); + await plugin.InitializeAsync(host.CreateInitArgs(), CancellationToken.None); + + Assert.True(plugin.Enabled); + } + [Fact] public async Task RateLimiting_ThrottlesOnceResourcesAreExhausted() { diff --git a/DevProxy.Plugins/Behavior/LatencyPlugin.cs b/DevProxy.Plugins/Behavior/LatencyPlugin.cs index a892b042..3740e6c0 100644 --- a/DevProxy.Plugins/Behavior/LatencyPlugin.cs +++ b/DevProxy.Plugins/Behavior/LatencyPlugin.cs @@ -32,6 +32,17 @@ public sealed class LatencyPlugin( public override string Name => nameof(LatencyPlugin); + public override async Task InitializeAsync(InitArgs e, CancellationToken cancellationToken) + { + await base.InitializeAsync(e, cancellationToken); + + if (Configuration.MinMs > Configuration.MaxMs) + { + Enabled = false; + throw new InvalidOperationException($"{Name}: minMs ({Configuration.MinMs}) must be less than or equal to maxMs ({Configuration.MaxMs})."); + } + } + // HTTP: Add latency before request is forwarded public override async Task BeforeRequestAsync(ProxyRequestArgs e, CancellationToken cancellationToken) {