using System; using Paca.Mobile.Core; using Xunit; namespace Paca.Tests.Core; public class DownloadTokenBucketRateLimiterGateTests { [Fact] public void Gate453_DownloadTokenBucketRateLimiter_AllowsImmediateConsumption_WhenBucketFull() { var now = DateTime.UtcNow; var limiter = new DownloadTokenBucketRateLimiter(rateBytesPerSec: 1_000_000, burstCapacityBytes: 2_000_000, initialTime: now); var decision = limiter.Request(500_000, now); Assert.True(decision.IsAllowedImmediately); Assert.Equal(TimeSpan.Zero, decision.DelayRequired); Assert.Equal(1_500_000, limiter.AvailableTokens, 1); } [Fact] public void Gate454_DownloadTokenBucketRateLimiter_CalculatesRequiredDelay_WhenTokensExhausted() { var now = DateTime.UtcNow; var limiter = new DownloadTokenBucketRateLimiter(rateBytesPerSec: 1_000_000, burstCapacityBytes: 1_000_000, initialTime: now); // Exhaust all tokens limiter.Request(1_000_000, now); // Request another 500KB immediately (needs 500ms refill) var decision = limiter.Request(500_000, now); Assert.False(decision.IsAllowedImmediately); Assert.Equal(TimeSpan.FromMilliseconds(500), decision.DelayRequired); } [Fact] public void Gate455_DownloadTokenBucketRateLimiter_RefillsTokensOverTime_UpToCapacity() { var now = DateTime.UtcNow; var limiter = new DownloadTokenBucketRateLimiter(rateBytesPerSec: 1_000_000, burstCapacityBytes: 2_000_000, initialTime: now); // Consume everything limiter.Request(2_000_000, now); Assert.Equal(0, limiter.AvailableTokens, 1); // Advance time by 3 seconds (3MB generated, capped at 2MB burst) var future = now.AddSeconds(3); var decision = limiter.Request(1, future); Assert.True(decision.IsAllowedImmediately); Assert.Equal(2_000_000 - 1, limiter.AvailableTokens, 1); } [Fact] public void Gate456_DownloadTokenBucketRateLimiter_DynamicRateAdjustment_PreservesTokens() { var now = DateTime.UtcNow; var limiter = new DownloadTokenBucketRateLimiter(rateBytesPerSec: 1_000_000, burstCapacityBytes: 2_000_000, initialTime: now); limiter.Request(1_000_000, now); Assert.Equal(1_000_000, limiter.AvailableTokens, 1); // Adjust rate to 5 MB/s limiter.SetRate(5_000_000, now); Assert.Equal(1_000_000, limiter.AvailableTokens, 1); Assert.Equal(5_000_000, limiter.RateBytesPerSec); } }