package services import ( "errors" "sync/atomic" "testing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer" "github.com/stretchr/testify/require" "go.uber.org/zap/zaptest" ) func TestHandleError(t *testing.T) { defaultError := errors.New("default error") for _, tc := range []struct { err error expectedError error }{ { err: defaultError, expectedError: defaultError, }, { err: errors.New("something not found"), expectedError: layer.ErrNodeNotFound, }, { err: errors.New("something is denied by some acl rule"), expectedError: layer.ErrNodeAccessDenied, }, } { t.Run("", func(t *testing.T) { err := handleError("err message", tc.err) require.True(t, errors.Is(err, tc.expectedError)) }) } } func TestRetry(t *testing.T) { cl := &ServiceClientGRPC{ log: zaptest.NewLogger(t), clients: []treeClient{ {address: "node0"}, {address: "node1"}, {address: "node2"}, {address: "node3"}, }, } makeFn := func(shouldFail []string) func(treeClient) error { return func(client treeClient) error { for _, item := range shouldFail { if item == client.address { return errors.New("not found") } } return nil } } t.Run("first ok", func(t *testing.T) { err := cl.requestWithRetry(makeFn([]string{})) require.NoError(t, err) require.Equal(t, 0, int(atomic.LoadInt32(&cl.startIndex))) atomic.StoreInt32(&cl.startIndex, 0) }) t.Run("first failed", func(t *testing.T) { err := cl.requestWithRetry(makeFn([]string{"node0"})) require.NoError(t, err) require.Equal(t, 1, int(atomic.LoadInt32(&cl.startIndex))) atomic.StoreInt32(&cl.startIndex, 0) }) t.Run("all failed", func(t *testing.T) { err := cl.requestWithRetry(makeFn([]string{"node0", "node1", "node2", "node3"})) require.Error(t, err) require.Equal(t, 0, int(atomic.LoadInt32(&cl.startIndex))) atomic.StoreInt32(&cl.startIndex, 0) }) t.Run("round", func(t *testing.T) { err := cl.requestWithRetry(makeFn([]string{"node0", "node1"})) require.NoError(t, err) require.Equal(t, 2, int(atomic.LoadInt32(&cl.startIndex))) err = cl.requestWithRetry(makeFn([]string{"node2", "node3"})) require.NoError(t, err) require.Equal(t, 0, int(atomic.LoadInt32(&cl.startIndex))) atomic.StoreInt32(&cl.startIndex, 0) }) }