81 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			81 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
| package git
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/stretchr/testify/require"
 | |
| 	"gitlab.com/gitlab-org/gitaly/v15/proto/go/gitalypb"
 | |
| 	"google.golang.org/grpc/codes"
 | |
| 	"google.golang.org/grpc/status"
 | |
| 	"google.golang.org/protobuf/proto"
 | |
| 	"google.golang.org/protobuf/types/known/anypb"
 | |
| 	"google.golang.org/protobuf/types/known/durationpb"
 | |
| )
 | |
| 
 | |
| func TestHandleLimitErr(t *testing.T) {
 | |
| 	testCases := []struct {
 | |
| 		desc          string
 | |
| 		errWriter     func(io.Writer) error
 | |
| 		expectedBytes []byte
 | |
| 	}{
 | |
| 		{
 | |
| 			desc:      "upload pack",
 | |
| 			errWriter: writeUploadPackError,
 | |
| 			expectedBytes: bytes.Join([][]byte{
 | |
| 				[]byte{'0', '0', '4', '7'},
 | |
| 				[]byte("ERR GitLab is currently unable to handle this request due to load.\n"),
 | |
| 			}, []byte{}),
 | |
| 		},
 | |
| 		{
 | |
| 			desc:      "recieve pack",
 | |
| 			errWriter: writeReceivePackError,
 | |
| 			expectedBytes: bytes.Join([][]byte{
 | |
| 				{'0', '0', '2', '3', 1, '0', '0', '1', 'a'},
 | |
| 				[]byte("unpack server is busy\n"),
 | |
| 				{'0', '0', '0', '0', '0', '0', '4', '4', 2},
 | |
| 				[]byte("GitLab is currently unable to handle this request due to load.\n"),
 | |
| 				{'0', '0', '0', '0'},
 | |
| 			}, []byte{}),
 | |
| 		},
 | |
| 	}
 | |
| 
 | |
| 	for _, tc := range testCases {
 | |
| 		t.Run(tc.desc, func(t *testing.T) {
 | |
| 			var body bytes.Buffer
 | |
| 			err := errWithDetail(t, &gitalypb.LimitError{
 | |
| 				ErrorMessage: "concurrency queue wait time reached",
 | |
| 				RetryAfter:   durationpb.New(0)})
 | |
| 
 | |
| 			handleLimitErr(fmt.Errorf("wrapped error: %w", err), &body, tc.errWriter)
 | |
| 			require.Equal(t, tc.expectedBytes, body.Bytes())
 | |
| 		})
 | |
| 	}
 | |
| 
 | |
| 	t.Run("non LimitError", func(t *testing.T) {
 | |
| 		var body bytes.Buffer
 | |
| 		err := status.Error(codes.Internal, "some internal error")
 | |
| 		handleLimitErr(fmt.Errorf("wrapped error: %w", err), &body, writeUploadPackError)
 | |
| 		require.Equal(t, []byte(nil), body.Bytes())
 | |
| 
 | |
| 		handleLimitErr(fmt.Errorf("wrapped error: %w", err), &body, writeReceivePackError)
 | |
| 		require.Equal(t, []byte(nil), body.Bytes())
 | |
| 
 | |
| 	})
 | |
| }
 | |
| 
 | |
| // errWithDetail adds the given details to the error if it is a gRPC status whose code is not OK.
 | |
| func errWithDetail(t *testing.T, detail proto.Message) error {
 | |
| 	st := status.New(codes.Unavailable, "too busy")
 | |
| 
 | |
| 	proto := st.Proto()
 | |
| 	marshaled, err := anypb.New(detail)
 | |
| 	require.NoError(t, err)
 | |
| 
 | |
| 	proto.Details = append(proto.Details, marshaled)
 | |
| 
 | |
| 	return status.ErrorProto(proto)
 | |
| }
 |