[#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 ( require (
github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210521073959-f0d4d129b7f1 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/google/uuid v1.2.0
github.com/hashicorp/golang-lru v0.5.4 github.com/hashicorp/golang-lru v0.5.4
github.com/mr-tron/base58 v1.2.0 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 package pool
import ( import (
context "context" "context"
reflect "reflect" "crypto/ecdsa"
"errors"
gomock "github.com/golang/mock/gomock" "github.com/google/uuid"
accounting "github.com/nspcc-dev/neofs-sdk-go/accounting" sessionv2 "github.com/nspcc-dev/neofs-api-go/v2/session"
container "github.com/nspcc-dev/neofs-sdk-go/container" "github.com/nspcc-dev/neofs-sdk-go/accounting"
id "github.com/nspcc-dev/neofs-sdk-go/container/id" "github.com/nspcc-dev/neofs-sdk-go/container"
eacl "github.com/nspcc-dev/neofs-sdk-go/eacl" cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
netmap "github.com/nspcc-dev/neofs-sdk-go/netmap" neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa"
object "github.com/nspcc-dev/neofs-sdk-go/object" "github.com/nspcc-dev/neofs-sdk-go/eacl"
id0 "github.com/nspcc-dev/neofs-sdk-go/object/id" "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 {
type MockClient struct { key ecdsa.PrivateKey
ctrl *gomock.Controller addr string
recorder *MockClientMockRecorder healthy *atomic.Bool
errorCount *atomic.Uint32
errorOnCreateSession bool
errorOnEndpointInfo bool
errorOnNetworkInfo bool
errorOnGetObject error
} }
// MockClientMockRecorder is the mock recorder for MockClient. func newMockClient(addr string, key ecdsa.PrivateKey) *mockClient {
type MockClientMockRecorder struct { return &mockClient{
mock *MockClient key: key,
addr: addr,
healthy: atomic.NewBool(true),
errorCount: atomic.NewUint32(0),
}
} }
// NewMockClient creates a new mock instance. func (m *mockClient) errOnCreateSession() {
func NewMockClient(ctrl *gomock.Controller) *MockClient { m.errorOnCreateSession = true
mock := &MockClient{ctrl: ctrl}
mock.recorder = &MockClientMockRecorder{mock}
return mock
} }
// EXPECT returns an object that allows the caller to indicate expected use. func (m *mockClient) errOnEndpointInfo() {
func (m *MockClient) EXPECT() *MockClientMockRecorder { m.errorOnEndpointInfo = true
return m.recorder
} }
// balanceGet mocks base method. func (m *mockClient) errOnNetworkInfo() {
func (m *MockClient) balanceGet(arg0 context.Context, arg1 PrmBalanceGet) (*accounting.Decimal, error) { m.errorOnEndpointInfo = true
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "balanceGet", arg0, arg1)
ret0, _ := ret[0].(*accounting.Decimal)
ret1, _ := ret[1].(error)
return ret0, ret1
} }
// balanceGet indicates an expected call of balanceGet. func (m *mockClient) errOnGetObject(err error) {
func (mr *MockClientMockRecorder) balanceGet(arg0, arg1 interface{}) *gomock.Call { m.errorOnGetObject = err
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "balanceGet", reflect.TypeOf((*MockClient)(nil).balanceGet), arg0, arg1)
} }
// containerDelete mocks base method. func newToken(key ecdsa.PrivateKey) *session.Object {
func (m *MockClient) containerDelete(arg0 context.Context, arg1 PrmContainerDelete) error { var tok session.Object
m.ctrl.T.Helper() tok.SetID(uuid.New())
ret := m.ctrl.Call(m, "containerDelete", arg0, arg1) pk := neofsecdsa.PublicKey(key.PublicKey)
ret0, _ := ret[0].(error) tok.SetAuthKey(&pk)
return ret0
return &tok
} }
// containerDelete indicates an expected call of containerDelete. func (m *mockClient) balanceGet(context.Context, PrmBalanceGet) (*accounting.Decimal, error) {
func (mr *MockClientMockRecorder) containerDelete(arg0, arg1 interface{}) *gomock.Call { return nil, nil
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "containerDelete", reflect.TypeOf((*MockClient)(nil).containerDelete), arg0, arg1)
} }
// containerEACL mocks base method. func (m *mockClient) containerPut(context.Context, PrmContainerPut) (*cid.ID, error) {
func (m *MockClient) containerEACL(arg0 context.Context, arg1 PrmContainerEACL) (*eacl.Table, error) { return nil, nil
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "containerEACL", arg0, arg1)
ret0, _ := ret[0].(*eacl.Table)
ret1, _ := ret[1].(error)
return ret0, ret1
} }
// containerEACL indicates an expected call of containerEACL. func (m *mockClient) containerGet(context.Context, PrmContainerGet) (*container.Container, error) {
func (mr *MockClientMockRecorder) containerEACL(arg0, arg1 interface{}) *gomock.Call { return nil, nil
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "containerEACL", reflect.TypeOf((*MockClient)(nil).containerEACL), arg0, arg1)
} }
// containerGet mocks base method. func (m *mockClient) containerList(context.Context, PrmContainerList) ([]cid.ID, error) {
func (m *MockClient) containerGet(arg0 context.Context, arg1 PrmContainerGet) (*container.Container, error) { return nil, nil
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "containerGet", arg0, arg1)
ret0, _ := ret[0].(*container.Container)
ret1, _ := ret[1].(error)
return ret0, ret1
} }
// containerGet indicates an expected call of containerGet. func (m *mockClient) containerDelete(context.Context, PrmContainerDelete) error {
func (mr *MockClientMockRecorder) containerGet(arg0, arg1 interface{}) *gomock.Call { return nil
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "containerGet", reflect.TypeOf((*MockClient)(nil).containerGet), arg0, arg1)
} }
// containerList mocks base method. func (m *mockClient) containerEACL(context.Context, PrmContainerEACL) (*eacl.Table, error) {
func (m *MockClient) containerList(arg0 context.Context, arg1 PrmContainerList) ([]id.ID, error) { return nil, nil
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "containerList", arg0, arg1)
ret0, _ := ret[0].([]id.ID)
ret1, _ := ret[1].(error)
return ret0, ret1
} }
// containerList indicates an expected call of containerList. func (m *mockClient) containerSetEACL(context.Context, PrmContainerSetEACL) error {
func (mr *MockClientMockRecorder) containerList(arg0, arg1 interface{}) *gomock.Call { return nil
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "containerList", reflect.TypeOf((*MockClient)(nil).containerList), arg0, arg1)
} }
// containerPut mocks base method. func (m *mockClient) endpointInfo(context.Context, prmEndpointInfo) (*netmap.NodeInfo, error) {
func (m *MockClient) containerPut(arg0 context.Context, arg1 PrmContainerPut) (*id.ID, error) { if m.errorOnEndpointInfo {
m.ctrl.T.Helper() return nil, errors.New("error")
ret := m.ctrl.Call(m, "containerPut", arg0, arg1) }
ret0, _ := ret[0].(*id.ID)
ret1, _ := ret[1].(error) var ni netmap.NodeInfo
return ret0, ret1 ni.SetNetworkEndpoints(m.addr)
return &ni, nil
} }
// containerPut indicates an expected call of containerPut. func (m *mockClient) networkInfo(context.Context, prmNetworkInfo) (*netmap.NetworkInfo, error) {
func (mr *MockClientMockRecorder) containerPut(arg0, arg1 interface{}) *gomock.Call { if m.errorOnNetworkInfo {
mr.mock.ctrl.T.Helper() return nil, errors.New("error")
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "containerPut", reflect.TypeOf((*MockClient)(nil).containerPut), arg0, arg1) }
var ni netmap.NetworkInfo
return &ni, nil
} }
// containerSetEACL mocks base method. func (m *mockClient) objectPut(context.Context, PrmObjectPut) (*oid.ID, error) {
func (m *MockClient) containerSetEACL(arg0 context.Context, arg1 PrmContainerSetEACL) error { return nil, nil
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "containerSetEACL", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
} }
// containerSetEACL indicates an expected call of containerSetEACL. func (m *mockClient) objectDelete(context.Context, PrmObjectDelete) error {
func (mr *MockClientMockRecorder) containerSetEACL(arg0, arg1 interface{}) *gomock.Call { return nil
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "containerSetEACL", reflect.TypeOf((*MockClient)(nil).containerSetEACL), arg0, arg1)
} }
// endpointInfo mocks base method. func (m *mockClient) objectGet(context.Context, PrmObjectGet) (*ResGetObject, error) {
func (m *MockClient) endpointInfo(arg0 context.Context, arg1 prmEndpointInfo) (*netmap.NodeInfo, error) { return &ResGetObject{}, m.errorOnGetObject
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "endpointInfo", arg0, arg1)
ret0, _ := ret[0].(*netmap.NodeInfo)
ret1, _ := ret[1].(error)
return ret0, ret1
} }
// endpointInfo indicates an expected call of endpointInfo. func (m *mockClient) objectHead(context.Context, PrmObjectHead) (*object.Object, error) {
func (mr *MockClientMockRecorder) endpointInfo(arg0, arg1 interface{}) *gomock.Call { return nil, nil
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "endpointInfo", reflect.TypeOf((*MockClient)(nil).endpointInfo), arg0, arg1)
} }
// networkInfo mocks base method. func (m *mockClient) objectRange(context.Context, PrmObjectRange) (*ResObjectRange, error) {
func (m *MockClient) networkInfo(arg0 context.Context, arg1 prmNetworkInfo) (*netmap.NetworkInfo, error) { return nil, nil
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "networkInfo", arg0, arg1)
ret0, _ := ret[0].(*netmap.NetworkInfo)
ret1, _ := ret[1].(error)
return ret0, ret1
} }
// networkInfo indicates an expected call of networkInfo. func (m *mockClient) objectSearch(context.Context, PrmObjectSearch) (*ResObjectSearch, error) {
func (mr *MockClientMockRecorder) networkInfo(arg0, arg1 interface{}) *gomock.Call { return nil, nil
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "networkInfo", reflect.TypeOf((*MockClient)(nil).networkInfo), arg0, arg1)
} }
// objectDelete mocks base method. func (m *mockClient) sessionCreate(context.Context, prmCreateSession) (*resCreateSession, error) {
func (m *MockClient) objectDelete(arg0 context.Context, arg1 PrmObjectDelete) error { if m.errorOnCreateSession {
m.ctrl.T.Helper() return nil, errors.New("error")
ret := m.ctrl.Call(m, "objectDelete", arg0, arg1) }
ret0, _ := ret[0].(error)
return ret0 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 (m *mockClient) isHealthy() bool {
func (mr *MockClientMockRecorder) objectDelete(arg0, arg1 interface{}) *gomock.Call { return m.healthy.Load()
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "objectDelete", reflect.TypeOf((*MockClient)(nil).objectDelete), arg0, arg1)
} }
// objectGet mocks base method. func (m *mockClient) setHealthy(b bool) bool {
func (m *MockClient) objectGet(arg0 context.Context, arg1 PrmObjectGet) (*ResGetObject, error) { return m.healthy.Swap(b) != b
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "objectGet", arg0, arg1)
ret0, _ := ret[0].(*ResGetObject)
ret1, _ := ret[1].(error)
return ret0, ret1
} }
// objectGet indicates an expected call of objectGet. func (m *mockClient) address() string {
func (mr *MockClientMockRecorder) objectGet(arg0, arg1 interface{}) *gomock.Call { return m.addr
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "objectGet", reflect.TypeOf((*MockClient)(nil).objectGet), arg0, arg1)
} }
// objectHead mocks base method. func (m *mockClient) errorRate() uint32 {
func (m *MockClient) objectHead(arg0 context.Context, arg1 PrmObjectHead) (*object.Object, error) { return m.errorCount.Load()
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "objectHead", arg0, arg1)
ret0, _ := ret[0].(*object.Object)
ret1, _ := ret[1].(error)
return ret0, ret1
} }
// objectHead indicates an expected call of objectHead. func (m *mockClient) resetErrorCounter() {
func (mr *MockClientMockRecorder) objectHead(arg0, arg1 interface{}) *gomock.Call { m.errorCount.Store(0)
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)
} }

View file

@ -1,32 +1,28 @@
package pool package pool
//go:generate mockgen -destination mock_test.go -source pool.go -mock_names client=MockClient -package pool . client
import ( import (
"bytes"
"context" "context"
"crypto/ecdsa" "crypto/ecdsa"
"errors"
"fmt" "fmt"
"strconv"
"testing" "testing"
"time" "time"
"github.com/golang/mock/gomock"
"github.com/google/uuid"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status" 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" 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" "github.com/nspcc-dev/neofs-sdk-go/object"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id" 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/session"
"github.com/nspcc-dev/neofs-sdk-go/user" "github.com/nspcc-dev/neofs-sdk-go/user"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.uber.org/atomic"
"go.uber.org/zap" "go.uber.org/zap"
) )
func TestBuildPoolClientFailed(t *testing.T) { func TestBuildPoolClientFailed(t *testing.T) {
clientBuilder := func(_ string) (client, error) { clientBuilder := func(string) (client, error) {
return nil, fmt.Errorf("error") return nil, fmt.Errorf("error")
} }
@ -43,17 +39,10 @@ func TestBuildPoolClientFailed(t *testing.T) {
} }
func TestBuildPoolCreateSessionFailed(t *testing.T) { func TestBuildPoolCreateSessionFailed(t *testing.T) {
ctrl := gomock.NewController(t) clientBuilder := func(addr string) (client, error) {
mockCli := newMockClient(addr, *newPrivateKey(t))
ni := &netmap.NodeInfo{} mockCli.errOnCreateSession()
ni.SetNetworkEndpoints("addr1", "addr2") return mockCli, nil
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
} }
opts := InitParameters{ opts := InitParameters{
@ -74,52 +63,24 @@ func newPrivateKey(t *testing.T) *ecdsa.PrivateKey {
return &p.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) { func TestBuildPoolOneNodeFailed(t *testing.T) {
ctrl := gomock.NewController(t) nodes := []NodeParam{
ctrl2 := gomock.NewController(t) {1, "peer0", 1},
{2, "peer1", 1},
}
var expectedToken *session.Object var clientKeys []*ecdsa.PrivateKey
clientCount := -1 clientBuilder := func(addr string) (client, error) {
clientBuilder := func(_ string) (client, error) { key := newPrivateKey(t)
clientCount++ clientKeys = append(clientKeys, key)
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()
mockClient.EXPECT().endpointInfo(gomock.Any(), gomock.Any()).Return(nil, fmt.Errorf("error")).AnyTimes() if addr == nodes[0].address {
mockClient.EXPECT().networkInfo(gomock.Any(), gomock.Any()).Return(&netmap.NetworkInfo{}, nil).AnyTimes() mockCli := newMockClient(addr, *key)
mockCli.errOnEndpointInfo()
mockClient2 := NewMockClient(ctrl2) return mockCli, nil
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
} }
return mockClient2, nil
return newMockClient(addr, *key), nil
} }
log, err := zap.NewProduction() log, err := zap.NewProduction()
@ -129,10 +90,7 @@ func TestBuildPoolOneNodeFailed(t *testing.T) {
clientBuilder: clientBuilder, clientBuilder: clientBuilder,
clientRebalanceInterval: 1000 * time.Millisecond, clientRebalanceInterval: 1000 * time.Millisecond,
logger: log, logger: log,
nodeParams: []NodeParam{ nodeParams: nodes,
{9, "peer0", 1},
{1, "peer1", 1},
},
} }
clientPool, err := NewPool(opts) clientPool, err := NewPool(opts)
@ -141,13 +99,14 @@ func TestBuildPoolOneNodeFailed(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(clientPool.Close) t.Cleanup(clientPool.Close)
expectedAuthKey := neofsecdsa.PublicKey(clientKeys[1].PublicKey)
condition := func() bool { condition := func() bool {
cp, err := clientPool.connection() cp, err := clientPool.connection()
if err != nil { if err != nil {
return false return false
} }
st, _ := clientPool.cache.Get(formCacheKey(cp.address, clientPool.key)) st, _ := clientPool.cache.Get(formCacheKey(cp.address(), clientPool.key))
return areEqualTokens(&st, expectedToken) return st.AssertAuthKey(&expectedAuthKey)
} }
require.Never(t, condition, 900*time.Millisecond, 100*time.Millisecond) require.Never(t, condition, 900*time.Millisecond, 100*time.Millisecond)
require.Eventually(t, condition, 3*time.Second, 300*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) { func TestOneNode(t *testing.T) {
ctrl := gomock.NewController(t) key1 := newPrivateKey(t)
clientBuilder := func(addr string) (client, error) {
uid := uuid.New() return newMockClient(addr, *key1), nil
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
} }
opts := InitParameters{ opts := InitParameters{
@ -196,38 +140,17 @@ func TestOneNode(t *testing.T) {
cp, err := pool.connection() cp, err := pool.connection()
require.NoError(t, err) require.NoError(t, err)
st, _ := pool.cache.Get(formCacheKey(cp.address, pool.key)) st, _ := pool.cache.Get(formCacheKey(cp.address(), pool.key))
require.True(t, areEqualTokens(&tok, &st)) expectedAuthKey := neofsecdsa.PublicKey(key1.PublicKey)
} require.True(t, st.AssertAuthKey(&expectedAuthKey))
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[:])
} }
func TestTwoNodes(t *testing.T) { func TestTwoNodes(t *testing.T) {
ctrl := gomock.NewController(t) var clientKeys []*ecdsa.PrivateKey
clientBuilder := func(addr string) (client, error) {
var tokens []*session.Object key := newPrivateKey(t)
clientBuilder := func(_ string) (client, error) { clientKeys = append(clientKeys, key)
mockClient := NewMockClient(ctrl) return newMockClient(addr, *key), nil
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
} }
opts := InitParameters{ opts := InitParameters{
@ -247,13 +170,14 @@ func TestTwoNodes(t *testing.T) {
cp, err := pool.connection() cp, err := pool.connection()
require.NoError(t, err) require.NoError(t, err)
st, _ := pool.cache.Get(formCacheKey(cp.address, pool.key)) st, _ := pool.cache.Get(formCacheKey(cp.address(), pool.key))
require.True(t, containsTokens(tokens, &st)) require.True(t, assertAuthKeyForAny(st, clientKeys))
} }
func containsTokens(list []*session.Object, item *session.Object) bool { func assertAuthKeyForAny(st session.Object, clientKeys []*ecdsa.PrivateKey) bool {
for _, tok := range list { for _, key := range clientKeys {
if areEqualTokens(tok, item) { expectedAuthKey := neofsecdsa.PublicKey(key.PublicKey)
if st.AssertAuthKey(&expectedAuthKey) {
return true return true
} }
} }
@ -261,55 +185,29 @@ func containsTokens(list []*session.Object, item *session.Object) bool {
} }
func TestOneOfTwoFailed(t *testing.T) { func TestOneOfTwoFailed(t *testing.T) {
ctrl := gomock.NewController(t) nodes := []NodeParam{
ctrl2 := gomock.NewController(t) {1, "peer0", 1},
{9, "peer1", 1},
}
var tokens []*session.Object var clientKeys []*ecdsa.PrivateKey
clientCount := -1 clientBuilder := func(addr string) (client, error) {
clientBuilder := func(_ string) (client, error) { key := newPrivateKey(t)
clientCount++ clientKeys = append(clientKeys, key)
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()
mockClient2 := NewMockClient(ctrl2) if addr == nodes[0].address {
mockClient2.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).DoAndReturn(func(_, _ interface{}) (*resCreateSession, error) { return newMockClient(addr, *key), nil
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
} }
return mockClient2, nil
mockCli := newMockClient(addr, *key)
mockCli.errOnEndpointInfo()
mockCli.errOnNetworkInfo()
return mockCli, nil
} }
opts := InitParameters{ opts := InitParameters{
key: newPrivateKey(t), key: newPrivateKey(t),
nodeParams: []NodeParam{ nodeParams: nodes,
{1, "peer0", 1},
{9, "peer1", 1},
},
clientRebalanceInterval: 200 * time.Millisecond, clientRebalanceInterval: 200 * time.Millisecond,
clientBuilder: clientBuilder, clientBuilder: clientBuilder,
} }
@ -327,23 +225,19 @@ func TestOneOfTwoFailed(t *testing.T) {
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
cp, err := pool.connection() cp, err := pool.connection()
require.NoError(t, err) require.NoError(t, err)
st, _ := pool.cache.Get(formCacheKey(cp.address, pool.key)) st, _ := pool.cache.Get(formCacheKey(cp.address(), pool.key))
require.True(t, areEqualTokens(tokens[0], &st)) require.True(t, assertAuthKeyForAny(st, clientKeys))
} }
} }
func TestTwoFailed(t *testing.T) { func TestTwoFailed(t *testing.T) {
ctrl := gomock.NewController(t) var clientKeys []*ecdsa.PrivateKey
clientBuilder := func(addr string) (client, error) {
clientBuilder := func(_ string) (client, error) { key := newPrivateKey(t)
mockClient := NewMockClient(ctrl) clientKeys = append(clientKeys, key)
mockClient.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).Return(&resCreateSession{ mockCli := newMockClient(addr, *key)
id: uuid.Nil[:], mockCli.errOnEndpointInfo()
sessionKey: newBinPublicKey(t), return mockCli, nil
}, 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
} }
opts := InitParameters{ opts := InitParameters{
@ -371,27 +265,13 @@ func TestTwoFailed(t *testing.T) {
} }
func TestSessionCache(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(addr string) (client, error) {
clientBuilder := func(_ string) (client, error) { mockCli := newMockClient(addr, *key)
mockClient := NewMockClient(ctrl) mockCli.errOnGetObject(apistatus.SessionTokenNotFound{})
mockClient.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).DoAndReturn(func(_, _ interface{}, _ ...interface{}) (*resCreateSession, error) { return mockCli, nil
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
} }
opts := InitParameters{ opts := InitParameters{
@ -415,8 +295,8 @@ func TestSessionCache(t *testing.T) {
// cache must contain session token // cache must contain session token
cp, err := pool.connection() cp, err := pool.connection()
require.NoError(t, err) require.NoError(t, err)
st, _ := pool.cache.Get(formCacheKey(cp.address, pool.key)) st, _ := pool.cache.Get(formCacheKey(cp.address(), pool.key))
require.True(t, containsTokens(tokens, &st)) require.True(t, st.AssertAuthKey(&expectedAuthKey))
var prm PrmObjectGet var prm PrmObjectGet
prm.SetAddress(oid.Address{}) prm.SetAddress(oid.Address{})
@ -428,7 +308,7 @@ func TestSessionCache(t *testing.T) {
// cache must not contain session token // cache must not contain session token
cp, err = pool.connection() cp, err = pool.connection()
require.NoError(t, err) 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) require.False(t, ok)
var prm2 PrmObjectPut var prm2 PrmObjectPut
@ -440,54 +320,33 @@ func TestSessionCache(t *testing.T) {
// cache must contain session token // cache must contain session token
cp, err = pool.connection() cp, err = pool.connection()
require.NoError(t, err) require.NoError(t, err)
st, _ = pool.cache.Get(formCacheKey(cp.address, pool.key)) st, _ = pool.cache.Get(formCacheKey(cp.address(), pool.key))
require.True(t, containsTokens(tokens, &st)) require.True(t, st.AssertAuthKey(&expectedAuthKey))
} }
func TestPriority(t *testing.T) { func TestPriority(t *testing.T) {
ctrl := gomock.NewController(t) nodes := []NodeParam{
ctrl2 := gomock.NewController(t) {1, "peer0", 1},
{2, "peer1", 100},
}
tokens := make([]*session.Object, 2) var clientKeys []*ecdsa.PrivateKey
clientBuilder := func(endpoint string) (client, error) { clientBuilder := func(addr string) (client, error) {
mockClient := NewMockClient(ctrl) key := newPrivateKey(t)
mockClient.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).DoAndReturn(func(_, _ interface{}) (*resCreateSession, error) { clientKeys = append(clientKeys, key)
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()
mockClient2 := NewMockClient(ctrl2) if addr == nodes[0].address {
mockClient2.EXPECT().sessionCreate(gomock.Any(), gomock.Any()).DoAndReturn(func(_, _ interface{}) (*resCreateSession, error) { mockCli := newMockClient(addr, *key)
tok := newToken(t) mockCli.errOnEndpointInfo()
tokens[1] = tok return mockCli, nil
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
} }
return mockClient2, nil
return newMockClient(addr, *key), nil
} }
opts := InitParameters{ opts := InitParameters{
key: newPrivateKey(t), key: newPrivateKey(t),
nodeParams: []NodeParam{ nodeParams: nodes,
{1, "peer0", 1},
{2, "peer1", 100},
},
clientRebalanceInterval: 1500 * time.Millisecond, clientRebalanceInterval: 1500 * time.Millisecond,
clientBuilder: clientBuilder, clientBuilder: clientBuilder,
} }
@ -501,17 +360,20 @@ func TestPriority(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
t.Cleanup(pool.Close) t.Cleanup(pool.Close)
expectedAuthKey1 := neofsecdsa.PublicKey(clientKeys[0].PublicKey)
firstNode := func() bool { firstNode := func() bool {
cp, err := pool.connection() cp, err := pool.connection()
require.NoError(t, err) require.NoError(t, err)
st, _ := pool.cache.Get(formCacheKey(cp.address, pool.key)) st, _ := pool.cache.Get(formCacheKey(cp.address(), pool.key))
return areEqualTokens(&st, tokens[0]) return st.AssertAuthKey(&expectedAuthKey1)
} }
expectedAuthKey2 := neofsecdsa.PublicKey(clientKeys[1].PublicKey)
secondNode := func() bool { secondNode := func() bool {
cp, err := pool.connection() cp, err := pool.connection()
require.NoError(t, err) require.NoError(t, err)
st, _ := pool.cache.Get(formCacheKey(cp.address, pool.key)) st, _ := pool.cache.Get(formCacheKey(cp.address(), pool.key))
return areEqualTokens(&st, tokens[1]) return st.AssertAuthKey(&expectedAuthKey2)
} }
require.Never(t, secondNode, time.Second, 200*time.Millisecond) require.Never(t, secondNode, time.Second, 200*time.Millisecond)
@ -520,26 +382,11 @@ func TestPriority(t *testing.T) {
} }
func TestSessionCacheWithKey(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(addr string) (client, error) {
clientBuilder := func(_ string) (client, error) { return newMockClient(addr, *key), nil
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
} }
opts := InitParameters{ opts := InitParameters{
@ -562,37 +409,24 @@ func TestSessionCacheWithKey(t *testing.T) {
// cache must contain session token // cache must contain session token
cp, err := pool.connection() cp, err := pool.connection()
require.NoError(t, err) require.NoError(t, err)
st, _ := pool.cache.Get(formCacheKey(cp.address, pool.key)) st, _ := pool.cache.Get(formCacheKey(cp.address(), pool.key))
require.True(t, containsTokens(tokens, &st)) require.True(t, st.AssertAuthKey(&expectedAuthKey))
var prm PrmObjectGet var prm PrmObjectGet
prm.SetAddress(oid.Address{}) prm.SetAddress(oid.Address{})
prm.UseKey(newPrivateKey(t)) anonKey := newPrivateKey(t)
prm.UseKey(anonKey)
_, err = pool.GetObject(ctx, prm) _, err = pool.GetObject(ctx, prm)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, tokens, 2) st, _ = pool.cache.Get(formCacheKey(cp.address(), anonKey))
} require.True(t, st.AssertAuthKey(&expectedAuthKey))
func newToken(t *testing.T) *session.Object {
var tok session.Object
tok.SetID(uuid.New())
return &tok
} }
func TestSessionTokenOwner(t *testing.T) { func TestSessionTokenOwner(t *testing.T) {
t.Skip() // neofs-sdk-go#??? clientBuilder := func(addr string) (client, error) {
ctrl := gomock.NewController(t) key := newPrivateKey(t)
clientBuilder := func(_ string) (client, error) { return newMockClient(addr, *key), nil
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
} }
opts := InitParameters{ opts := InitParameters{
@ -613,7 +447,6 @@ func TestSessionTokenOwner(t *testing.T) {
t.Cleanup(p.Close) t.Cleanup(p.Close)
anonKey := newPrivateKey(t) anonKey := newPrivateKey(t)
var anonOwner user.ID var anonOwner user.ID
user.IDFromKey(&anonOwner, anonKey.PublicKey) user.IDFromKey(&anonOwner, anonKey.PublicKey)
@ -622,27 +455,23 @@ func TestSessionTokenOwner(t *testing.T) {
var prmCtx prmContext var prmCtx prmContext
prmCtx.useDefaultSession() prmCtx.useDefaultSession()
var tkn session.Object
var cc callContext var cc callContext
cc.Context = ctx cc.Context = ctx
cc.sessionTarget = func(session.Object) {} cc.sessionTarget = func(tok session.Object) {
tkn = tok
}
err = p.initCallContext(&cc, prm, prmCtx) err = p.initCallContext(&cc, prm, prmCtx)
require.NoError(t, err) require.NoError(t, err)
err = p.openDefaultSession(&cc) err = p.openDefaultSession(&cc)
require.NoError(t, err) require.NoError(t, err)
tkn, _ := p.cache.Get(formCacheKey("peer0", anonKey))
require.True(t, tkn.VerifySignature()) require.True(t, tkn.VerifySignature())
require.True(t, tkn.Issuer().Equals(anonOwner))
} }
func TestWaitPresence(t *testing.T) { func TestWaitPresence(t *testing.T) {
ctrl := gomock.NewController(t) mockCli := newMockClient("", *newPrivateKey(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()
t.Run("context canceled", func(t *testing.T) { t.Run("context canceled", func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
@ -651,7 +480,7 @@ func TestWaitPresence(t *testing.T) {
cancel() cancel()
}() }()
err := waitForContainerPresence(ctx, mockClient, nil, &WaitParams{ err := waitForContainerPresence(ctx, mockCli, nil, &WaitParams{
timeout: 120 * time.Second, timeout: 120 * time.Second,
pollInterval: 5 * time.Second, pollInterval: 5 * time.Second,
}) })
@ -661,7 +490,7 @@ func TestWaitPresence(t *testing.T) {
t.Run("context deadline exceeded", func(t *testing.T) { t.Run("context deadline exceeded", func(t *testing.T) {
ctx := context.Background() ctx := context.Background()
err := waitForContainerPresence(ctx, mockClient, nil, &WaitParams{ err := waitForContainerPresence(ctx, mockCli, nil, &WaitParams{
timeout: 500 * time.Millisecond, timeout: 500 * time.Millisecond,
pollInterval: 5 * time.Second, pollInterval: 5 * time.Second,
}) })
@ -671,10 +500,92 @@ func TestWaitPresence(t *testing.T) {
t.Run("ok", func(t *testing.T) { t.Run("ok", func(t *testing.T) {
ctx := context.Background() ctx := context.Background()
err := waitForContainerPresence(ctx, mockClient, nil, &WaitParams{ err := waitForContainerPresence(ctx, mockCli, nil, &WaitParams{
timeout: 10 * time.Second, timeout: 10 * time.Second,
pollInterval: 500 * time.Millisecond, pollInterval: 500 * time.Millisecond,
}) })
require.NoError(t, err) 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/nspcc-dev/neofs-sdk-go/netmap"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"go.uber.org/atomic"
) )
func TestSamplerStability(t *testing.T) { func TestSamplerStability(t *testing.T) {
@ -61,7 +62,15 @@ func newNetmapMock(name string, needErr bool) *clientMock {
if needErr { if needErr {
err = fmt.Errorf("not available") 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) { func TestHealthyReweight(t *testing.T) {
@ -76,9 +85,10 @@ func TestHealthyReweight(t *testing.T) {
inner := &innerPool{ inner := &innerPool{
sampler: newSampler(weights, rand.NewSource(0)), sampler: newSampler(weights, rand.NewSource(0)),
clientPacks: []*clientPack{ clients: []client{
{client: newNetmapMock(names[0], true), healthy: true, address: "address0"}, newNetmapMock(names[0], true),
{client: newNetmapMock(names[1], false), healthy: true, address: "address1"}}, newNetmapMock(names[1], false),
},
} }
p := &Pool{ p := &Pool{
innerPools: []*innerPool{inner}, innerPools: []*innerPool{inner},
@ -90,19 +100,19 @@ func TestHealthyReweight(t *testing.T) {
// check getting first node connection before rebalance happened // check getting first node connection before rebalance happened
connection0, err := p.connection() connection0, err := p.connection()
require.NoError(t, err) require.NoError(t, err)
mock0 := connection0.client.(*clientMock) mock0 := connection0.(*clientMock)
require.Equal(t, names[0], mock0.name) require.Equal(t, names[0], mock0.name)
p.updateInnerNodesHealth(context.TODO(), 0, buffer) p.updateInnerNodesHealth(context.TODO(), 0, buffer)
connection1, err := p.connection() connection1, err := p.connection()
require.NoError(t, err) require.NoError(t, err)
mock1 := connection1.client.(*clientMock) mock1 := connection1.(*clientMock)
require.Equal(t, names[1], mock1.name) require.Equal(t, names[1], mock1.name)
// enabled first node again // enabled first node again
inner.lock.Lock() inner.lock.Lock()
inner.clientPacks[0].client = newNetmapMock(names[0], false) inner.clients[0] = newNetmapMock(names[0], false)
inner.lock.Unlock() inner.lock.Unlock()
p.updateInnerNodesHealth(context.TODO(), 0, buffer) p.updateInnerNodesHealth(context.TODO(), 0, buffer)
@ -110,7 +120,7 @@ func TestHealthyReweight(t *testing.T) {
connection0, err = p.connection() connection0, err = p.connection()
require.NoError(t, err) require.NoError(t, err)
mock0 = connection0.client.(*clientMock) mock0 = connection0.(*clientMock)
require.Equal(t, names[0], mock0.name) require.Equal(t, names[0], mock0.name)
} }
@ -121,12 +131,13 @@ func TestHealthyNoReweight(t *testing.T) {
buffer = make([]float64, len(weights)) buffer = make([]float64, len(weights))
) )
sampler := newSampler(weights, rand.NewSource(0)) sampl := newSampler(weights, rand.NewSource(0))
inner := &innerPool{ inner := &innerPool{
sampler: sampler, sampler: sampl,
clientPacks: []*clientPack{ clients: []client{
{client: newNetmapMock(names[0], false), healthy: true}, newNetmapMock(names[0], false),
{client: newNetmapMock(names[1], false), healthy: true}}, newNetmapMock(names[1], false),
},
} }
p := &Pool{ p := &Pool{
innerPools: []*innerPool{inner}, innerPools: []*innerPool{inner},
@ -137,5 +148,5 @@ func TestHealthyNoReweight(t *testing.T) {
inner.lock.RLock() inner.lock.RLock()
defer inner.lock.RUnlock() defer inner.lock.RUnlock()
require.Equal(t, inner.sampler, sampler) require.Equal(t, inner.sampler, sampl)
} }