github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/go-grpc-middleware/recovery/interceptors_test.go (about)

     1  // Copyright 2017 David Ackroyd. All Rights Reserved.
     2  // See LICENSE for licensing terms.
     3  
     4  package grpc_recovery_test
     5  
     6  import (
     7  	"testing"
     8  
     9  	grpc_middleware "github.com/hxx258456/ccgo/go-grpc-middleware"
    10  	grpc_recovery "github.com/hxx258456/ccgo/go-grpc-middleware/recovery"
    11  	grpc_testing "github.com/hxx258456/ccgo/go-grpc-middleware/testing"
    12  	pb_testproto "github.com/hxx258456/ccgo/go-grpc-middleware/testing/testproto"
    13  	"github.com/hxx258456/ccgo/grpc"
    14  	"github.com/hxx258456/ccgo/grpc/codes"
    15  	"github.com/hxx258456/ccgo/net/context"
    16  	"github.com/stretchr/testify/assert"
    17  	"github.com/stretchr/testify/require"
    18  	"github.com/stretchr/testify/suite"
    19  )
    20  
    21  var (
    22  	goodPing  = &pb_testproto.PingRequest{Value: "something", SleepTimeMs: 9999}
    23  	panicPing = &pb_testproto.PingRequest{Value: "panic", SleepTimeMs: 9999}
    24  )
    25  
    26  type recoveryAssertService struct {
    27  	pb_testproto.TestServiceServer
    28  }
    29  
    30  func (s *recoveryAssertService) Ping(ctx context.Context, ping *pb_testproto.PingRequest) (*pb_testproto.PingResponse, error) {
    31  	if ping.Value == "panic" {
    32  		panic("very bad thing happened")
    33  	}
    34  	return s.TestServiceServer.Ping(ctx, ping)
    35  }
    36  
    37  func (s *recoveryAssertService) PingList(ping *pb_testproto.PingRequest, stream pb_testproto.TestService_PingListServer) error {
    38  	if ping.Value == "panic" {
    39  		panic("very bad thing happened")
    40  	}
    41  	return s.TestServiceServer.PingList(ping, stream)
    42  }
    43  
    44  func TestRecoverySuite(t *testing.T) {
    45  	s := &RecoverySuite{
    46  		InterceptorTestSuite: &grpc_testing.InterceptorTestSuite{
    47  			TestService: &recoveryAssertService{TestServiceServer: &grpc_testing.TestPingService{T: t}},
    48  			ServerOpts: []grpc.ServerOption{
    49  				grpc_middleware.WithStreamServerChain(
    50  					grpc_recovery.StreamServerInterceptor()),
    51  				grpc_middleware.WithUnaryServerChain(
    52  					grpc_recovery.UnaryServerInterceptor()),
    53  			},
    54  		},
    55  	}
    56  	suite.Run(t, s)
    57  }
    58  
    59  type RecoverySuite struct {
    60  	*grpc_testing.InterceptorTestSuite
    61  }
    62  
    63  func (s *RecoverySuite) TestUnary_SuccessfulRequest() {
    64  	_, err := s.Client.Ping(s.SimpleCtx(), goodPing)
    65  	require.NoError(s.T(), err, "no error must occur")
    66  }
    67  
    68  func (s *RecoverySuite) TestUnary_PanickingRequest() {
    69  	_, err := s.Client.Ping(s.SimpleCtx(), panicPing)
    70  	require.Error(s.T(), err, "there must be an error")
    71  	assert.Equal(s.T(), codes.Internal, grpc.Code(err), "must error with internal")
    72  	assert.Equal(s.T(), "very bad thing happened", grpc.ErrorDesc(err), "must error with message")
    73  }
    74  
    75  func (s *RecoverySuite) TestStream_SuccessfulReceive() {
    76  	stream, err := s.Client.PingList(s.SimpleCtx(), goodPing)
    77  	require.NoError(s.T(), err, "should not fail on establishing the stream")
    78  	pong, err := stream.Recv()
    79  	require.NoError(s.T(), err, "no error must occur")
    80  	require.NotNil(s.T(), pong, "pong must not be nil")
    81  }
    82  
    83  func (s *RecoverySuite) TestStream_PanickingReceive() {
    84  	stream, err := s.Client.PingList(s.SimpleCtx(), panicPing)
    85  	require.NoError(s.T(), err, "should not fail on establishing the stream")
    86  	_, err = stream.Recv()
    87  	require.Error(s.T(), err, "there must be an error")
    88  	assert.Equal(s.T(), codes.Internal, grpc.Code(err), "must error with internal")
    89  	assert.Equal(s.T(), "very bad thing happened", grpc.ErrorDesc(err), "must error with message")
    90  }
    91  
    92  func TestRecoveryOverrideSuite(t *testing.T) {
    93  	opts := []grpc_recovery.Option{
    94  		grpc_recovery.WithRecoveryHandler(func(p interface{}) (err error) {
    95  			return grpc.Errorf(codes.Unknown, "panic triggered: %v", p)
    96  		}),
    97  	}
    98  	s := &RecoveryOverrideSuite{
    99  		InterceptorTestSuite: &grpc_testing.InterceptorTestSuite{
   100  			TestService: &recoveryAssertService{TestServiceServer: &grpc_testing.TestPingService{T: t}},
   101  			ServerOpts: []grpc.ServerOption{
   102  				grpc_middleware.WithStreamServerChain(
   103  					grpc_recovery.StreamServerInterceptor(opts...)),
   104  				grpc_middleware.WithUnaryServerChain(
   105  					grpc_recovery.UnaryServerInterceptor(opts...)),
   106  			},
   107  		},
   108  	}
   109  	suite.Run(t, s)
   110  }
   111  
   112  type RecoveryOverrideSuite struct {
   113  	*grpc_testing.InterceptorTestSuite
   114  }
   115  
   116  func (s *RecoveryOverrideSuite) TestUnary_SuccessfulRequest() {
   117  	_, err := s.Client.Ping(s.SimpleCtx(), goodPing)
   118  	require.NoError(s.T(), err, "no error must occur")
   119  }
   120  
   121  func (s *RecoveryOverrideSuite) TestUnary_PanickingRequest() {
   122  	_, err := s.Client.Ping(s.SimpleCtx(), panicPing)
   123  	require.Error(s.T(), err, "there must be an error")
   124  	assert.Equal(s.T(), codes.Unknown, grpc.Code(err), "must error with unknown")
   125  	assert.Equal(s.T(), "panic triggered: very bad thing happened", grpc.ErrorDesc(err), "must error with message")
   126  }
   127  
   128  func (s *RecoveryOverrideSuite) TestStream_SuccessfulReceive() {
   129  	stream, err := s.Client.PingList(s.SimpleCtx(), goodPing)
   130  	require.NoError(s.T(), err, "should not fail on establishing the stream")
   131  	pong, err := stream.Recv()
   132  	require.NoError(s.T(), err, "no error must occur")
   133  	require.NotNil(s.T(), pong, "pong must not be nil")
   134  }
   135  
   136  func (s *RecoveryOverrideSuite) TestStream_PanickingReceive() {
   137  	stream, err := s.Client.PingList(s.SimpleCtx(), panicPing)
   138  	require.NoError(s.T(), err, "should not fail on establishing the stream")
   139  	_, err = stream.Recv()
   140  	require.Error(s.T(), err, "there must be an error")
   141  	assert.Equal(s.T(), codes.Unknown, grpc.Code(err), "must error with unknown")
   142  	assert.Equal(s.T(), "panic triggered: very bad thing happened", grpc.ErrorDesc(err), "must error with message")
   143  }