github.com/hellofresh/janus@v0.0.0-20230925145208-ce8de8183c67/pkg/proxy/balancer/weight_test.go (about)

     1  package balancer
     2  
     3  import (
     4  	"fmt"
     5  	"math"
     6  	"testing"
     7  
     8  	"github.com/stretchr/testify/suite"
     9  )
    10  
    11  type WeightBalancerTestSuite struct {
    12  	suite.Suite
    13  	hosts []*Target
    14  }
    15  
    16  func (suite *WeightBalancerTestSuite) SetupTest() {
    17  	suite.hosts = []*Target{
    18  		{Target: "127.0.0.1", Weight: 5},
    19  		{Target: "http://test.com", Weight: 10},
    20  		{Target: "http://example.com", Weight: 8},
    21  	}
    22  }
    23  
    24  func (suite *WeightBalancerTestSuite) TestWeightBalancer() {
    25  	balancer := NewWeightBalancer()
    26  
    27  	electedHost, err := balancer.Elect(suite.hosts)
    28  	suite.NoError(err)
    29  	suite.NotNil(electedHost)
    30  }
    31  
    32  func (suite *WeightBalancerTestSuite) TestWeightBalancerEmptyList() {
    33  	balancer := NewWeightBalancer()
    34  
    35  	_, err := balancer.Elect([]*Target{})
    36  	suite.Error(err)
    37  }
    38  
    39  func (suite *WeightBalancerTestSuite) TestWeightBalancerZeroWeight() {
    40  	balancer := NewWeightBalancer()
    41  
    42  	_, err := balancer.Elect([]*Target{{Target: "", Weight: 0}})
    43  	suite.Error(err)
    44  }
    45  
    46  func (suite *WeightBalancerTestSuite) TestWeightBalancerZeroWeightForOneTarget() {
    47  	balancer := NewWeightBalancer()
    48  
    49  	hosts := []*Target{
    50  		{Target: "127.0.0.1", Weight: 0},
    51  		{Target: "http://test.com", Weight: 100},
    52  	}
    53  
    54  	electedHost, err := balancer.Elect(hosts)
    55  	suite.NoError(err)
    56  	suite.Equal(hosts[1], electedHost)
    57  }
    58  
    59  func (suite *WeightBalancerTestSuite) TestWeightBalancerWeight() {
    60  	balancer := NewWeightBalancer()
    61  
    62  	totalSteps := 10000
    63  	percentDiffMax := 15
    64  
    65  	for _, weights := range []struct {
    66  		weight0 int
    67  		weight1 int
    68  	}{{50, 50}, {80, 20}, {85, 15}, {90, 15}, {20, 80}, {30, 70}, {5, 95}} {
    69  		hosts := []*Target{
    70  			{Target: "127.0.0.1", Weight: weights.weight0},
    71  			{Target: "http://test.com", Weight: weights.weight1},
    72  		}
    73  		shouldElect0 := totalSteps * weights.weight0 / 100
    74  		shouldElect1 := totalSteps * weights.weight1 / 100
    75  
    76  		volatility0 := shouldElect0 * percentDiffMax / 100
    77  		volatility1 := shouldElect1 * percentDiffMax / 100
    78  
    79  		elected0 := 0
    80  		elected1 := 0
    81  		for i := 0; i < totalSteps; i++ {
    82  			electedHost, err := balancer.Elect(hosts)
    83  			suite.NoError(err)
    84  
    85  			if electedHost == hosts[0] {
    86  				elected0++
    87  			} else {
    88  				elected1++
    89  			}
    90  		}
    91  
    92  		electedDiff0 := int(math.Abs(float64(elected0 - shouldElect0)))
    93  		suite.True(
    94  			electedDiff0 < volatility0,
    95  			fmt.Sprintf(
    96  				"totalSteps: %d; percentDiffMax: %d; weight0: %d; shouldElect0: %d; elected0: %d; volatility0: %d; electedDiff0: %d",
    97  				totalSteps, percentDiffMax, weights.weight0, shouldElect0, elected0, volatility0, electedDiff0,
    98  			),
    99  		)
   100  
   101  		electedDiff1 := int(math.Abs(float64(elected1 - shouldElect1)))
   102  		suite.True(
   103  			electedDiff1 < volatility1,
   104  			fmt.Sprintf(
   105  				"totalSteps: %d; percentDiffMax: %d; weight1: %d; shouldElect1: %d; elected1: %d; volatility1: %d; electedDiff1: %d",
   106  				totalSteps, percentDiffMax, weights.weight1, shouldElect1, elected1, volatility1, electedDiff1,
   107  			),
   108  		)
   109  	}
   110  }
   111  
   112  // In order for 'go test' to run this suite, we need to create
   113  // a normal test function and pass our suite to suite.Run
   114  func TestWeightBalancerTestSuiteTestSuite(t *testing.T) {
   115  	suite.Run(t, new(WeightBalancerTestSuite))
   116  }