From 6095b8ede3016c8ed23587ff91c5353aa1aee18c Mon Sep 17 00:00:00 2001 From: blindlobstar Date: Mon, 7 Apr 2025 01:33:31 +0200 Subject: [PATCH] added tests for rate limiter --- 06-rate-limiter/solution/solution.go | 2 +- 06-rate-limiter/task.go | 8 +- 06-rate-limiter/task_test.go | 107 +++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 7 deletions(-) create mode 100644 06-rate-limiter/task_test.go diff --git a/06-rate-limiter/solution/solution.go b/06-rate-limiter/solution/solution.go index 67b83d2..4c4dd0b 100644 --- a/06-rate-limiter/solution/solution.go +++ b/06-rate-limiter/solution/solution.go @@ -1,4 +1,4 @@ -package solution +package main import "time" diff --git a/06-rate-limiter/task.go b/06-rate-limiter/task.go index 7d7a108..9ee8259 100644 --- a/06-rate-limiter/task.go +++ b/06-rate-limiter/task.go @@ -1,10 +1,6 @@ -package solution +package main -import "time" - -type RateLimiter struct { - ticker *time.Ticker -} +type RateLimiter struct{} func NewRateLimiter(n int) *RateLimiter { return &RateLimiter{} diff --git a/06-rate-limiter/task_test.go b/06-rate-limiter/task_test.go new file mode 100644 index 0000000..ee72fea --- /dev/null +++ b/06-rate-limiter/task_test.go @@ -0,0 +1,107 @@ +package main + +import ( + "testing" + "time" +) + +func TestCanTake(t *testing.T) { + tests := []struct { + name string + duration time.Duration + rps int + min int + max int + }{ + { + name: "100 RPS for 1 second", + duration: 1 * time.Second, + rps: 100, + min: 95, + max: 105, // Allow some flexibility + }, + { + name: "100 RPS for 500ms", + duration: 500 * time.Millisecond, + rps: 100, + min: 45, // ~50 requests expected (100 RPS * 0.5s) + max: 55, // Allow some flexibility + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + limiter := NewRateLimiter(tt.rps) + timer := time.NewTimer(tt.duration) + var total int + for loop := true; loop; { + if total > tt.max { + break + } + + select { + case <-timer.C: + loop = false + default: + } + if limiter.CanTake() { + total++ + } + } + + if total < tt.min || total > tt.max { + t.Errorf("failed rps. expeceted between %d and %d, got: %d", tt.min, tt.max, total) + } + }) + } +} + +func TestTake(t *testing.T) { + tests := []struct { + name string + duration time.Duration + rps int + min int + max int + }{ + { + name: "100 RPS for 1 second", + duration: 1 * time.Second, + rps: 100, + min: 95, + max: 105, // Allow some flexibility + }, + { + name: "100 RPS for 500ms", + duration: 500 * time.Millisecond, + rps: 100, + min: 45, // ~50 requests expected (100 RPS * 0.5s) + max: 55, // Allow some flexibility + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + limiter := NewRateLimiter(tt.rps) + timer := time.NewTimer(tt.duration) + var total int + for loop := true; loop; { + if total > tt.max { + break + } + + select { + case <-timer.C: + loop = false + default: + } + limiter.Take() + total++ + } + + if total < tt.min || total > tt.max { + t.Errorf("failed rps. expeceted between %d and %d, got: %d", tt.min, tt.max, total) + } + }) + } +}