github.com/cloudwego/hertz@v0.9.3/pkg/app/client/loadbalance/weight_random_test.go (about) 1 /* 2 * Copyright 2022 CloudWeGo Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package loadbalance 18 19 import ( 20 "math" 21 "testing" 22 23 "github.com/cloudwego/hertz/pkg/app/client/discovery" 24 "github.com/cloudwego/hertz/pkg/common/test/assert" 25 ) 26 27 func TestWeightedBalancer(t *testing.T) { 28 balancer := NewWeightedBalancer() 29 // nil 30 ins := balancer.Pick(discovery.Result{}) 31 assert.DeepEqual(t, ins, nil) 32 33 // empty instance 34 e := discovery.Result{ 35 Instances: make([]discovery.Instance, 0), 36 CacheKey: "a", 37 } 38 balancer.Rebalance(e) 39 ins = balancer.Pick(e) 40 assert.DeepEqual(t, ins, nil) 41 42 // one instance 43 insList := []discovery.Instance{ 44 discovery.NewInstance("tcp", "127.0.0.1:8888", 20, nil), 45 } 46 e = discovery.Result{ 47 Instances: insList, 48 CacheKey: "b", 49 } 50 balancer.Rebalance(e) 51 for i := 0; i < 100; i++ { 52 ins = balancer.Pick(e) 53 assert.DeepEqual(t, ins.Weight(), 20) 54 } 55 56 // multi instances, weightSum > 0 57 insList = []discovery.Instance{ 58 discovery.NewInstance("tcp", "127.0.0.1:8881", 10, nil), 59 discovery.NewInstance("tcp", "127.0.0.1:8882", 20, nil), 60 discovery.NewInstance("tcp", "127.0.0.1:8883", 50, nil), 61 discovery.NewInstance("tcp", "127.0.0.1:8884", 100, nil), 62 discovery.NewInstance("tcp", "127.0.0.1:8885", 200, nil), 63 discovery.NewInstance("tcp", "127.0.0.1:8886", 500, nil), 64 } 65 66 var weightSum int 67 for _, ins := range insList { 68 weight := ins.Weight() 69 weightSum += weight 70 } 71 72 n := 10000000 73 pickedStat := map[int]int{} 74 e = discovery.Result{ 75 Instances: insList, 76 CacheKey: "c", 77 } 78 balancer.Rebalance(e) 79 for i := 0; i < n; i++ { 80 ins = balancer.Pick(e) 81 weight := ins.Weight() 82 if pickedCnt, ok := pickedStat[weight]; ok { 83 pickedStat[weight] = pickedCnt + 1 84 } else { 85 pickedStat[weight] = 1 86 } 87 } 88 89 for _, ins := range insList { 90 weight := ins.Weight() 91 expect := float64(weight) / float64(weightSum) * float64(n) 92 actual := float64(pickedStat[weight]) 93 delta := math.Abs(expect - actual) 94 assert.DeepEqual(t, true, delta/expect < 0.01) 95 } 96 97 // have instances that weight < 0 98 insList = []discovery.Instance{ 99 discovery.NewInstance("tcp", "127.0.0.1:8881", 10, nil), 100 discovery.NewInstance("tcp", "127.0.0.1:8882", -10, nil), 101 } 102 e = discovery.Result{ 103 Instances: insList, 104 CacheKey: "d", 105 } 106 balancer.Rebalance(e) 107 for i := 0; i < 1000; i++ { 108 ins = balancer.Pick(e) 109 assert.DeepEqual(t, 10, ins.Weight()) 110 } 111 }