[#283] pool: Drop gomock

Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
Denis Kirillov 2022-07-12 21:57:33 +03:00 committed by fyrchik
parent e6cb5f2ee1
commit 9d3a1835d1
5 changed files with 344 additions and 529 deletions

1
go.mod
View file

@ -4,7 +4,6 @@ go 1.16
require (
github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210521073959-f0d4d129b7f1
github.com/golang/mock v1.5.0
github.com/google/uuid v1.2.0
github.com/hashicorp/golang-lru v0.5.4
github.com/mr-tron/base58 v1.2.0

BIN
go.sum

Binary file not shown.

View file

@ -1,279 +1,173 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: pool.go
// Package pool is a generated GoMock package.
package pool
import (
context "context"
reflect "reflect"
"context"
"crypto/ecdsa"
"errors"
gomock "github.com/golang/mock/gomock"
accounting "github.com/nspcc-dev/neofs-sdk-go/accounting"
container "github.com/nspcc-dev/neofs-sdk-go/container"
id "github.com/nspcc-dev/neofs-sdk-go/container/id"
eacl "github.com/nspcc-dev/neofs-sdk-go/eacl"
netmap "github.com/nspcc-dev/neofs-sdk-go/netmap"
object "github.com/nspcc-dev/neofs-sdk-go/object"
id0 "github.com/nspcc-dev/neofs-sdk-go/object/id"
"github.com/google/uuid"
sessionv2 "github.com/nspcc-dev/neofs-api-go/v2/session"
"github.com/nspcc-dev/neofs-sdk-go/accounting"
"github.com/nspcc-dev/neofs-sdk-go/container"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa"
"github.com/nspcc-dev/neofs-sdk-go/eacl"
"github.com/nspcc-dev/neofs-sdk-go/netmap"
"github.com/nspcc-dev/neofs-sdk-go/object"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
"github.com/nspcc-dev/neofs-sdk-go/session"
"go.uber.org/atomic"
)
// MockClient is a mock of client interface.
type MockClient struct {
ctrl *gomock.Controller
recorder *MockClientMockRecorder
type mockClient struct {
key ecdsa.PrivateKey
addr string
healthy *atomic.Bool
errorCount *atomic.Uint32
errorOnCreateSession bool
errorOnEndpointInfo bool
errorOnNetworkInfo bool
errorOnGetObject error
}
// MockClientMockRecorder is the mock recorder for MockClient.
type MockClientMockRecorder struct {
mock *MockClient
func newMockClient(addr string, key ecdsa.PrivateKey) *mockClient {
return &mockClient{
key: key,
addr: addr,
healthy: atomic.NewBool(true),
errorCount: atomic.NewUint32(0),
}
}
// NewMockClient creates a new mock instance.
func NewMockClient(ctrl *gomock.Controller) *MockClient {
mock := &MockClient{ctrl: ctrl}
mock.recorder = &MockClientMockRecorder{mock}
return mock
func (m *mockClient) errOnCreateSession() {
m.errorOnCreateSession = true
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockClient) EXPECT() *MockClientMockRecorder {
return m.recorder
func (m *mockClient) errOnEndpointInfo() {
m.errorOnEndpointInfo = true
}
// balanceGet mocks base method.
func (m *MockClient) balanceGet(arg0 context.Context, arg1 PrmBalanceGet) (*accounting.Decimal, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "balanceGet", arg0, arg1)
ret0, _ := ret[0].(*accounting.Decimal)
ret1, _ := ret[1].(error)
return ret0, ret1
func (m *mockClient) errOnNetworkInfo() {
m.errorOnEndpointInfo = true
}
// balanceGet indicates an expected call of balanceGet.
func (mr *MockClientMockRecorder) balanceGet(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "balanceGet", reflect.TypeOf((*MockClient)(nil).balanceGet), arg0, arg1)
func (m *mockClient) errOnGetObject(err error) {
m.errorOnGetObject = err
}
// containerDelete mocks base method.
func (m *MockClient) containerDelete(arg0 context.Context, arg1 PrmContainerDelete) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "containerDelete", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
func newToken(key ecdsa.PrivateKey) *session.Object {
var tok session.Object
tok.SetID(uuid.New())
pk := neofsecdsa.PublicKey(key.PublicKey)
tok.SetAuthKey(&pk)
return &tok
}
// containerDelete indicates an expected call of containerDelete.
func (mr *MockClientMockRecorder) containerDelete(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "containerDelete", reflect.TypeOf((*MockClient)(nil).containerDelete), arg0, arg1)
func (m *mockClient) balanceGet(context.Context, PrmBalanceGet) (*accounting.Decimal, error) {
return nil, nil
}
// containerEACL mocks base method.
func (m *MockClient) containerEACL(arg0 context.Context, arg1 PrmContainerEACL) (*eacl.Table, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "containerEACL", arg0, arg1)
ret0, _ := ret[0].(*eacl.Table)
ret1, _ := ret[1].(error)
return ret0, ret1
func (m *mockClient) containerPut(context.Context, PrmContainerPut) (*cid.ID, error) {
return nil, nil
}
// containerEACL indicates an expected call of containerEACL.
func (mr *MockClientMockRecorder) containerEACL(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "containerEACL", reflect.TypeOf((*MockClient)(nil).containerEACL), arg0, arg1)
func (m *mockClient) containerGet(context.Context, PrmContainerGet) (*container.Container, error) {
return nil, nil
}
// containerGet mocks base method.
func (m *MockClient) containerGet(arg0 context.Context, arg1 PrmContainerGet) (*container.Container, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "containerGet", arg0, arg1)
ret0, _ := ret[0].(*container.Container)
ret1, _ := ret[1].(error)
return ret0, ret1
func (m *mockClient) containerList(context.Context, PrmContainerList) ([]cid.ID, error) {
return nil, nil
}
// containerGet indicates an expected call of containerGet.
func (mr *MockClientMockRecorder) containerGet(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "containerGet", reflect.TypeOf((*MockClient)(nil).containerGet), arg0, arg1)
func (m *mockClient) containerDelete(context.Context, PrmContainerDelete) error {
return nil
}
// containerList mocks base method.
func (m *MockClient) containerList(arg0 context.Context, arg1 PrmContainerList) ([]id.ID, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "containerList", arg0, arg1)
ret0, _ := ret[0].([]id.ID)
ret1, _ := ret[1].(error)
return ret0, ret1
func (m *mockClient) containerEACL(context.Context, PrmContainerEACL) (*eacl.Table, error) {
return nil, nil
}
// containerList indicates an expected call of containerList.
func (mr *MockClientMockRecorder) containerList(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "containerList", reflect.TypeOf((*MockClient)(nil).containerList), arg0, arg1)
func (m *mockClient) containerSetEACL(context.Context, PrmContainerSetEACL) error {
return nil
}
// containerPut mocks base method.
func (m *MockClient) containerPut(arg0 context.Context, arg1 PrmContainerPut) (*id.ID, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "containerPut", arg0, arg1)
ret0, _ := ret[0].(*id.ID)
ret1, _ := ret[1].(error)
return ret0, ret1
func (m *mockClient) endpointInfo(context.Context, prmEndpointInfo) (*netmap.NodeInfo, error) {
if m.errorOnEndpointInfo {
return nil, errors.New("error")
}
var ni netmap.NodeInfo
ni.SetNetworkEndpoints(m.addr)
return &ni, nil
}
// containerPut indicates an expected call of containerPut.
func (mr *MockClientMockRecorder) containerPut(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "containerPut", reflect.TypeOf((*MockClient)(nil).containerPut), arg0, arg1)
func (m *mockClient) networkInfo(context.Context, prmNetworkInfo) (*netmap.NetworkInfo, error) {
if m.errorOnNetworkInfo {
return nil, errors.New("error")
}
var ni netmap.NetworkInfo
return &ni, nil
}
// containerSetEACL mocks base method.
func (m *MockClient) containerSetEACL(arg0 context.Context, arg1 PrmContainerSetEACL) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "containerSetEACL", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
func (m *mockClient) objectPut(context.Context, PrmObjectPut) (*oid.ID, error) {
return nil, nil
}
// containerSetEACL indicates an expected call of containerSetEACL.
func (mr *MockClientMockRecorder) containerSetEACL(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "containerSetEACL", reflect.TypeOf((*MockClient)(nil).containerSetEACL), arg0, arg1)
func (m *mockClient) objectDelete(context.Context, PrmObjectDelete) error {
return nil
}
// endpointInfo mocks base method.
func (m *MockClient) endpointInfo(arg0 context.Context, arg1 prmEndpointInfo) (*netmap.NodeInfo, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "endpointInfo", arg0, arg1)
ret0, _ := ret[0].(*netmap.NodeInfo)
ret1, _ := ret[1].(error)
return ret0, ret1
func (m *mockClient) objectGet(context.Context, PrmObjectGet) (*ResGetObject, error) {
return &ResGetObject{}, m.errorOnGetObject
}
// endpointInfo indicates an expected call of endpointInfo.
func (mr *MockClientMockRecorder) endpointInfo(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "endpointInfo", reflect.TypeOf((*MockClient)(nil).endpointInfo), arg0, arg1)
func (m *mockClient) objectHead(context.Context, PrmObjectHead) (*object.Object, error) {
return nil, nil
}
// networkInfo mocks base method.
func (m *MockClient) networkInfo(arg0 context.Context, arg1 prmNetworkInfo) (*netmap.NetworkInfo, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "networkInfo", arg0, arg1)
ret0, _ := ret[0].(*netmap.NetworkInfo)
ret1, _ := ret[1].(error)
return ret0, ret1
func (m *mockClient) objectRange(context.Context, PrmObjectRange) (*ResObjectRange, error) {
return nil, nil
}
// networkInfo indicates an expected call of networkInfo.
func (mr *MockClientMockRecorder) networkInfo(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "networkInfo", reflect.TypeOf((*MockClient)(nil).networkInfo), arg0, arg1)
func (m *mockClient) objectSearch(context.Context, PrmObjectSearch) (*ResObjectSearch, error) {
return nil, nil
}
// objectDelete mocks base method.
func (m *MockClient) objectDelete(arg0 context.Context, arg1 PrmObjectDelete) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "objectDelete", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
func (m *mockClient) sessionCreate(context.Context, prmCreateSession) (*resCreateSession, error) {
if m.errorOnCreateSession {
return nil, errors.New("error")
}
tok := newToken(m.key)
var v2tok sessionv2.Token
tok.WriteToV2(&v2tok)
return &resCreateSession{
id: v2tok.GetBody().GetID(),
sessionKey: v2tok.GetBody().GetSessionKey(),
}, nil
}
// objectDelete indicates an expected call of objectDelete.
func (mr *MockClientMockRecorder) objectDelete(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "objectDelete", reflect.TypeOf((*MockClient)(nil).objectDelete), arg0, arg1)
func (m *mockClient) isHealthy() bool {
return m.healthy.Load()
}
// objectGet mocks base method.
func (m *MockClient) objectGet(arg0 context.Context, arg1 PrmObjectGet) (*ResGetObject, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "objectGet", arg0, arg1)
ret0, _ := ret[0].(*ResGetObject)
ret1, _ := ret[1].(error)
return ret0, ret1
func (m *mockClient) setHealthy(b bool) bool {
return m.healthy.Swap(b) != b
}
// objectGet indicates an expected call of objectGet.
func (mr *MockClientMockRecorder) objectGet(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "objectGet", reflect.TypeOf((*MockClient)(nil).objectGet), arg0, arg1)
func (m *mockClient) address() string {
return m.addr
}
// objectHead mocks base method.
func (m *MockClient) objectHead(arg0 context.Context, arg1 PrmObjectHead) (*object.Object, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "objectHead", arg0, arg1)
ret0, _ := ret[0].(*object.Object)
ret1, _ := ret[1].(error)
return ret0, ret1
func (m *mockClient) errorRate() uint32 {
return m.errorCount.Load()
}
// objectHead indicates an expected call of objectHead.
func (mr *MockClientMockRecorder) objectHead(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "objectHead", reflect.TypeOf((*MockClient)(nil).objectHead), arg0, arg1)
}
// objectPut mocks base method.
func (m *MockClient) objectPut(arg0 context.Context, arg1 PrmObjectPut) (*id0.ID, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "objectPut", arg0, arg1)
ret0, _ := ret[0].(*id0.ID)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// objectPut indicates an expected call of objectPut.
func (mr *MockClientMockRecorder) objectPut(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "objectPut", reflect.TypeOf((*MockClient)(nil).objectPut), arg0, arg1)
}
// objectRange mocks base method.
func (m *MockClient) objectRange(arg0 context.Context, arg1 PrmObjectRange) (*ResObjectRange, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "objectRange", arg0, arg1)
ret0, _ := ret[0].(*ResObjectRange)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// objectRange indicates an expected call of objectRange.
func (mr *MockClientMockRecorder) objectRange(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "objectRange", reflect.TypeOf((*MockClient)(nil).objectRange), arg0, arg1)
}
// objectSearch mocks base method.
func (m *MockClient) objectSearch(arg0 context.Context, arg1 PrmObjectSearch) (*ResObjectSearch, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "objectSearch", arg0, arg1)
ret0, _ := ret[0].(*ResObjectSearch)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// objectSearch indicates an expected call of objectSearch.
func (mr *MockClientMockRecorder) objectSearch(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "objectSearch", reflect.TypeOf((*MockClient)(nil).objectSearch), arg0, arg1)
}
// sessionCreate mocks base method.
func (m *MockClient) sessionCreate(arg0 context.Context, arg1 prmCreateSession) (*resCreateSession, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "sessionCreate", arg0, arg1)
ret0, _ := ret[0].(*resCreateSession)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// sessionCreate indicates an expected call of sessionCreate.
func (mr *MockClientMockRecorder) sessionCreate(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "sessionCreate", reflect.TypeOf((*MockClient)(nil).sessionCreate), arg0, arg1)
func (m *mockClient) resetErrorCounter() {
m.errorCount.Store(0)
}

View file

@ -1,32 +1,28 @@
package pool
//go:generate mockgen -destination mock_test.go -source pool.go -mock_names client=MockClient -package pool . client
import (
"bytes"
"context"
"crypto/ecdsa"
"errors"
"fmt"
"strconv"
"testing"
"time"
"github.com/golang/mock/gomock"
"github.com/google/uuid"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status"
"github.com/nspcc-dev/neofs-sdk-go/container"
neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa"
"github.com/nspcc-dev/neofs-sdk-go/netmap"
"github.com/nspcc-dev/neofs-sdk-go/object"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
"github.com/nspcc-dev/neofs-sdk-go/session"
"github.com/nspcc-dev/neofs-sdk-go/user"
"github.com/stretchr/testify/require"
"go.uber.org/atomic"
"go.uber.org/zap"
)
func TestBuildPoolClientFailed(t *testing.T) {
clientBuilder := func(_ string) (client, error) {
clientBuilder := func(string) (client, error) {
return nil, fmt.Errorf("error")
}
@ -43,17 +39,10 @@ func TestBuildPoolClientFailed(t *testing.T) {
}
func TestBuildPoolCreateSessionFailed(t *testing.T) {
ctrl := gomock.NewController(t)
ni := &netmap.NodeInfo{}
ni.SetNetworkEndpoints("addr1", "addr2")
clientBuilder := func(_ string) (client, error) {
mockClient := NewMockClient(ctrl)
mockClient.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("error session")).AnyTimes()
mockClient.EXPECT().endpointInfo(gomock.Any(), gomock.Any()).Return(&netmap.NodeInfo{}, nil).AnyTimes()
mockClient.EXPECT().networkInfo(gomock.Any(), gomock.Any()).Return(&netmap.NetworkInfo{}, nil).AnyTimes()
return mockClient, nil
clientBuilder := func(addr string) (client, error) {
mockCli := newMockClient(addr, *newPrivateKey(t))
mockCli.errOnCreateSession()
return mockCli, nil
}
opts := InitParameters{
@ -74,52 +63,24 @@ func newPrivateKey(t *testing.T) *ecdsa.PrivateKey {
return &p.PrivateKey
}
func newBinPublicKey(t *testing.T) []byte {
authKey := neofsecdsa.PublicKey(newPrivateKey(t).PublicKey)
bKey := make([]byte, authKey.MaxEncodedSize())
bKey = bKey[:authKey.Encode(bKey)]
return bKey
}
func TestBuildPoolOneNodeFailed(t *testing.T) {
ctrl := gomock.NewController(t)
ctrl2 := gomock.NewController(t)
nodes := []NodeParam{
{1, "peer0", 1},
{2, "peer1", 1},
}
var expectedToken *session.Object
clientCount := -1
clientBuilder := func(_ string) (client, error) {
clientCount++
mockClient := NewMockClient(ctrl)
mockClient.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).DoAndReturn(func(_, _ interface{}) (*resCreateSession, error) {
tok := newToken(t)
id := tok.ID()
return &resCreateSession{
id: id[:],
sessionKey: newBinPublicKey(t),
}, nil
}).AnyTimes()
var clientKeys []*ecdsa.PrivateKey
clientBuilder := func(addr string) (client, error) {
key := newPrivateKey(t)
clientKeys = append(clientKeys, key)
mockClient.EXPECT().endpointInfo(gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("error")).AnyTimes()
mockClient.EXPECT().networkInfo(gomock.Any(), gomock.Any()).Return(&netmap.NetworkInfo{}, nil).AnyTimes()
mockClient2 := NewMockClient(ctrl2)
mockClient2.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).DoAndReturn(func(_, _ interface{}) (*resCreateSession, error) {
expectedToken = newToken(t)
id := expectedToken.ID()
return &resCreateSession{
id: id[:],
sessionKey: newBinPublicKey(t),
}, nil
}).AnyTimes()
mockClient2.EXPECT().endpointInfo(gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes()
mockClient2.EXPECT().networkInfo(gomock.Any(), gomock.Any()).Return(&netmap.NetworkInfo{}, nil).AnyTimes()
if clientCount == 0 {
return mockClient, nil
if addr == nodes[0].address {
mockCli := newMockClient(addr, *key)
mockCli.errOnEndpointInfo()
return mockCli, nil
}
return mockClient2, nil
return newMockClient(addr, *key), nil
}
log, err := zap.NewProduction()
@ -129,10 +90,7 @@ func TestBuildPoolOneNodeFailed(t *testing.T) {
clientBuilder: clientBuilder,
clientRebalanceInterval: 1000 * time.Millisecond,
logger: log,
nodeParams: []NodeParam{
{9, "peer0", 1},
{1, "peer1", 1},
},
nodeParams: nodes,
}
clientPool, err := NewPool(opts)
@ -141,13 +99,14 @@ func TestBuildPoolOneNodeFailed(t *testing.T) {
require.NoError(t, err)
t.Cleanup(clientPool.Close)
expectedAuthKey := neofsecdsa.PublicKey(clientKeys[1].PublicKey)
condition := func() bool {
cp, err := clientPool.connection()
if err != nil {
return false
}
st, _ := clientPool.cache.Get(formCacheKey(cp.address, clientPool.key))
return areEqualTokens(&st, expectedToken)
st, _ := clientPool.cache.Get(formCacheKey(cp.address(), clientPool.key))
return st.AssertAuthKey(&expectedAuthKey)
}
require.Never(t, condition, 900*time.Millisecond, 100*time.Millisecond)
require.Eventually(t, condition, 3*time.Second, 300*time.Millisecond)
@ -162,24 +121,9 @@ func TestBuildPoolZeroNodes(t *testing.T) {
}
func TestOneNode(t *testing.T) {
ctrl := gomock.NewController(t)
uid := uuid.New()
var tok session.Object
tok.SetID(uid)
tokRes := &resCreateSession{
id: uid[:],
sessionKey: newBinPublicKey(t),
}
clientBuilder := func(_ string) (client, error) {
mockClient := NewMockClient(ctrl)
mockClient.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).Return(tokRes, nil)
mockClient.EXPECT().endpointInfo(gomock.Any(), gomock.Any()).Return(&netmap.NodeInfo{}, nil).AnyTimes()
mockClient.EXPECT().networkInfo(gomock.Any(), gomock.Any()).Return(&netmap.NetworkInfo{}, nil).AnyTimes()
return mockClient, nil
key1 := newPrivateKey(t)
clientBuilder := func(addr string) (client, error) {
return newMockClient(addr, *key1), nil
}
opts := InitParameters{
@ -196,38 +140,17 @@ func TestOneNode(t *testing.T) {
cp, err := pool.connection()
require.NoError(t, err)
st, _ := pool.cache.Get(formCacheKey(cp.address, pool.key))
require.True(t, areEqualTokens(&tok, &st))
}
func areEqualTokens(t1, t2 *session.Object) bool {
if t1 == nil || t2 == nil {
return false
}
id1, id2 := t1.ID(), t2.ID()
return bytes.Equal(id1[:], id2[:])
st, _ := pool.cache.Get(formCacheKey(cp.address(), pool.key))
expectedAuthKey := neofsecdsa.PublicKey(key1.PublicKey)
require.True(t, st.AssertAuthKey(&expectedAuthKey))
}
func TestTwoNodes(t *testing.T) {
ctrl := gomock.NewController(t)
var tokens []*session.Object
clientBuilder := func(_ string) (client, error) {
mockClient := NewMockClient(ctrl)
mockClient.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).DoAndReturn(func(_, _ interface{}) (*resCreateSession, error) {
var tok session.Object
uid := uuid.New()
tok.SetID(uid)
tokens = append(tokens, &tok)
return &resCreateSession{
id: uid[:],
sessionKey: newBinPublicKey(t),
}, nil
})
mockClient.EXPECT().endpointInfo(gomock.Any(), gomock.Any()).Return(&netmap.NodeInfo{}, nil).AnyTimes()
mockClient.EXPECT().networkInfo(gomock.Any(), gomock.Any()).Return(&netmap.NetworkInfo{}, nil).AnyTimes()
return mockClient, nil
var clientKeys []*ecdsa.PrivateKey
clientBuilder := func(addr string) (client, error) {
key := newPrivateKey(t)
clientKeys = append(clientKeys, key)
return newMockClient(addr, *key), nil
}
opts := InitParameters{
@ -247,13 +170,14 @@ func TestTwoNodes(t *testing.T) {
cp, err := pool.connection()
require.NoError(t, err)
st, _ := pool.cache.Get(formCacheKey(cp.address, pool.key))
require.True(t, containsTokens(tokens, &st))
st, _ := pool.cache.Get(formCacheKey(cp.address(), pool.key))
require.True(t, assertAuthKeyForAny(st, clientKeys))
}
func containsTokens(list []*session.Object, item *session.Object) bool {
for _, tok := range list {
if areEqualTokens(tok, item) {
func assertAuthKeyForAny(st session.Object, clientKeys []*ecdsa.PrivateKey) bool {
for _, key := range clientKeys {
expectedAuthKey := neofsecdsa.PublicKey(key.PublicKey)
if st.AssertAuthKey(&expectedAuthKey) {
return true
}
}
@ -261,55 +185,29 @@ func containsTokens(list []*session.Object, item *session.Object) bool {
}
func TestOneOfTwoFailed(t *testing.T) {
ctrl := gomock.NewController(t)
ctrl2 := gomock.NewController(t)
nodes := []NodeParam{
{1, "peer0", 1},
{9, "peer1", 1},
}
var tokens []*session.Object
clientCount := -1
clientBuilder := func(_ string) (client, error) {
clientCount++
mockClient := NewMockClient(ctrl)
mockClient.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).DoAndReturn(func(_, _ interface{}) (*resCreateSession, error) {
tok := newToken(t)
tokens = append(tokens, tok)
id := tok.ID()
return &resCreateSession{
id: id[:],
sessionKey: newBinPublicKey(t),
}, nil
}).AnyTimes()
mockClient.EXPECT().endpointInfo(gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes()
mockClient.EXPECT().networkInfo(gomock.Any(), gomock.Any()).Return(&netmap.NetworkInfo{}, nil).AnyTimes()
var clientKeys []*ecdsa.PrivateKey
clientBuilder := func(addr string) (client, error) {
key := newPrivateKey(t)
clientKeys = append(clientKeys, key)
mockClient2 := NewMockClient(ctrl2)
mockClient2.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).DoAndReturn(func(_, _ interface{}) (*resCreateSession, error) {
tok := newToken(t)
tokens = append(tokens, tok)
id := tok.ID()
return &resCreateSession{
id: id[:],
sessionKey: newBinPublicKey(t),
}, nil
}).AnyTimes()
mockClient2.EXPECT().endpointInfo(gomock.Any(), gomock.Any()).DoAndReturn(func(_ interface{}, _ ...interface{}) (*netmap.NodeInfo, error) {
return nil, fmt.Errorf("error")
}).AnyTimes()
mockClient2.EXPECT().networkInfo(gomock.Any(), gomock.Any()).DoAndReturn(func(_ interface{}, _ ...interface{}) (*netmap.NetworkInfo, error) {
return nil, fmt.Errorf("error")
}).AnyTimes()
if clientCount == 0 {
return mockClient, nil
if addr == nodes[0].address {
return newMockClient(addr, *key), nil
}
return mockClient2, nil
mockCli := newMockClient(addr, *key)
mockCli.errOnEndpointInfo()
mockCli.errOnNetworkInfo()
return mockCli, nil
}
opts := InitParameters{
key: newPrivateKey(t),
nodeParams: []NodeParam{
{1, "peer0", 1},
{9, "peer1", 1},
},
key: newPrivateKey(t),
nodeParams: nodes,
clientRebalanceInterval: 200 * time.Millisecond,
clientBuilder: clientBuilder,
}
@ -327,23 +225,19 @@ func TestOneOfTwoFailed(t *testing.T) {
for i := 0; i < 5; i++ {
cp, err := pool.connection()
require.NoError(t, err)
st, _ := pool.cache.Get(formCacheKey(cp.address, pool.key))
require.True(t, areEqualTokens(tokens[0], &st))
st, _ := pool.cache.Get(formCacheKey(cp.address(), pool.key))
require.True(t, assertAuthKeyForAny(st, clientKeys))
}
}
func TestTwoFailed(t *testing.T) {
ctrl := gomock.NewController(t)
clientBuilder := func(_ string) (client, error) {
mockClient := NewMockClient(ctrl)
mockClient.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).Return(&resCreateSession{
id: uuid.Nil[:],
sessionKey: newBinPublicKey(t),
}, nil).AnyTimes()
mockClient.EXPECT().endpointInfo(gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("error")).AnyTimes()
mockClient.EXPECT().networkInfo(gomock.Any(), gomock.Any()).Return(&netmap.NetworkInfo{}, nil).AnyTimes()
return mockClient, nil
var clientKeys []*ecdsa.PrivateKey
clientBuilder := func(addr string) (client, error) {
key := newPrivateKey(t)
clientKeys = append(clientKeys, key)
mockCli := newMockClient(addr, *key)
mockCli.errOnEndpointInfo()
return mockCli, nil
}
opts := InitParameters{
@ -371,27 +265,13 @@ func TestTwoFailed(t *testing.T) {
}
func TestSessionCache(t *testing.T) {
ctrl := gomock.NewController(t)
key := newPrivateKey(t)
expectedAuthKey := neofsecdsa.PublicKey(key.PublicKey)
var tokens []*session.Object
clientBuilder := func(_ string) (client, error) {
mockClient := NewMockClient(ctrl)
mockClient.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).DoAndReturn(func(_, _ interface{}, _ ...interface{}) (*resCreateSession, error) {
var tok session.Object
uid := uuid.New()
tok.SetID(uid)
tokens = append(tokens, &tok)
return &resCreateSession{
id: uid[:],
sessionKey: newBinPublicKey(t),
}, nil
}).MaxTimes(3)
mockClient.EXPECT().networkInfo(gomock.Any(), gomock.Any()).Return(&netmap.NetworkInfo{}, nil).AnyTimes()
mockClient.EXPECT().objectGet(gomock.Any(), gomock.Any()).Return(nil, apistatus.SessionTokenNotFound{})
mockClient.EXPECT().objectPut(gomock.Any(), gomock.Any()).Return(nil, nil)
return mockClient, nil
clientBuilder := func(addr string) (client, error) {
mockCli := newMockClient(addr, *key)
mockCli.errOnGetObject(apistatus.SessionTokenNotFound{})
return mockCli, nil
}
opts := InitParameters{
@ -415,8 +295,8 @@ func TestSessionCache(t *testing.T) {
// cache must contain session token
cp, err := pool.connection()
require.NoError(t, err)
st, _ := pool.cache.Get(formCacheKey(cp.address, pool.key))
require.True(t, containsTokens(tokens, &st))
st, _ := pool.cache.Get(formCacheKey(cp.address(), pool.key))
require.True(t, st.AssertAuthKey(&expectedAuthKey))
var prm PrmObjectGet
prm.SetAddress(oid.Address{})
@ -428,7 +308,7 @@ func TestSessionCache(t *testing.T) {
// cache must not contain session token
cp, err = pool.connection()
require.NoError(t, err)
_, ok := pool.cache.Get(formCacheKey(cp.address, pool.key))
_, ok := pool.cache.Get(formCacheKey(cp.address(), pool.key))
require.False(t, ok)
var prm2 PrmObjectPut
@ -440,54 +320,33 @@ func TestSessionCache(t *testing.T) {
// cache must contain session token
cp, err = pool.connection()
require.NoError(t, err)
st, _ = pool.cache.Get(formCacheKey(cp.address, pool.key))
require.True(t, containsTokens(tokens, &st))
st, _ = pool.cache.Get(formCacheKey(cp.address(), pool.key))
require.True(t, st.AssertAuthKey(&expectedAuthKey))
}
func TestPriority(t *testing.T) {
ctrl := gomock.NewController(t)
ctrl2 := gomock.NewController(t)
nodes := []NodeParam{
{1, "peer0", 1},
{2, "peer1", 100},
}
tokens := make([]*session.Object, 2)
clientBuilder := func(endpoint string) (client, error) {
mockClient := NewMockClient(ctrl)
mockClient.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).DoAndReturn(func(_, _ interface{}) (*resCreateSession, error) {
tok := newToken(t)
tokens[0] = tok
id := tok.ID()
return &resCreateSession{
id: id[:],
sessionKey: newBinPublicKey(t),
}, nil
}).AnyTimes()
mockClient.EXPECT().endpointInfo(gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("error")).AnyTimes()
mockClient.EXPECT().networkInfo(gomock.Any(), gomock.Any()).Return(&netmap.NetworkInfo{}, nil).AnyTimes()
var clientKeys []*ecdsa.PrivateKey
clientBuilder := func(addr string) (client, error) {
key := newPrivateKey(t)
clientKeys = append(clientKeys, key)
mockClient2 := NewMockClient(ctrl2)
mockClient2.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).DoAndReturn(func(_, _ interface{}) (*resCreateSession, error) {
tok := newToken(t)
tokens[1] = tok
id := tok.ID()
return &resCreateSession{
id: id[:],
sessionKey: newBinPublicKey(t),
}, nil
}).AnyTimes()
mockClient2.EXPECT().endpointInfo(gomock.Any(), gomock.Any()).Return(&netmap.NodeInfo{}, nil).AnyTimes()
mockClient2.EXPECT().networkInfo(gomock.Any(), gomock.Any()).Return(&netmap.NetworkInfo{}, nil).AnyTimes()
if endpoint == "peer0" {
return mockClient, nil
if addr == nodes[0].address {
mockCli := newMockClient(addr, *key)
mockCli.errOnEndpointInfo()
return mockCli, nil
}
return mockClient2, nil
return newMockClient(addr, *key), nil
}
opts := InitParameters{
key: newPrivateKey(t),
nodeParams: []NodeParam{
{1, "peer0", 1},
{2, "peer1", 100},
},
key: newPrivateKey(t),
nodeParams: nodes,
clientRebalanceInterval: 1500 * time.Millisecond,
clientBuilder: clientBuilder,
}
@ -501,17 +360,20 @@ func TestPriority(t *testing.T) {
require.NoError(t, err)
t.Cleanup(pool.Close)
expectedAuthKey1 := neofsecdsa.PublicKey(clientKeys[0].PublicKey)
firstNode := func() bool {
cp, err := pool.connection()
require.NoError(t, err)
st, _ := pool.cache.Get(formCacheKey(cp.address, pool.key))
return areEqualTokens(&st, tokens[0])
st, _ := pool.cache.Get(formCacheKey(cp.address(), pool.key))
return st.AssertAuthKey(&expectedAuthKey1)
}
expectedAuthKey2 := neofsecdsa.PublicKey(clientKeys[1].PublicKey)
secondNode := func() bool {
cp, err := pool.connection()
require.NoError(t, err)
st, _ := pool.cache.Get(formCacheKey(cp.address, pool.key))
return areEqualTokens(&st, tokens[1])
st, _ := pool.cache.Get(formCacheKey(cp.address(), pool.key))
return st.AssertAuthKey(&expectedAuthKey2)
}
require.Never(t, secondNode, time.Second, 200*time.Millisecond)
@ -520,26 +382,11 @@ func TestPriority(t *testing.T) {
}
func TestSessionCacheWithKey(t *testing.T) {
ctrl := gomock.NewController(t)
key := newPrivateKey(t)
expectedAuthKey := neofsecdsa.PublicKey(key.PublicKey)
var tokens []*session.Object
clientBuilder := func(_ string) (client, error) {
mockClient := NewMockClient(ctrl)
mockClient.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).DoAndReturn(func(_, _ interface{}) (*resCreateSession, error) {
var tok session.Object
uid := uuid.New()
tok.SetID(uid)
tokens = append(tokens, &tok)
return &resCreateSession{
id: uid[:],
sessionKey: newBinPublicKey(t),
}, nil
}).MaxTimes(2)
mockClient.EXPECT().networkInfo(gomock.Any(), gomock.Any()).Return(&netmap.NetworkInfo{}, nil).AnyTimes()
mockClient.EXPECT().objectGet(gomock.Any(), gomock.Any()).Return(nil, nil)
return mockClient, nil
clientBuilder := func(addr string) (client, error) {
return newMockClient(addr, *key), nil
}
opts := InitParameters{
@ -562,37 +409,24 @@ func TestSessionCacheWithKey(t *testing.T) {
// cache must contain session token
cp, err := pool.connection()
require.NoError(t, err)
st, _ := pool.cache.Get(formCacheKey(cp.address, pool.key))
require.True(t, containsTokens(tokens, &st))
st, _ := pool.cache.Get(formCacheKey(cp.address(), pool.key))
require.True(t, st.AssertAuthKey(&expectedAuthKey))
var prm PrmObjectGet
prm.SetAddress(oid.Address{})
prm.UseKey(newPrivateKey(t))
anonKey := newPrivateKey(t)
prm.UseKey(anonKey)
_, err = pool.GetObject(ctx, prm)
require.NoError(t, err)
require.Len(t, tokens, 2)
}
func newToken(t *testing.T) *session.Object {
var tok session.Object
tok.SetID(uuid.New())
return &tok
st, _ = pool.cache.Get(formCacheKey(cp.address(), anonKey))
require.True(t, st.AssertAuthKey(&expectedAuthKey))
}
func TestSessionTokenOwner(t *testing.T) {
t.Skip() // neofs-sdk-go#???
ctrl := gomock.NewController(t)
clientBuilder := func(_ string) (client, error) {
mockClient := NewMockClient(ctrl)
mockClient.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).Return(&resCreateSession{
id: uuid.Nil[:],
sessionKey: newBinPublicKey(t),
}, nil).AnyTimes()
mockClient.EXPECT().endpointInfo(gomock.Any(), gomock.Any()).Return(&netmap.NodeInfo{}, nil).AnyTimes()
mockClient.EXPECT().networkInfo(gomock.Any(), gomock.Any()).Return(&netmap.NetworkInfo{}, nil).AnyTimes()
return mockClient, nil
clientBuilder := func(addr string) (client, error) {
key := newPrivateKey(t)
return newMockClient(addr, *key), nil
}
opts := InitParameters{
@ -613,7 +447,6 @@ func TestSessionTokenOwner(t *testing.T) {
t.Cleanup(p.Close)
anonKey := newPrivateKey(t)
var anonOwner user.ID
user.IDFromKey(&anonOwner, anonKey.PublicKey)
@ -622,27 +455,23 @@ func TestSessionTokenOwner(t *testing.T) {
var prmCtx prmContext
prmCtx.useDefaultSession()
var tkn session.Object
var cc callContext
cc.Context = ctx
cc.sessionTarget = func(session.Object) {}
cc.sessionTarget = func(tok session.Object) {
tkn = tok
}
err = p.initCallContext(&cc, prm, prmCtx)
require.NoError(t, err)
err = p.openDefaultSession(&cc)
require.NoError(t, err)
tkn, _ := p.cache.Get(formCacheKey("peer0", anonKey))
require.True(t, tkn.VerifySignature())
require.True(t, tkn.Issuer().Equals(anonOwner))
}
func TestWaitPresence(t *testing.T) {
ctrl := gomock.NewController(t)
mockClient := NewMockClient(ctrl)
mockClient.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes()
mockClient.EXPECT().endpointInfo(gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes()
mockClient.EXPECT().networkInfo(gomock.Any(), gomock.Any()).Return(&netmap.NetworkInfo{}, nil).AnyTimes()
mockClient.EXPECT().containerGet(gomock.Any(), gomock.Any()).Return(&container.Container{}, nil).AnyTimes()
mockCli := newMockClient("", *newPrivateKey(t))
t.Run("context canceled", func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
@ -651,7 +480,7 @@ func TestWaitPresence(t *testing.T) {
cancel()
}()
err := waitForContainerPresence(ctx, mockClient, nil, &WaitParams{
err := waitForContainerPresence(ctx, mockCli, nil, &WaitParams{
timeout: 120 * time.Second,
pollInterval: 5 * time.Second,
})
@ -661,7 +490,7 @@ func TestWaitPresence(t *testing.T) {
t.Run("context deadline exceeded", func(t *testing.T) {
ctx := context.Background()
err := waitForContainerPresence(ctx, mockClient, nil, &WaitParams{
err := waitForContainerPresence(ctx, mockCli, nil, &WaitParams{
timeout: 500 * time.Millisecond,
pollInterval: 5 * time.Second,
})
@ -671,10 +500,92 @@ func TestWaitPresence(t *testing.T) {
t.Run("ok", func(t *testing.T) {
ctx := context.Background()
err := waitForContainerPresence(ctx, mockClient, nil, &WaitParams{
err := waitForContainerPresence(ctx, mockCli, nil, &WaitParams{
timeout: 10 * time.Second,
pollInterval: 500 * time.Millisecond,
})
require.NoError(t, err)
})
}
func newTestWrapper(addr string) *clientWrapper {
return &clientWrapper{
addr: addr,
healthy: atomic.NewBool(true),
errorCount: atomic.NewUint32(0),
}
}
func TestHandleError(t *testing.T) {
wrapper := newTestWrapper("")
for i, tc := range []struct {
status apistatus.Status
err error
expectedError bool
countError bool
}{
{
status: nil,
err: nil,
expectedError: false,
countError: false,
},
{
status: apistatus.SuccessDefaultV2{},
err: nil,
expectedError: false,
countError: false,
},
{
status: apistatus.SuccessDefaultV2{},
err: errors.New("error"),
expectedError: true,
countError: true,
},
{
status: nil,
err: errors.New("error"),
expectedError: true,
countError: true,
},
{
status: apistatus.ObjectNotFound{},
err: nil,
expectedError: true,
countError: false,
},
{
status: apistatus.ServerInternal{},
err: nil,
expectedError: true,
countError: true,
},
{
status: apistatus.WrongMagicNumber{},
err: nil,
expectedError: true,
countError: true,
},
{
status: apistatus.SignatureVerification{},
err: nil,
expectedError: true,
countError: true,
},
} {
t.Run(strconv.Itoa(i), func(t *testing.T) {
errCount := wrapper.errorCount.Load()
err := wrapper.handleError(tc.status, tc.err)
if tc.expectedError {
require.Error(t, err)
} else {
require.NoError(t, err)
}
if tc.countError {
errCount++
}
require.Equal(t, errCount, wrapper.errorCount.Load())
})
}
}

View file

@ -8,6 +8,7 @@ import (
"github.com/nspcc-dev/neofs-sdk-go/netmap"
"github.com/stretchr/testify/require"
"go.uber.org/atomic"
)
func TestSamplerStability(t *testing.T) {
@ -61,7 +62,15 @@ func newNetmapMock(name string, needErr bool) *clientMock {
if needErr {
err = fmt.Errorf("not available")
}
return &clientMock{name: name, err: err}
return &clientMock{
clientWrapper: clientWrapper{
addr: "",
healthy: atomic.NewBool(true),
errorCount: atomic.NewUint32(0),
},
name: name,
err: err,
}
}
func TestHealthyReweight(t *testing.T) {
@ -76,9 +85,10 @@ func TestHealthyReweight(t *testing.T) {
inner := &innerPool{
sampler: newSampler(weights, rand.NewSource(0)),
clientPacks: []*clientPack{
{client: newNetmapMock(names[0], true), healthy: true, address: "address0"},
{client: newNetmapMock(names[1], false), healthy: true, address: "address1"}},
clients: []client{
newNetmapMock(names[0], true),
newNetmapMock(names[1], false),
},
}
p := &Pool{
innerPools: []*innerPool{inner},
@ -90,19 +100,19 @@ func TestHealthyReweight(t *testing.T) {
// check getting first node connection before rebalance happened
connection0, err := p.connection()
require.NoError(t, err)
mock0 := connection0.client.(*clientMock)
mock0 := connection0.(*clientMock)
require.Equal(t, names[0], mock0.name)
p.updateInnerNodesHealth(context.TODO(), 0, buffer)
connection1, err := p.connection()
require.NoError(t, err)
mock1 := connection1.client.(*clientMock)
mock1 := connection1.(*clientMock)
require.Equal(t, names[1], mock1.name)
// enabled first node again
inner.lock.Lock()
inner.clientPacks[0].client = newNetmapMock(names[0], false)
inner.clients[0] = newNetmapMock(names[0], false)
inner.lock.Unlock()
p.updateInnerNodesHealth(context.TODO(), 0, buffer)
@ -110,7 +120,7 @@ func TestHealthyReweight(t *testing.T) {
connection0, err = p.connection()
require.NoError(t, err)
mock0 = connection0.client.(*clientMock)
mock0 = connection0.(*clientMock)
require.Equal(t, names[0], mock0.name)
}
@ -121,12 +131,13 @@ func TestHealthyNoReweight(t *testing.T) {
buffer = make([]float64, len(weights))
)
sampler := newSampler(weights, rand.NewSource(0))
sampl := newSampler(weights, rand.NewSource(0))
inner := &innerPool{
sampler: sampler,
clientPacks: []*clientPack{
{client: newNetmapMock(names[0], false), healthy: true},
{client: newNetmapMock(names[1], false), healthy: true}},
sampler: sampl,
clients: []client{
newNetmapMock(names[0], false),
newNetmapMock(names[1], false),
},
}
p := &Pool{
innerPools: []*innerPool{inner},
@ -137,5 +148,5 @@ func TestHealthyNoReweight(t *testing.T) {
inner.lock.RLock()
defer inner.lock.RUnlock()
require.Equal(t, inner.sampler, sampler)
require.Equal(t, inner.sampler, sampl)
}