Skip to content

Commit d7d563a

Browse files
author
Petr Pchelko
authored
Add support for rate limit overrides. (#158)
Fixes #154 Signed-off-by: Petr Pchelko <ppchelko@wikimedia.org>
1 parent 60af777 commit d7d563a

File tree

7 files changed

+161
-15
lines changed

7 files changed

+161
-15
lines changed

go.mod

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@ go 1.14
55
require (
66
github.com/alicebob/miniredis/v2 v2.11.4
77
github.com/cespare/xxhash v1.1.0 // indirect
8+
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354 // indirect
89
github.com/coocood/freecache v1.1.0
9-
github.com/envoyproxy/go-control-plane v0.9.5
10+
github.com/envoyproxy/go-control-plane v0.9.6
1011
github.com/gogo/protobuf v1.3.1 // indirect
1112
github.com/golang/mock v1.4.1
12-
github.com/golang/protobuf v1.3.2
13+
github.com/golang/protobuf v1.4.2
1314
github.com/gorilla/mux v1.7.4-0.20191121170500-49c01487a141
1415
github.com/kavu/go_reuseport v1.2.0
1516
github.com/kelseyhightower/envconfig v1.1.0
@@ -26,8 +27,8 @@ require (
2627
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553
2728
golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a // indirect
2829
golang.org/x/text v0.3.3-0.20191122225017-cbf43d21aaeb // indirect
29-
google.golang.org/genproto v0.0.0-20191216205247-b31c10ee225f // indirect
30-
google.golang.org/grpc v1.25.1
30+
google.golang.org/grpc v1.27.0
31+
google.golang.org/protobuf v1.25.0 // indirect
3132
gopkg.in/airbrake/gobrake.v2 v2.0.9 // indirect
3233
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2 // indirect
3334
gopkg.in/yaml.v2 v2.3.0

go.sum

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
1414
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
1515
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
1616
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
17+
github.com/cncf/udpa v0.0.0-20200629203442-efcf912fb354 h1:JBAT2dkeyeqzQOaAA8tB21Zfyv/nHfaqjZvWIllABnw=
1718
github.com/cncf/udpa/go v0.0.0-20200313221541-5f7e5dd04533 h1:8wZizuKuZVu5COB7EsBYxBQz8nRcXXn5d4Gt91eJLvU=
1819
github.com/cncf/udpa/go v0.0.0-20200313221541-5f7e5dd04533/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
20+
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354 h1:9kRtNpqLHbZVO/NNxhHp2ymxFxsHOe3x2efJGn//Tas=
21+
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
1922
github.com/coocood/freecache v1.1.0 h1:ENiHOsWdj1BrrlPwblhbn4GdAsMymK3pZORJ+bJGAjA=
2023
github.com/coocood/freecache v1.1.0/go.mod h1:ePwxCDzOYvARfHdr1pByNct1at3CoKnsipOHwKlNbzI=
2124
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -24,8 +27,13 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
2427
github.com/envoyproxy/go-control-plane v0.6.9 h1:deEH9W8ZAUGNbCdX+9iNzBOGrAOrnpJGoy0PcTqk/tE=
2528
github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
2629
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
30+
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
2731
github.com/envoyproxy/go-control-plane v0.9.5 h1:lRJIqDD8yjV1YyPRqecMdytjDLs2fTXq363aCib5xPU=
2832
github.com/envoyproxy/go-control-plane v0.9.5/go.mod h1:OXl5to++W0ctG+EHWTFUjiypVxC/Y4VLc/KFU+al13s=
33+
github.com/envoyproxy/go-control-plane v0.9.6-0.20200630214754-219d0fe20d5e h1:C4C1u9L0TNuvG9Se3g5DdqplIjf4qy7EqzUrOr8RCVI=
34+
github.com/envoyproxy/go-control-plane v0.9.6-0.20200630214754-219d0fe20d5e/go.mod h1:JvuSsUgXzeWfLVfAe9OeW40eBtd+E8yMydqNm0iuBxs=
35+
github.com/envoyproxy/go-control-plane v0.9.6 h1:GgblEiDzxf5ajlAZY4aC8xp7DwkrGfauFNMGdB2bBv0=
36+
github.com/envoyproxy/go-control-plane v0.9.6/go.mod h1:GFqM7v0B62MraO4PWRedIbhThr/Rf7ev6aHOOPXeaDA=
2937
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
3038
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
3139
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
@@ -40,8 +48,21 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
4048
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
4149
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
4250
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
51+
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
52+
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
53+
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
54+
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
55+
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
56+
github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0=
57+
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
58+
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
59+
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
4360
github.com/gomodule/redigo v1.7.1-0.20190322064113-39e2c31b7ca3/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
4461
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
62+
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
63+
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
64+
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
65+
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
4566
github.com/gorilla/mux v1.7.4-0.20191121170500-49c01487a141 h1:VQjjMh+uElTfioy6GnUrVrTMAiLTNF3xsrAlSwC+g8o=
4667
github.com/gorilla/mux v1.7.4-0.20191121170500-49c01487a141/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
4768
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
@@ -136,17 +157,33 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+y
136157
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
137158
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898 h1:/atklqdjdhuosWIl6AIbOeHJjicWYPqR9bpxqxYG2pA=
138159
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
160+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
161+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
139162
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
140163
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
141164
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
142165
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
143166
google.golang.org/genproto v0.0.0-20191216205247-b31c10ee225f h1:0RYv5T9ZdroAqqfM2taEB0nJrArv0X1JpIdgUmY4xg8=
144167
google.golang.org/genproto v0.0.0-20191216205247-b31c10ee225f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
168+
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
169+
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
145170
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
146171
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
147172
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
148173
google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0=
149174
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
175+
google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=
176+
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
177+
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
178+
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
179+
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
180+
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
181+
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
182+
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
183+
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
184+
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
185+
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
186+
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
150187
gopkg.in/airbrake/gobrake.v2 v2.0.9 h1:7z2uVWwn7oVeeugY1DtlPAy5H+KYgB1KeKTnqjNatLo=
151188
gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
152189
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=

src/config/config_impl.go

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ type rateLimitDomain struct {
3939
}
4040

4141
type rateLimitConfigImpl struct {
42-
domains map[string]*rateLimitDomain
42+
domains map[string]*rateLimitDomain
43+
statsScope stats.Scope
4344
}
4445

4546
var validKeys = map[string]bool{
@@ -197,8 +198,7 @@ func validateYamlKeys(config RateLimitConfigToLoad, config_map map[interface{}]i
197198

198199
// Load a single YAML config file into the global config.
199200
// @param config specifies the file contents to load.
200-
// @param statsScope supplies the owning scope.
201-
func (this *rateLimitConfigImpl) loadConfig(config RateLimitConfigToLoad, statsScope stats.Scope) {
201+
func (this *rateLimitConfigImpl) loadConfig(config RateLimitConfigToLoad) {
202202
// validate keys in config with generic map
203203
any := map[interface{}]interface{}{}
204204
err := yaml.Unmarshal([]byte(config.FileBytes), &any)
@@ -228,10 +228,24 @@ func (this *rateLimitConfigImpl) loadConfig(config RateLimitConfigToLoad, statsS
228228

229229
logger.Debugf("loading domain: %s", root.Domain)
230230
newDomain := &rateLimitDomain{rateLimitDescriptor{map[string]*rateLimitDescriptor{}, nil}}
231-
newDomain.loadDescriptors(config, root.Domain+".", root.Descriptors, statsScope)
231+
newDomain.loadDescriptors(config, root.Domain+".", root.Descriptors, this.statsScope)
232232
this.domains[root.Domain] = newDomain
233233
}
234234

235+
func (this *rateLimitConfigImpl) descriptorToKey(descriptor *pb_struct.RateLimitDescriptor) string {
236+
rateLimitKey := ""
237+
for _, entry := range descriptor.Entries {
238+
if rateLimitKey != "" {
239+
rateLimitKey += "."
240+
}
241+
rateLimitKey += entry.Key
242+
if entry.Value != "" {
243+
rateLimitKey += "_" + entry.Value
244+
}
245+
}
246+
return rateLimitKey
247+
}
248+
235249
func (this *rateLimitConfigImpl) Dump() string {
236250
ret := ""
237251
for _, domain := range this.domains {
@@ -252,6 +266,17 @@ func (this *rateLimitConfigImpl) GetLimit(
252266
return rateLimit
253267
}
254268

269+
if descriptor.GetLimit() != nil {
270+
rateLimitKey := domain + "." + this.descriptorToKey(descriptor)
271+
rateLimitOverrideUnit := pb.RateLimitResponse_RateLimit_Unit(descriptor.GetLimit().GetUnit())
272+
rateLimit = NewRateLimit(
273+
descriptor.GetLimit().GetRequestsPerUnit(),
274+
rateLimitOverrideUnit,
275+
rateLimitKey,
276+
this.statsScope)
277+
return rateLimit
278+
}
279+
255280
descriptorsMap := value.descriptors
256281
for i, entry := range descriptor.Entries {
257282
// First see if key_value is in the map. If that isn't in the map we look for just key
@@ -292,9 +317,9 @@ func (this *rateLimitConfigImpl) GetLimit(
292317
func NewRateLimitConfigImpl(
293318
configs []RateLimitConfigToLoad, statsScope stats.Scope) RateLimitConfig {
294319

295-
ret := &rateLimitConfigImpl{map[string]*rateLimitDomain{}}
320+
ret := &rateLimitConfigImpl{map[string]*rateLimitDomain{}, statsScope}
296321
for _, config := range configs {
297-
ret.loadConfig(config, statsScope)
322+
ret.loadConfig(config)
298323
}
299324

300325
return ret

src/service/ratelimit_legacy.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ func ConvertResponse(response *pb.RateLimitResponse) (*pb_legacy.RateLimitRespon
110110
}
111111
if status.GetCurrentLimit() != nil {
112112
statuses[i].CurrentLimit = &pb_legacy.RateLimitResponse_RateLimit{
113+
Name: status.GetCurrentLimit().GetName(),
113114
RequestsPerUnit: status.GetCurrentLimit().GetRequestsPerUnit(),
114115
Unit: pb_legacy.RateLimitResponse_RateLimit_Unit(status.GetCurrentLimit().GetUnit()),
115116
}

test/config/config_test.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package config_test
22

33
import (
4+
"github.com/envoyproxy/ratelimit/test/common"
45
"io/ioutil"
56
"testing"
67

78
pb_struct "github.com/envoyproxy/go-control-plane/envoy/extensions/common/ratelimit/v3"
89
pb "github.com/envoyproxy/go-control-plane/envoy/service/ratelimit/v3"
10+
pb_type "github.com/envoyproxy/go-control-plane/envoy/type/v3"
911
"github.com/envoyproxy/ratelimit/src/config"
1012
"github.com/lyft/gostats"
1113
"github.com/stretchr/testify/assert"
@@ -150,6 +152,80 @@ func TestBasicConfig(t *testing.T) {
150152
assert.EqualValues(1, stats.NewCounter("test-domain.key4.near_limit").Value())
151153
}
152154

155+
func TestConfigLimitOverride(t *testing.T) {
156+
assert := assert.New(t)
157+
stats := stats.NewStore(stats.NewNullSink(), false)
158+
rlConfig := config.NewRateLimitConfigImpl(loadFile("basic_config.yaml"), stats)
159+
rlConfig.Dump()
160+
// No matching domain
161+
assert.Nil(rlConfig.GetLimit(nil, "foo_domain", &pb_struct.RateLimitDescriptor{
162+
Limit: &pb_struct.RateLimitDescriptor_RateLimitOverride{
163+
RequestsPerUnit: 10, Unit: pb_type.RateLimitUnit_DAY,
164+
},
165+
}))
166+
rl := rlConfig.GetLimit(
167+
nil, "test-domain",
168+
&pb_struct.RateLimitDescriptor{
169+
Entries: []*pb_struct.RateLimitDescriptor_Entry{{Key: "key1", Value: "value1"}, {Key: "subkey1", Value: "something"}},
170+
Limit: &pb_struct.RateLimitDescriptor_RateLimitOverride{
171+
RequestsPerUnit: 10, Unit: pb_type.RateLimitUnit_DAY,
172+
},
173+
})
174+
assert.Equal("test-domain.key1_value1.subkey1_something", rl.FullKey)
175+
common.AssertProtoEqual(assert, &pb.RateLimitResponse_RateLimit{
176+
RequestsPerUnit: 10,
177+
Unit: pb.RateLimitResponse_RateLimit_DAY,
178+
}, rl.Limit)
179+
rl.Stats.TotalHits.Inc()
180+
rl.Stats.OverLimit.Inc()
181+
rl.Stats.NearLimit.Inc()
182+
assert.EqualValues(1, stats.NewCounter("test-domain.key1_value1.subkey1_something.total_hits").Value())
183+
assert.EqualValues(1, stats.NewCounter("test-domain.key1_value1.subkey1_something.over_limit").Value())
184+
assert.EqualValues(1, stats.NewCounter("test-domain.key1_value1.subkey1_something.near_limit").Value())
185+
186+
// Change in override value doesn't erase stats
187+
rl = rlConfig.GetLimit(
188+
nil, "test-domain",
189+
&pb_struct.RateLimitDescriptor{
190+
Entries: []*pb_struct.RateLimitDescriptor_Entry{{Key: "key1", Value: "value1"}, {Key: "subkey1", Value: "something"}},
191+
Limit: &pb_struct.RateLimitDescriptor_RateLimitOverride{
192+
RequestsPerUnit: 42, Unit: pb_type.RateLimitUnit_HOUR,
193+
},
194+
})
195+
assert.Equal("test-domain.key1_value1.subkey1_something", rl.FullKey)
196+
rl.Stats.TotalHits.Inc()
197+
rl.Stats.OverLimit.Inc()
198+
rl.Stats.NearLimit.Inc()
199+
common.AssertProtoEqual(assert, &pb.RateLimitResponse_RateLimit{
200+
RequestsPerUnit: 42,
201+
Unit: pb.RateLimitResponse_RateLimit_HOUR,
202+
}, rl.Limit)
203+
assert.EqualValues(2, stats.NewCounter("test-domain.key1_value1.subkey1_something.total_hits").Value())
204+
assert.EqualValues(2, stats.NewCounter("test-domain.key1_value1.subkey1_something.over_limit").Value())
205+
assert.EqualValues(2, stats.NewCounter("test-domain.key1_value1.subkey1_something.near_limit").Value())
206+
207+
// Different value creates a different counter
208+
rl = rlConfig.GetLimit(
209+
nil, "test-domain",
210+
&pb_struct.RateLimitDescriptor{
211+
Entries: []*pb_struct.RateLimitDescriptor_Entry{{Key: "key1", Value: "value1"}, {Key: "subkey1", Value: "something_else"}},
212+
Limit: &pb_struct.RateLimitDescriptor_RateLimitOverride{
213+
RequestsPerUnit: 42, Unit: pb_type.RateLimitUnit_HOUR,
214+
},
215+
})
216+
assert.Equal("test-domain.key1_value1.subkey1_something_else", rl.FullKey)
217+
common.AssertProtoEqual(assert, &pb.RateLimitResponse_RateLimit{
218+
RequestsPerUnit: 42,
219+
Unit: pb.RateLimitResponse_RateLimit_HOUR,
220+
}, rl.Limit)
221+
rl.Stats.TotalHits.Inc()
222+
rl.Stats.OverLimit.Inc()
223+
rl.Stats.NearLimit.Inc()
224+
assert.EqualValues(1, stats.NewCounter("test-domain.key1_value1.subkey1_something_else.total_hits").Value())
225+
assert.EqualValues(1, stats.NewCounter("test-domain.key1_value1.subkey1_something_else.over_limit").Value())
226+
assert.EqualValues(1, stats.NewCounter("test-domain.key1_value1.subkey1_something_else.near_limit").Value())
227+
}
228+
153229
func expectConfigPanic(t *testing.T, call func(), expectedError string) {
154230
assert := assert.New(t)
155231
defer func() {

test/integration/integration_test.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,8 @@ func TestBasicConfigLegacy(t *testing.T) {
427427
response, err = c.ShouldRateLimit(
428428
context.Background(),
429429
common.NewRateLimitRequestLegacy("basic_legacy", [][][2]string{{{"key1", "foo"}}}, 1))
430-
assert.Equal(
430+
common.AssertProtoEqual(
431+
assert,
431432
&pb_legacy.RateLimitResponse{
432433
OverallCode: pb_legacy.RateLimitResponse_OK,
433434
Statuses: []*pb_legacy.RateLimitResponse_DescriptorStatus{
@@ -451,7 +452,8 @@ func TestBasicConfigLegacy(t *testing.T) {
451452
limitRemaining = 0
452453
}
453454

454-
assert.Equal(
455+
common.AssertProtoEqual(
456+
assert,
455457
&pb_legacy.RateLimitResponse{
456458
OverallCode: status,
457459
Statuses: []*pb_legacy.RateLimitResponse_DescriptorStatus{
@@ -479,7 +481,8 @@ func TestBasicConfigLegacy(t *testing.T) {
479481
limitRemaining2 = 0
480482
}
481483

482-
assert.Equal(
484+
common.AssertProtoEqual(
485+
assert,
483486
&pb_legacy.RateLimitResponse{
484487
OverallCode: status,
485488
Statuses: []*pb_legacy.RateLimitResponse_DescriptorStatus{
@@ -523,7 +526,8 @@ func testConfigReload(grpcPort, perSecond string, local_cache_size string) func(
523526
response, err := c.ShouldRateLimit(
524527
context.Background(),
525528
common.NewRateLimitRequest("reload", [][][2]string{{{getCacheKey("block", enable_local_cache), "foo"}}}, 1))
526-
assert.Equal(
529+
common.AssertProtoEqual(
530+
assert,
527531
&pb.RateLimitResponse{
528532
OverallCode: pb.RateLimitResponse_OK,
529533
Statuses: []*pb.RateLimitResponse_DescriptorStatus{{Code: pb.RateLimitResponse_OK}}},
@@ -577,7 +581,8 @@ func testConfigReload(grpcPort, perSecond string, local_cache_size string) func(
577581
response, err = c.ShouldRateLimit(
578582
context.Background(),
579583
common.NewRateLimitRequest("reload", [][][2]string{{{getCacheKey("key1", enable_local_cache), "foo"}}}, 1))
580-
assert.Equal(
584+
common.AssertProtoEqual(
585+
assert,
581586
&pb.RateLimitResponse{
582587
OverallCode: pb.RateLimitResponse_OK,
583588
Statuses: []*pb.RateLimitResponse_DescriptorStatus{

test/service/ratelimit_legacy_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ func convertRatelimit(ratelimit *pb.RateLimitResponse_RateLimit) (*pb_legacy.Rat
2525
}
2626

2727
return &pb_legacy.RateLimitResponse_RateLimit{
28+
Name: ratelimit.GetName(),
2829
RequestsPerUnit: ratelimit.GetRequestsPerUnit(),
2930
Unit: pb_legacy.RateLimitResponse_RateLimit_Unit(ratelimit.GetUnit()),
3031
}, nil

0 commit comments

Comments
 (0)