github.com/polarismesh/polaris@v1.17.8/plugin/ratelimit/token/api_limit_test.go (about)

     1  /**
     2   * Tencent is pleased to support the open source community by making Polaris available.
     3   *
     4   * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved.
     5   *
     6   * Licensed under the BSD 3-Clause License (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at
     9   *
    10   * https://opensource.org/licenses/BSD-3-Clause
    11   *
    12   * Unless required by applicable law or agreed to in writing, software distributed
    13   * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
    14   * CONDITIONS OF ANY KIND, either express or implied. See the License for the
    15   * specific language governing permissions and limitations under the License.
    16   */
    17  
    18  package token
    19  
    20  import (
    21  	"testing"
    22  	"time"
    23  
    24  	. "github.com/smartystreets/goconvey/convey"
    25  )
    26  
    27  // newAPIRateLimitCheck 校验新建apiRate
    28  func newAPIRateLimitCheck(t *testing.T, config *APILimitConfig) *apiRatelimit {
    29  	apiLimit, err := newAPIRatelimit(config)
    30  	if err != nil {
    31  		t.Fatalf("error: %s", err.Error())
    32  	}
    33  	return apiLimit
    34  }
    35  
    36  // TestAPIRateLimitAllow 正常场景测试
    37  func TestAPIRateLimitAllow(t *testing.T) {
    38  	config := &APILimitConfig{
    39  		Open: true,
    40  		Rules: []*RateLimitRule{
    41  			{Name: "rule-a", Limit: &BucketRatelimit{true, 10, 2}},
    42  			{Name: "rule-b", Limit: &BucketRatelimit{true, 10, 1}},
    43  			{Name: "rule-c", Limit: &BucketRatelimit{Open: false}},
    44  		},
    45  		Apis: []*APILimitInfo{
    46  			{Name: "api1", Rule: "rule-a"},
    47  			{Name: "api2", Rule: "rule-b"},
    48  			{Name: "api3", Rule: "rule-c"},
    49  		},
    50  	}
    51  	limiter := newAPIRateLimitCheck(t, config)
    52  	Convey("正常请求,令牌桶限流可以生效", t, func() {
    53  		allowCnt := 0
    54  		for i := 0; i < limiter.rules["rule-a"].Bucket*2; i++ {
    55  			if ok := limiter.allow("api1"); ok {
    56  				allowCnt++
    57  			}
    58  		}
    59  		So(allowCnt, ShouldEqual, limiter.rules["rule-a"].Bucket)
    60  	})
    61  	Convey("持续请求,不超过限制,可以一直请求下去", t, func() {
    62  		for i := 0; i < 15; i++ {
    63  			So(limiter.allow("api2"), ShouldEqual, true)
    64  			time.Sleep(time.Millisecond*1 + time.Second)
    65  		}
    66  	})
    67  	Convey("api不限制,可以随便请求", t, func() {
    68  		for i := 0; i < limiter.rules["rule-c"].Bucket*2; i++ {
    69  			So(limiter.allow("api3"), ShouldEqual, true)
    70  		}
    71  	})
    72  	Convey("api不存在rule,不做限制", t, func() {
    73  		cnt := 0
    74  		for i := 0; i < 10000; i++ {
    75  			cnt++
    76  		}
    77  		So(cnt, ShouldEqual, 10000)
    78  	})
    79  }
    80  
    81  // TestAPILimitConfig 配置校验
    82  func TestAPILimitConfig(t *testing.T) {
    83  	Convey("api-limit配置为空,可以正常执行", t, func() {
    84  		limiter := newAPIRateLimitCheck(t, nil)
    85  		So(limiter, ShouldNotBeNil)
    86  		So(limiter.isOpen(), ShouldEqual, false)
    87  	})
    88  	Convey("可以通过系统open开关,关闭api限流", t, func() {
    89  		config := &APILimitConfig{
    90  			Open: false,
    91  			Rules: []*RateLimitRule{
    92  				{Name: "rule-1",
    93  					Limit: &BucketRatelimit{Open: true, Bucket: 10, Rate: 5}},
    94  			},
    95  			Apis: []*APILimitInfo{{Name: "api-1", Rule: "rule-1"}},
    96  		}
    97  		limiter := newAPIRateLimitCheck(t, config)
    98  		So(limiter.isOpen(), ShouldEqual, false)
    99  		for i := 0; i < 15; i++ {
   100  			So(limiter.allow("api-1"), ShouldEqual, true)
   101  		}
   102  	})
   103  	Convey("rules为空,报错", t, func() {
   104  		config := &APILimitConfig{Open: true}
   105  		limiter, err := newAPIRatelimit(config)
   106  		So(err, ShouldNotBeNil)
   107  		So(limiter, ShouldBeNil)
   108  	})
   109  	Convey("api为空,报错", t, func() {
   110  		config := &APILimitConfig{
   111  			Open: true,
   112  			Rules: []*RateLimitRule{
   113  				{Name: "rule-1",
   114  					Limit: &BucketRatelimit{Open: true, Bucket: 10, Rate: 5}},
   115  			},
   116  			Apis: []*APILimitInfo{},
   117  		}
   118  		_, err := newAPIRatelimit(config)
   119  		So(err, ShouldNotBeNil)
   120  	})
   121  }
   122  
   123  // TestAPILimitConfigRule api-limit规则配置测试
   124  func TestAPILimitConfigRule(t *testing.T) {
   125  	config := &APILimitConfig{
   126  		Open: true,
   127  		Apis: []*APILimitInfo{{Name: "api-1", Rule: "rule-1"}},
   128  	}
   129  	Convey("rules内部参数,name不能为空", t, func() {
   130  		config.Rules = []*RateLimitRule{
   131  			{Name: "",
   132  				Limit: &BucketRatelimit{Open: true, Bucket: 0, Rate: 5}},
   133  		}
   134  		_, err := newAPIRatelimit(config)
   135  		So(err, ShouldNotBeNil)
   136  	})
   137  	Convey("rules内部参数,limit不能为空", t, func() {
   138  		config.Rules = []*RateLimitRule{
   139  			{Name: "rule-1", Limit: nil},
   140  		}
   141  		_, err := newAPIRatelimit(config)
   142  		So(err, ShouldNotBeNil)
   143  	})
   144  	Convey("rules内部参数,open为false,bucket和rate可以是任意值", t, func() {
   145  		config.Rules = []*RateLimitRule{
   146  			{Name: "",
   147  				Limit: &BucketRatelimit{Open: false}},
   148  		}
   149  		_, err := newAPIRatelimit(config)
   150  		So(err, ShouldNotBeNil)
   151  	})
   152  	Convey("rules内部参数,open的规则,bucket和rate必须大于0", t, func() {
   153  		config.Rules = []*RateLimitRule{
   154  			{Name: "rule-1",
   155  				Limit: &BucketRatelimit{Open: true, Bucket: 0, Rate: 5}},
   156  		}
   157  		_, err := newAPIRatelimit(config)
   158  		So(err, ShouldNotBeNil)
   159  		t.Logf("%s", err.Error())
   160  
   161  		config.Rules[0].Limit.Bucket = 10
   162  		config.Rules[0].Limit.Rate = 0
   163  		_, err = newAPIRatelimit(config)
   164  		So(err, ShouldNotBeNil)
   165  		t.Logf("%s", err.Error())
   166  	})
   167  }
   168  
   169  // TestAPILimitConfigApi apis配置测试
   170  func TestAPILimitConfigApi(t *testing.T) {
   171  	config := &APILimitConfig{
   172  		Open: true,
   173  		Rules: []*RateLimitRule{
   174  			{Name: "rule-1",
   175  				Limit: &BucketRatelimit{Open: true, Bucket: 10, Rate: 5}},
   176  		},
   177  	}
   178  	Convey("apis内部参数,apis为空,返回错误", t, func() {
   179  		_, err := newAPIRatelimit(config)
   180  		So(err, ShouldNotBeNil)
   181  		t.Logf("%s", err.Error())
   182  	})
   183  	Convey("apis内部参数,部分参数为空,返回错误", t, func() {
   184  		config.Apis = []*APILimitInfo{{Name: "", Rule: ""}}
   185  		_, err := newAPIRatelimit(config)
   186  		So(err, ShouldNotBeNil)
   187  		t.Logf("%s", err.Error())
   188  
   189  		config.Apis[0].Name = "123"
   190  		_, err = newAPIRatelimit(config)
   191  		So(err, ShouldNotBeNil)
   192  		t.Logf("%s", err.Error())
   193  
   194  		config.Apis[0].Rule = "rule-1"
   195  		newAPIRateLimitCheck(t, config)
   196  	})
   197  	Convey("api内部参数,rule不存在,返回错误", t, func() {
   198  		config.Apis = []*APILimitInfo{{Name: "aaa", Rule: "bbb"}}
   199  		_, err := newAPIRatelimit(config)
   200  		So(err, ShouldNotBeNil)
   201  		t.Logf("%s", err.Error())
   202  
   203  		config.Apis[0].Rule = "rule-1"
   204  		newAPIRateLimitCheck(t, config)
   205  	})
   206  }