| /* |
| * |
| * Copyright 2019 gRPC authors. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package wrr |
| |
| import ( |
| "errors" |
| "math" |
| "math/rand" |
| "testing" |
| |
| "github.com/google/go-cmp/cmp" |
| ) |
| |
| const iterCount = 10000 |
| |
| func equalApproximate(a, b float64) error { |
| opt := cmp.Comparer(func(x, y float64) bool { |
| delta := math.Abs(x - y) |
| mean := math.Abs(x+y) / 2.0 |
| return delta/mean < 0.05 |
| }) |
| if !cmp.Equal(a, b, opt) { |
| return errors.New(cmp.Diff(a, b)) |
| } |
| return nil |
| } |
| |
| func testWRRNext(t *testing.T, newWRR func() WRR) { |
| tests := []struct { |
| name string |
| weights []int64 |
| }{ |
| { |
| name: "1-1-1", |
| weights: []int64{1, 1, 1}, |
| }, |
| { |
| name: "1-2-3", |
| weights: []int64{1, 2, 3}, |
| }, |
| { |
| name: "5-3-2", |
| weights: []int64{5, 3, 2}, |
| }, |
| { |
| name: "17-23-37", |
| weights: []int64{17, 23, 37}, |
| }, |
| } |
| for _, tt := range tests { |
| t.Run(tt.name, func(t *testing.T) { |
| var sumOfWeights int64 |
| |
| w := newWRR() |
| for i, weight := range tt.weights { |
| w.Add(i, weight) |
| sumOfWeights += weight |
| } |
| |
| results := make(map[int]int) |
| for i := 0; i < iterCount; i++ { |
| results[w.Next().(int)]++ |
| } |
| |
| wantRatio := make([]float64, len(tt.weights)) |
| for i, weight := range tt.weights { |
| wantRatio[i] = float64(weight) / float64(sumOfWeights) |
| } |
| gotRatio := make([]float64, len(tt.weights)) |
| for i, count := range results { |
| gotRatio[i] = float64(count) / iterCount |
| } |
| |
| for i := range wantRatio { |
| if err := equalApproximate(gotRatio[i], wantRatio[i]); err != nil { |
| t.Errorf("%v not equal %v", i, err) |
| } |
| } |
| }) |
| } |
| } |
| |
| func TestRandomWRRNext(t *testing.T) { |
| testWRRNext(t, NewRandom) |
| } |
| |
| func TestEdfWrrNext(t *testing.T) { |
| testWRRNext(t, NewEDF) |
| } |
| |
| func init() { |
| r := rand.New(rand.NewSource(0)) |
| grpcrandInt63n = r.Int63n |
| } |