github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/internal/wrr/wrr_test.go (about)

     1  /*
     2   *
     3   * Copyright 2019 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  
    18  package wrr
    19  
    20  import (
    21  	"errors"
    22  	"math"
    23  	"math/rand"
    24  	"testing"
    25  
    26  	"github.com/google/go-cmp/cmp"
    27  	"github.com/hxx258456/ccgo/grpc/internal/grpctest"
    28  )
    29  
    30  type s struct {
    31  	grpctest.Tester
    32  }
    33  
    34  func Test(t *testing.T) {
    35  	grpctest.RunSubTests(t, s{})
    36  }
    37  
    38  const iterCount = 10000
    39  
    40  func equalApproximate(a, b float64) error {
    41  	opt := cmp.Comparer(func(x, y float64) bool {
    42  		delta := math.Abs(x - y)
    43  		mean := math.Abs(x+y) / 2.0
    44  		return delta/mean < 0.05
    45  	})
    46  	if !cmp.Equal(a, b, opt) {
    47  		return errors.New(cmp.Diff(a, b))
    48  	}
    49  	return nil
    50  }
    51  
    52  func testWRRNext(t *testing.T, newWRR func() WRR) {
    53  	tests := []struct {
    54  		name    string
    55  		weights []int64
    56  	}{
    57  		{
    58  			name:    "1-1-1",
    59  			weights: []int64{1, 1, 1},
    60  		},
    61  		{
    62  			name:    "1-2-3",
    63  			weights: []int64{1, 2, 3},
    64  		},
    65  		{
    66  			name:    "5-3-2",
    67  			weights: []int64{5, 3, 2},
    68  		},
    69  		{
    70  			name:    "17-23-37",
    71  			weights: []int64{17, 23, 37},
    72  		},
    73  	}
    74  	for _, tt := range tests {
    75  		t.Run(tt.name, func(t *testing.T) {
    76  			var sumOfWeights int64
    77  
    78  			w := newWRR()
    79  			for i, weight := range tt.weights {
    80  				w.Add(i, weight)
    81  				sumOfWeights += weight
    82  			}
    83  
    84  			results := make(map[int]int)
    85  			for i := 0; i < iterCount; i++ {
    86  				results[w.Next().(int)]++
    87  			}
    88  
    89  			wantRatio := make([]float64, len(tt.weights))
    90  			for i, weight := range tt.weights {
    91  				wantRatio[i] = float64(weight) / float64(sumOfWeights)
    92  			}
    93  			gotRatio := make([]float64, len(tt.weights))
    94  			for i, count := range results {
    95  				gotRatio[i] = float64(count) / iterCount
    96  			}
    97  
    98  			for i := range wantRatio {
    99  				if err := equalApproximate(gotRatio[i], wantRatio[i]); err != nil {
   100  					t.Errorf("%v not equal %v", i, err)
   101  				}
   102  			}
   103  		})
   104  	}
   105  }
   106  
   107  func (s) TestRandomWRRNext(t *testing.T) {
   108  	testWRRNext(t, NewRandom)
   109  }
   110  
   111  func (s) TestEdfWrrNext(t *testing.T) {
   112  	testWRRNext(t, NewEDF)
   113  }
   114  
   115  func init() {
   116  	r := rand.New(rand.NewSource(0))
   117  	grpcrandInt63n = r.Int63n
   118  }