package services import ( "context" "errors" "testing" "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer" "github.com/stretchr/testify/require" "go.uber.org/zap/zaptest" "google.golang.org/grpc" ) 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) { ctx := context.Background() cl := &ServiceClientGRPC{ log: zaptest.NewLogger(t), clients: []treeClient{ {address: "node0"}, {address: "node1"}, {address: "node2"}, {address: "node3"}, }, } fn := func(client treeClient) grpcFunc[[]string, string] { return func(ctx context.Context, shouldFail []string, opts ...grpc.CallOption) (string, error) { for _, item := range shouldFail { if item == client.address { return "", errors.New("not found") } } return client.address, nil } } t.Run("first ok", func(t *testing.T) { resp, err := requestWithRetry(ctx, []string{}, cl, fn) require.NoError(t, err) require.Equal(t, "node0", resp) require.Equal(t, 0, int(cl.startIndex.Load())) cl.startIndex.Store(0) }) t.Run("first failed", func(t *testing.T) { resp, err := requestWithRetry(ctx, []string{"node0"}, cl, fn) require.NoError(t, err) require.Equal(t, "node1", resp) require.Equal(t, 1, int(cl.startIndex.Load())) cl.startIndex.Store(0) }) t.Run("all failed", func(t *testing.T) { resp, err := requestWithRetry(ctx, []string{"node0", "node1", "node2", "node3"}, cl, fn) require.Error(t, err) require.Equal(t, "", resp) require.Equal(t, 0, int(cl.startIndex.Load())) cl.startIndex.Store(0) }) t.Run("round", func(t *testing.T) { resp, err := requestWithRetry(ctx, []string{"node0", "node1"}, cl, fn) require.NoError(t, err) require.Equal(t, "node2", resp) require.Equal(t, 2, int(cl.startIndex.Load())) resp, err = requestWithRetry(ctx, []string{"node2", "node3"}, cl, fn) require.NoError(t, err) require.Equal(t, "node0", resp) require.Equal(t, 0, int(cl.startIndex.Load())) cl.startIndex.Store(0) }) }