github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/go-grpc-middleware/logging/logrus/client_interceptors_test.go (about) 1 package grpc_logrus_test 2 3 import ( 4 "io" 5 "runtime" 6 "strings" 7 "testing" 8 9 grpc_logrus "github.com/hxx258456/ccgo/go-grpc-middleware/logging/logrus" 10 "github.com/hxx258456/ccgo/grpc" 11 "github.com/hxx258456/ccgo/grpc/codes" 12 "github.com/sirupsen/logrus" 13 "github.com/stretchr/testify/assert" 14 "github.com/stretchr/testify/require" 15 "github.com/stretchr/testify/suite" 16 17 pb_testproto "github.com/hxx258456/ccgo/go-grpc-middleware/testing/testproto" 18 ) 19 20 func customClientCodeToLevel(c codes.Code) logrus.Level { 21 if c == codes.Unauthenticated { 22 // Make this a special case for tests, and an error. 23 return logrus.ErrorLevel 24 } 25 level := grpc_logrus.DefaultClientCodeToLevel(c) 26 return level 27 } 28 29 func TestLogrusClientSuite(t *testing.T) { 30 if strings.HasPrefix(runtime.Version(), "go1.7") { 31 t.Skipf("Skipping due to json.RawMessage incompatibility with go1.7") 32 return 33 } 34 opts := []grpc_logrus.Option{ 35 grpc_logrus.WithLevels(customClientCodeToLevel), 36 } 37 b := newLogrusBaseSuite(t) 38 b.logger.Level = logrus.DebugLevel // a lot of our stuff is on debug level by default 39 b.InterceptorTestSuite.ClientOpts = []grpc.DialOption{ 40 grpc.WithUnaryInterceptor(grpc_logrus.UnaryClientInterceptor(logrus.NewEntry(b.logger), opts...)), 41 grpc.WithStreamInterceptor(grpc_logrus.StreamClientInterceptor(logrus.NewEntry(b.logger), opts...)), 42 } 43 suite.Run(t, &logrusClientSuite{b}) 44 } 45 46 type logrusClientSuite struct { 47 *logrusBaseSuite 48 } 49 50 func (s *logrusClientSuite) TestPing() { 51 _, err := s.Client.Ping(s.SimpleCtx(), goodPing) 52 assert.NoError(s.T(), err, "there must be not be an on a successful call") 53 54 msgs := s.getOutputJSONs() 55 require.Len(s.T(), msgs, 1, "one log statement should be logged") 56 57 assert.Equal(s.T(), msgs[0]["grpc.service"], "mwitkow.testproto.TestService", "all lines must contain the correct service name") 58 assert.Equal(s.T(), msgs[0]["grpc.method"], "Ping", "all lines must contain the correct method name") 59 assert.Equal(s.T(), msgs[0]["msg"], "finished client unary call", "handler's message must contain the correct message") 60 assert.Equal(s.T(), msgs[0]["span.kind"], "client", "all lines must contain the kind of call (client)") 61 assert.Equal(s.T(), msgs[0]["level"], "debug", "OK codes must be logged on debug level.") 62 63 assert.Contains(s.T(), msgs[0], "grpc.time_ms", "interceptor log statement should contain execution time (duration in ms)") 64 } 65 66 func (s *logrusClientSuite) TestPingList() { 67 stream, err := s.Client.PingList(s.SimpleCtx(), goodPing) 68 require.NoError(s.T(), err, "should not fail on establishing the stream") 69 for { 70 _, err := stream.Recv() 71 if err == io.EOF { 72 break 73 } 74 require.NoError(s.T(), err, "reading stream should not fail") 75 } 76 77 msgs := s.getOutputJSONs() 78 require.Len(s.T(), msgs, 1, "one log statement should be logged") 79 80 assert.Equal(s.T(), msgs[0]["grpc.service"], "mwitkow.testproto.TestService", "all lines must contain the correct service name") 81 assert.Equal(s.T(), msgs[0]["grpc.method"], "PingList", "all lines must contain the correct method name") 82 assert.Equal(s.T(), msgs[0]["msg"], "finished client streaming call", "handler's message must contain the correct message") 83 assert.Equal(s.T(), msgs[0]["span.kind"], "client", "all lines must contain the kind of call (client)") 84 assert.Equal(s.T(), msgs[0]["level"], "debug", "OK codes must be logged on debug level.") 85 assert.Contains(s.T(), msgs[0], "grpc.time_ms", "interceptor log statement should contain execution time (duration in ms)") 86 } 87 88 func (s *logrusClientSuite) TestPingError_WithCustomLevels() { 89 for _, tcase := range []struct { 90 code codes.Code 91 level logrus.Level 92 msg string 93 }{ 94 { 95 code: codes.Internal, 96 level: logrus.WarnLevel, 97 msg: "Internal must remap to ErrorLevel in DefaultClientCodeToLevel", 98 }, 99 { 100 code: codes.NotFound, 101 level: logrus.DebugLevel, 102 msg: "NotFound must remap to InfoLevel in DefaultClientCodeToLevel", 103 }, 104 { 105 code: codes.FailedPrecondition, 106 level: logrus.DebugLevel, 107 msg: "FailedPrecondition must remap to WarnLevel in DefaultClientCodeToLevel", 108 }, 109 { 110 code: codes.Unauthenticated, 111 level: logrus.ErrorLevel, 112 msg: "Unauthenticated is overwritten to ErrorLevel with customClientCodeToLevel override, which probably didn't work", 113 }, 114 } { 115 s.SetupTest() 116 _, err := s.Client.PingError( 117 s.SimpleCtx(), 118 &pb_testproto.PingRequest{Value: "something", ErrorCodeReturned: uint32(tcase.code)}) 119 120 assert.Error(s.T(), err, "each call here must return an error") 121 122 msgs := s.getOutputJSONs() 123 require.Len(s.T(), msgs, 1, "only a single log message is printed") 124 125 assert.Equal(s.T(), msgs[0]["grpc.service"], "mwitkow.testproto.TestService", "all lines must contain the correct service name") 126 assert.Equal(s.T(), msgs[0]["grpc.method"], "PingError", "all lines must contain the correct method name") 127 assert.Equal(s.T(), msgs[0]["grpc.code"], tcase.code.String(), "all lines must contain a grpc code") 128 assert.Equal(s.T(), msgs[0]["level"], tcase.level.String(), tcase.msg) 129 } 130 } 131 132 func TestLogrusClientOverrideSuite(t *testing.T) { 133 if strings.HasPrefix(runtime.Version(), "go1.7") { 134 t.Skip("Skipping due to json.RawMessage incompatibility with go1.7") 135 return 136 } 137 opts := []grpc_logrus.Option{ 138 grpc_logrus.WithDurationField(grpc_logrus.DurationToDurationField), 139 } 140 b := newLogrusBaseSuite(t) 141 b.logger.Level = logrus.DebugLevel // a lot of our stuff is on debug level by default 142 b.InterceptorTestSuite.ClientOpts = []grpc.DialOption{ 143 grpc.WithUnaryInterceptor(grpc_logrus.UnaryClientInterceptor(logrus.NewEntry(b.logger), opts...)), 144 grpc.WithStreamInterceptor(grpc_logrus.StreamClientInterceptor(logrus.NewEntry(b.logger), opts...)), 145 } 146 suite.Run(t, &logrusClientOverrideSuite{b}) 147 } 148 149 type logrusClientOverrideSuite struct { 150 *logrusBaseSuite 151 } 152 153 func (s *logrusClientOverrideSuite) TestPing_HasOverrides() { 154 _, err := s.Client.Ping(s.SimpleCtx(), goodPing) 155 assert.NoError(s.T(), err, "there must be not be an on a successful call") 156 157 msgs := s.getOutputJSONs() 158 require.Len(s.T(), msgs, 1, "one log statement should be logged") 159 assert.Equal(s.T(), msgs[0]["grpc.service"], "mwitkow.testproto.TestService", "all lines must contain the correct service name") 160 assert.Equal(s.T(), msgs[0]["grpc.method"], "Ping", "all lines must contain the correct method name") 161 assert.Equal(s.T(), msgs[0]["msg"], "finished client unary call", "handler's message must contain the correct message") 162 163 assert.NotContains(s.T(), msgs[0], "grpc.time_ms", "message must not contain default duration") 164 assert.Contains(s.T(), msgs[0], "grpc.duration", "message must contain overridden duration") 165 } 166 167 func (s *logrusClientOverrideSuite) TestPingList_HasOverrides() { 168 stream, err := s.Client.PingList(s.SimpleCtx(), goodPing) 169 require.NoError(s.T(), err, "should not fail on establishing the stream") 170 for { 171 _, err := stream.Recv() 172 if err == io.EOF { 173 break 174 } 175 require.NoError(s.T(), err, "reading stream should not fail") 176 } 177 178 msgs := s.getOutputJSONs() 179 require.Len(s.T(), msgs, 1, "one log statement should be logged") 180 181 assert.Equal(s.T(), msgs[0]["grpc.service"], "mwitkow.testproto.TestService", "all lines must contain the correct service name") 182 assert.Equal(s.T(), msgs[0]["grpc.method"], "PingList", "all lines must contain the correct method name") 183 assert.Equal(s.T(), msgs[0]["msg"], "finished client streaming call", "log message must be correct") 184 assert.Equal(s.T(), msgs[0]["span.kind"], "client", "all lines must contain the kind of call (client)") 185 assert.Equal(s.T(), msgs[0]["level"], "debug", "OK codes must be logged on debug level.") 186 187 assert.NotContains(s.T(), msgs[0], "grpc.time_ms", "message must not contain default duration") 188 assert.Contains(s.T(), msgs[0], "grpc.duration", "message must contain overridden duration") 189 }