go.uber.org/yarpc@v1.72.1/transport/grpc/handler_test.go (about)

     1  // Copyright (c) 2022 Uber Technologies, Inc.
     2  //
     3  // Permission is hereby granted, free of charge, to any person obtaining a copy
     4  // of this software and associated documentation files (the "Software"), to deal
     5  // in the Software without restriction, including without limitation the rights
     6  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     7  // copies of the Software, and to permit persons to whom the Software is
     8  // furnished to do so, subject to the following conditions:
     9  //
    10  // The above copyright notice and this permission notice shall be included in
    11  // all copies or substantial portions of the Software.
    12  //
    13  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    14  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    15  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    16  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    17  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    18  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    19  // THE SOFTWARE.
    20  
    21  package grpc
    22  
    23  import (
    24  	"context"
    25  	"net"
    26  	"testing"
    27  
    28  	"github.com/stretchr/testify/assert"
    29  	"github.com/stretchr/testify/require"
    30  	"go.uber.org/yarpc/yarpcerrors"
    31  	"google.golang.org/grpc/codes"
    32  	"google.golang.org/grpc/metadata"
    33  	"google.golang.org/grpc/status"
    34  )
    35  
    36  func TestInvalidStreamContext(t *testing.T) {
    37  	listener, err := net.Listen("tcp", "127.0.0.1:0")
    38  	require.NoError(t, err)
    39  
    40  	tran := NewTransport()
    41  	i := tran.NewInbound(listener)
    42  
    43  	h := handler{i: i}
    44  
    45  	_, err = h.getBasicTransportRequest(context.Background(), "serv/proc")
    46  
    47  	require.Contains(t, err.Error(), "cannot get metadata from ctx:")
    48  	require.Contains(t, err.Error(), "code:internal")
    49  }
    50  
    51  func TestInvalidStreamMethod(t *testing.T) {
    52  	listener, err := net.Listen("tcp", "127.0.0.1:0")
    53  	require.NoError(t, err)
    54  
    55  	tran := NewTransport()
    56  	i := tran.NewInbound(listener)
    57  
    58  	h := handler{i: i}
    59  	ctx := metadata.NewIncomingContext(context.Background(), metadata.MD{})
    60  
    61  	_, err = h.getBasicTransportRequest(ctx, "invalidMethod!")
    62  
    63  	require.Contains(t, err.Error(), errInvalidGRPCMethod.Error())
    64  }
    65  
    66  func TestInvalidStreamRequest(t *testing.T) {
    67  	listener, err := net.Listen("tcp", "127.0.0.1:0")
    68  	require.NoError(t, err)
    69  
    70  	tran := NewTransport()
    71  	i := tran.NewInbound(listener)
    72  
    73  	h := handler{i: i}
    74  	ctx := metadata.NewIncomingContext(context.Background(), metadata.MD{})
    75  
    76  	_, err = h.getBasicTransportRequest(ctx, "service/proc")
    77  
    78  	require.Contains(t, err.Error(), "code:invalid-argument")
    79  	require.Contains(t, err.Error(), "missing service name, caller name, encoding")
    80  }
    81  
    82  func TestInvalidStreamEmptyHeader(t *testing.T) {
    83  	listener, err := net.Listen("tcp", "127.0.0.1:0")
    84  	require.NoError(t, err)
    85  
    86  	tran := NewTransport()
    87  	i := tran.NewInbound(listener)
    88  
    89  	h := handler{i: i}
    90  	md := metadata.MD{
    91  		CallerHeader:   []string{},
    92  		ServiceHeader:  []string{"test"},
    93  		EncodingHeader: []string{"raw"},
    94  	}
    95  	ctx := metadata.NewIncomingContext(context.Background(), md)
    96  
    97  	_, err = h.getBasicTransportRequest(ctx, "service/proc")
    98  
    99  	require.Contains(t, err.Error(), "code:invalid-argument")
   100  	require.Contains(t, err.Error(), "missing caller name")
   101  }
   102  
   103  func TestInvalidStreamMultipleHeaders(t *testing.T) {
   104  	listener, err := net.Listen("tcp", "127.0.0.1:0")
   105  	require.NoError(t, err)
   106  
   107  	tran := NewTransport()
   108  	i := tran.NewInbound(listener)
   109  
   110  	h := handler{i: i}
   111  	md := metadata.MD{
   112  		CallerHeader: []string{"caller1", "caller2"},
   113  	}
   114  	ctx := metadata.NewIncomingContext(context.Background(), md)
   115  
   116  	_, err = h.getBasicTransportRequest(ctx, "service/proc")
   117  
   118  	require.Contains(t, err.Error(), "code:invalid-argument")
   119  	require.Contains(t, err.Error(), "header has more than one value: rpc-caller:[caller1 caller2]")
   120  }
   121  
   122  func TestToGRPCError(t *testing.T) {
   123  	t.Run("nil", func(t *testing.T) {
   124  		assert.Nil(t, toGRPCError(nil))
   125  	})
   126  
   127  	t.Run("gRPC status", func(t *testing.T) {
   128  		grpcSt := status.New(codes.InvalidArgument, "foo").Err()
   129  		assert.Equal(t, grpcSt, toGRPCError(grpcSt), "expected same error given")
   130  	})
   131  
   132  	t.Run("yarpcerror", func(t *testing.T) {
   133  		msg := "foo"
   134  		yErr := yarpcerrors.FailedPreconditionErrorf(msg)
   135  
   136  		grpcSt, ok := status.FromError(toGRPCError(yErr))
   137  		require.True(t, ok, "expected gRPC error")
   138  
   139  		assert.Equal(t, codes.FailedPrecondition, grpcSt.Code(), "code")
   140  		assert.Equal(t, msg, grpcSt.Message(), "message mismatch")
   141  	})
   142  }