limiter_test.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package ratelimit
  2. import (
  3. "context"
  4. "testing"
  5. "time"
  6. "git3.techno-world.net/lrosales/broad-announce/internal/store"
  7. )
  8. func newRedis(t *testing.T) *store.Redis {
  9. t.Helper()
  10. r, err := store.ConnectRedis(context.Background(), "redis://localhost:6379/0")
  11. if err != nil {
  12. t.Skipf("redis not available: %v", err)
  13. }
  14. return r
  15. }
  16. func TestAllow_UnderCap(t *testing.T) {
  17. r := newRedis(t)
  18. l := New(r.Client)
  19. for i := 0; i < 5; i++ {
  20. ok, _, err := l.Allow(context.Background(), "test-under-"+time.Now().Format(time.RFC3339Nano), 100)
  21. if err != nil {
  22. t.Fatal(err)
  23. }
  24. if !ok {
  25. t.Fatalf("denied at i=%d under cap", i)
  26. }
  27. }
  28. }
  29. func TestAllow_OverCap(t *testing.T) {
  30. r := newRedis(t)
  31. l := New(r.Client)
  32. key := "test-over-" + time.Now().Format(time.RFC3339Nano)
  33. // cap=2, try 5 in one second
  34. for i := 0; i < 2; i++ {
  35. ok, _, _ := l.Allow(context.Background(), key, 2)
  36. if !ok {
  37. t.Fatalf("denied at i=%d", i)
  38. }
  39. }
  40. ok, ttl, _ := l.Allow(context.Background(), key, 2)
  41. if ok {
  42. t.Fatal("expected deny at i=3")
  43. }
  44. if ttl <= 0 || ttl > 2*time.Second {
  45. t.Fatalf("ttl out of range: %v", ttl)
  46. }
  47. }
  48. func TestAllow_ZeroCapIsNoOp(t *testing.T) {
  49. r := newRedis(t)
  50. l := New(r.Client)
  51. for i := 0; i < 1000; i++ {
  52. ok, _, _ := l.Allow(context.Background(), "noop", 0)
  53. if !ok {
  54. t.Fatal("zero cap must always allow")
  55. }
  56. }
  57. }