2021-06-18 11:09:43 +00:00
|
|
|
package pool
|
|
|
|
|
|
|
|
import (
|
2021-06-21 11:12:08 +00:00
|
|
|
"context"
|
2021-06-18 11:09:43 +00:00
|
|
|
"math/rand"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestSamplerStability(t *testing.T) {
|
|
|
|
const COUNT = 100000
|
|
|
|
|
|
|
|
cases := []struct {
|
|
|
|
probabilities []float64
|
|
|
|
expected []int
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
probabilities: []float64{1, 0},
|
|
|
|
expected: []int{COUNT, 0},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
probabilities: []float64{0.1, 0.2, 0.7},
|
|
|
|
expected: []int{10138, 19813, 70049},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
probabilities: []float64{0.2, 0.2, 0.4, 0.1, 0.1, 0},
|
|
|
|
expected: []int{19824, 20169, 39900, 10243, 9864, 0},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
2022-03-11 11:57:35 +00:00
|
|
|
sampler := newSampler(tc.probabilities, rand.NewSource(0))
|
2021-06-18 11:09:43 +00:00
|
|
|
res := make([]int, len(tc.probabilities))
|
|
|
|
for i := 0; i < COUNT; i++ {
|
|
|
|
res[sampler.Next()]++
|
|
|
|
}
|
|
|
|
|
|
|
|
require.Equal(t, tc.expected, res, "probabilities: %v", tc.probabilities)
|
|
|
|
}
|
|
|
|
}
|
2021-06-21 11:12:08 +00:00
|
|
|
|
|
|
|
func TestHealthyReweight(t *testing.T) {
|
|
|
|
var (
|
|
|
|
weights = []float64{0.9, 0.1}
|
|
|
|
names = []string{"node0", "node1"}
|
|
|
|
buffer = make([]float64, len(weights))
|
|
|
|
)
|
|
|
|
|
2022-03-11 11:57:35 +00:00
|
|
|
cache, err := newCache()
|
2021-11-08 13:28:28 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
2022-11-03 14:58:38 +00:00
|
|
|
client1 := newMockClient(names[0], *newPrivateKey(t))
|
|
|
|
client1.errOnDial()
|
|
|
|
|
|
|
|
client2 := newMockClient(names[1], *newPrivateKey(t))
|
|
|
|
|
2021-11-16 13:50:33 +00:00
|
|
|
inner := &innerPool{
|
2022-03-11 11:57:35 +00:00
|
|
|
sampler: newSampler(weights, rand.NewSource(0)),
|
2022-11-03 14:58:38 +00:00
|
|
|
clients: []client{client1, client2},
|
2021-11-16 13:50:33 +00:00
|
|
|
}
|
2022-03-09 09:40:23 +00:00
|
|
|
p := &Pool{
|
2022-03-11 14:55:02 +00:00
|
|
|
innerPools: []*innerPool{inner},
|
|
|
|
cache: cache,
|
|
|
|
key: newPrivateKey(t),
|
|
|
|
rebalanceParams: rebalanceParameters{nodesParams: []*nodesParam{{weights: weights}}},
|
2021-06-21 11:12:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// check getting first node connection before rebalance happened
|
2022-03-15 12:00:38 +00:00
|
|
|
connection0, err := p.connection()
|
2021-06-21 11:12:08 +00:00
|
|
|
require.NoError(t, err)
|
2022-11-03 14:58:38 +00:00
|
|
|
mock0 := connection0.(*mockClient)
|
|
|
|
require.Equal(t, names[0], mock0.address())
|
2021-06-21 11:12:08 +00:00
|
|
|
|
2022-03-11 14:55:02 +00:00
|
|
|
p.updateInnerNodesHealth(context.TODO(), 0, buffer)
|
2021-06-21 11:12:08 +00:00
|
|
|
|
2022-03-15 12:00:38 +00:00
|
|
|
connection1, err := p.connection()
|
2021-06-21 11:12:08 +00:00
|
|
|
require.NoError(t, err)
|
2022-11-03 14:58:38 +00:00
|
|
|
mock1 := connection1.(*mockClient)
|
|
|
|
require.Equal(t, names[1], mock1.address())
|
2021-06-21 11:12:08 +00:00
|
|
|
|
|
|
|
// enabled first node again
|
2021-11-16 13:50:33 +00:00
|
|
|
inner.lock.Lock()
|
2022-11-03 14:58:38 +00:00
|
|
|
inner.clients[0] = newMockClient(names[0], *newPrivateKey(t))
|
2021-11-16 13:50:33 +00:00
|
|
|
inner.lock.Unlock()
|
2021-06-21 11:12:08 +00:00
|
|
|
|
2022-03-11 14:55:02 +00:00
|
|
|
p.updateInnerNodesHealth(context.TODO(), 0, buffer)
|
2022-03-11 11:57:35 +00:00
|
|
|
inner.sampler = newSampler(weights, rand.NewSource(0))
|
2021-06-21 11:12:08 +00:00
|
|
|
|
2022-03-15 12:00:38 +00:00
|
|
|
connection0, err = p.connection()
|
2021-06-21 11:12:08 +00:00
|
|
|
require.NoError(t, err)
|
2022-11-03 14:58:38 +00:00
|
|
|
mock0 = connection0.(*mockClient)
|
|
|
|
require.Equal(t, names[0], mock0.address())
|
2021-06-21 11:12:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestHealthyNoReweight(t *testing.T) {
|
|
|
|
var (
|
|
|
|
weights = []float64{0.9, 0.1}
|
|
|
|
names = []string{"node0", "node1"}
|
|
|
|
buffer = make([]float64, len(weights))
|
|
|
|
)
|
|
|
|
|
2022-07-12 18:57:33 +00:00
|
|
|
sampl := newSampler(weights, rand.NewSource(0))
|
2021-11-16 13:50:33 +00:00
|
|
|
inner := &innerPool{
|
2022-07-12 18:57:33 +00:00
|
|
|
sampler: sampl,
|
|
|
|
clients: []client{
|
2022-11-03 14:58:38 +00:00
|
|
|
newMockClient(names[0], *newPrivateKey(t)),
|
|
|
|
newMockClient(names[1], *newPrivateKey(t)),
|
2022-07-12 18:57:33 +00:00
|
|
|
},
|
2021-06-21 11:12:08 +00:00
|
|
|
}
|
2022-03-09 09:40:23 +00:00
|
|
|
p := &Pool{
|
2022-03-11 14:55:02 +00:00
|
|
|
innerPools: []*innerPool{inner},
|
|
|
|
rebalanceParams: rebalanceParameters{nodesParams: []*nodesParam{{weights: weights}}},
|
2021-11-16 13:50:33 +00:00
|
|
|
}
|
2021-06-21 11:12:08 +00:00
|
|
|
|
2022-03-11 14:55:02 +00:00
|
|
|
p.updateInnerNodesHealth(context.TODO(), 0, buffer)
|
2021-06-21 11:12:08 +00:00
|
|
|
|
2021-11-16 13:50:33 +00:00
|
|
|
inner.lock.RLock()
|
|
|
|
defer inner.lock.RUnlock()
|
2022-07-12 18:57:33 +00:00
|
|
|
require.Equal(t, inner.sampler, sampl)
|
2021-06-21 11:12:08 +00:00
|
|
|
}
|