From ca0c260c1ab905beefa67e5e3efb363bcbec31ea Mon Sep 17 00:00:00 2001 From: Vojtech Vitek Date: Thu, 8 Aug 2024 17:42:22 +0200 Subject: [PATCH] Add test case for local in-memory fallback --- go.mod | 3 ++ go.sum | 6 ++++ local_fallback_test.go | 70 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 local_fallback_test.go diff --git a/go.mod b/go.mod index 412598e..f281933 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,9 @@ require ( ) require ( + github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 // indirect + github.com/alicebob/miniredis/v2 v2.33.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/yuin/gopher-lua v1.1.1 // indirect ) diff --git a/go.sum b/go.sum index 5e2ed0f..25d3763 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,7 @@ +github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302 h1:uvdUDbHQHO85qeSydJtItA4T55Pw6BtAejd0APRJOCE= +github.com/alicebob/gopher-json v0.0.0-20230218143504-906a9b012302/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= +github.com/alicebob/miniredis/v2 v2.33.0 h1:uvTF0EDeu9RLnUEG27Db5I68ESoIxTiXbNUiji6lZrA= +github.com/alicebob/miniredis/v2 v2.33.0/go.mod h1:MhP4a3EU7aENRi9aO+tHfTBZicLqQevyi/DJpoj6mi0= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -10,5 +14,7 @@ github.com/redis/go-redis/v9 v9.6.0 h1:NLck+Rab3AOTHw21CGRpvQpgTrAU4sgdCswqGtlhG github.com/redis/go-redis/v9 v9.6.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= +github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= +github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= diff --git a/local_fallback_test.go b/local_fallback_test.go new file mode 100644 index 0000000..3c9b8c0 --- /dev/null +++ b/local_fallback_test.go @@ -0,0 +1,70 @@ +package httprateredis_test + +import ( + "fmt" + "math/rand" + "strconv" + "testing" + "time" + + "github.com/alicebob/miniredis/v2" + httprateredis "github.com/go-chi/httprate-redis" +) + +// Test local in-memory counter fallback, which gets activated in case Redis is not available. +func TestLocalFallback(t *testing.T) { + redis, err := miniredis.Run() + redisPort, _ := strconv.Atoi(redis.Port()) + + limitCounter, err := httprateredis.NewRedisLimitCounter(&httprateredis.Config{ + Host: redis.Host(), + Port: uint16(redisPort), + MaxIdle: 0, + MaxActive: 1, + ClientName: "httprateredis_test", + PrefixKey: fmt.Sprintf("httprate:test:%v", rand.Int31n(100000)), // Unique Redis key for each test + FallbackTimeout: 200 * time.Millisecond, + }) + if err != nil { + t.Fatalf("redis not available: %v", err) + } + + limitCounter.Config(1000, time.Minute) + + currentWindow := time.Now().UTC().Truncate(time.Minute) + previousWindow := currentWindow.Add(-time.Minute) + + if limitCounter.IsFallbackActivated() { + t.Error("fallback should not be activated at the beginning") + } + + err = limitCounter.IncrementBy("key:fallback", currentWindow, 1) + if err != nil { + t.Error(err) + } + + _, _, err = limitCounter.Get("key:fallback", currentWindow, previousWindow) + if err != nil { + t.Error(err) + } + + if limitCounter.IsFallbackActivated() { + t.Error("fallback should not be activated before we simulate redis failure") + } + + redis.Close() + + err = limitCounter.IncrementBy("key:fallback", currentWindow, 1) + if err != nil { + t.Error(err) + } + + _, _, err = limitCounter.Get("key:fallback", currentWindow, previousWindow) + if err != nil { + t.Error(err) + } + + if !limitCounter.IsFallbackActivated() { + t.Error("fallback should be activated after we simulate redis failure") + } +}