github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/server/grpc/grpc_test.go (about) 1 // Copyright 2020 Asim Aslam 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 // Original source: github.com/micro/go-micro/v3/server/grpc/grpc_test.go 16 17 package grpc_test 18 19 import ( 20 "context" 21 "fmt" 22 "testing" 23 24 pberr "github.com/tickoalcantara12/micro/v3/proto/errors" 25 bmemory "github.com/tickoalcantara12/micro/v3/service/broker/memory" 26 "github.com/tickoalcantara12/micro/v3/service/client" 27 gcli "github.com/tickoalcantara12/micro/v3/service/client/grpc" 28 "github.com/tickoalcantara12/micro/v3/service/errors" 29 tgrpc "github.com/tickoalcantara12/micro/v3/service/network/transport/grpc" 30 rmemory "github.com/tickoalcantara12/micro/v3/service/registry/memory" 31 "github.com/tickoalcantara12/micro/v3/service/router" 32 rtreg "github.com/tickoalcantara12/micro/v3/service/router/registry" 33 "github.com/tickoalcantara12/micro/v3/service/server" 34 gsrv "github.com/tickoalcantara12/micro/v3/service/server/grpc" 35 pb "github.com/tickoalcantara12/micro/v3/service/server/grpc/proto" 36 "google.golang.org/grpc" 37 "google.golang.org/grpc/status" 38 ) 39 40 // server is used to implement helloworld.GreeterServer. 41 type testServer struct { 42 msgCount int 43 } 44 45 func (s *testServer) Handle(ctx context.Context, msg *pb.Request) error { 46 s.msgCount++ 47 return nil 48 } 49 func (s *testServer) HandleError(ctx context.Context, msg *pb.Request) error { 50 return fmt.Errorf("fake") 51 } 52 53 // TestHello implements helloworld.GreeterServer 54 func (s *testServer) CallPcre(ctx context.Context, req *pb.Request, rsp *pb.Response) error { 55 if req.Name == "Error" { 56 return &errors.Error{Id: "1", Code: 99, Detail: "detail"} 57 } 58 59 rsp.Msg = "Hello " + req.Name 60 return nil 61 } 62 63 // TestHello implements helloworld.GreeterServer 64 func (s *testServer) CallPcreInvalid(ctx context.Context, req *pb.Request, rsp *pb.Response) error { 65 if req.Name == "Error" { 66 return &errors.Error{Id: "1", Code: 99, Detail: "detail"} 67 } 68 69 rsp.Msg = "Hello " + req.Name 70 return nil 71 } 72 73 // TestHello implements helloworld.GreeterServer 74 func (s *testServer) Call(ctx context.Context, req *pb.Request, rsp *pb.Response) error { 75 if req.Name == "Error" { 76 return &errors.Error{Id: "1", Code: 99, Detail: "detail"} 77 } 78 79 if req.Name == "Panic" { 80 // make it panic 81 panic("handler panic") 82 } 83 84 rsp.Msg = "Hello " + req.Name 85 return nil 86 } 87 88 /* 89 func BenchmarkServer(b *testing.B) { 90 r := rmemory.NewRegistry() 91 br := bmemory.NewBroker() 92 tr := tgrpc.NewTransport() 93 s := gsrv.NewServer( 94 server.Broker(br), 95 server.Name("foo"), 96 server.Registry(r), 97 server.Transport(tr), 98 ) 99 c := gcli.NewClient( 100 client.Registry(r), 101 client.Broker(br), 102 client.Transport(tr), 103 ) 104 ctx := context.TODO() 105 106 h := &testServer{} 107 pb.RegisterTestHandler(s, h) 108 if err := s.Start(); err != nil { 109 b.Fatalf("failed to start: %v", err) 110 } 111 112 // check registration 113 services, err := r.GetService("foo") 114 if err != nil || len(services) == 0 { 115 b.Fatalf("failed to get service: %v # %d", err, len(services)) 116 } 117 118 defer func() { 119 if err := s.Stop(); err != nil { 120 b.Fatalf("failed to stop: %v", err) 121 } 122 }() 123 124 b.ResetTimer() 125 for i := 0; i < b.N; i++ { 126 c.Call() 127 } 128 129 } 130 */ 131 func TestGRPCServer(t *testing.T) { 132 r := rmemory.NewRegistry() 133 b := bmemory.NewBroker() 134 tr := tgrpc.NewTransport() 135 rtr := rtreg.NewRouter(router.Registry(r)) 136 137 s := gsrv.NewServer( 138 server.Broker(b), 139 server.Name("foo"), 140 server.Registry(r), 141 server.Transport(tr), 142 ) 143 144 c := gcli.NewClient( 145 client.Router(rtr), 146 client.Broker(b), 147 client.Transport(tr), 148 ) 149 ctx := context.TODO() 150 151 h := &testServer{} 152 pb.RegisterTestHandler(s, h) 153 154 if err := s.Subscribe(s.NewSubscriber("test_topic", h.Handle)); err != nil { 155 t.Fatal(err) 156 } 157 158 if err := s.Start(); err != nil { 159 t.Fatalf("failed to start: %v", err) 160 } 161 162 // check registration 163 services, err := r.GetService("foo") 164 if err != nil || len(services) == 0 { 165 t.Fatalf("failed to get service: %v # %d", err, len(services)) 166 } 167 168 defer func() { 169 if err := s.Stop(); err != nil { 170 t.Fatalf("failed to stop: %v", err) 171 } 172 }() 173 174 cnt := 4 175 for i := 0; i < cnt; i++ { 176 msg := c.NewMessage("test_topic", &pb.Request{Name: fmt.Sprintf("msg %d", i)}) 177 if err = c.Publish(ctx, msg); err != nil { 178 t.Fatal(err) 179 } 180 } 181 182 if h.msgCount != cnt { 183 t.Fatalf("pub/sub not work, or invalid message count %d", h.msgCount) 184 } 185 186 cc, err := grpc.Dial(s.Options().Address, grpc.WithInsecure()) 187 if err != nil { 188 t.Fatalf("failed to dial server: %v", err) 189 } 190 191 testMethods := []string{"/test.Test/Call", "/go.micro.test.Test/Call"} 192 193 for _, method := range testMethods { 194 rsp := pb.Response{} 195 196 if err := cc.Invoke(context.Background(), method, &pb.Request{Name: "John"}, &rsp); err != nil { 197 t.Fatalf("error calling server: %v", err) 198 } 199 200 if rsp.Msg != "Hello John" { 201 t.Fatalf("Got unexpected response %v", rsp.Msg) 202 } 203 } 204 205 // Test grpc error 206 rsp := pb.Response{} 207 208 if err := cc.Invoke(context.Background(), "/test.Test/Call", &pb.Request{Name: "Error"}, &rsp); err != nil { 209 st, ok := status.FromError(err) 210 if !ok { 211 t.Fatalf("invalid error received %#+v\n", err) 212 } 213 verr, ok := st.Details()[0].(*pberr.Error) 214 if !ok { 215 t.Fatalf("invalid error received %#+v\n", st.Details()[0]) 216 } 217 if verr.Code != 99 && verr.Id != "1" && verr.Detail != "detail" { 218 t.Fatalf("invalid error received %#+v\n", verr) 219 } 220 } 221 } 222 223 // TestGRPCServerWithPanicWrapper test grpc server with panic wrapper 224 // gRPC server should not crash when wrapper crashed 225 func TestGRPCServerWithPanicWrapper(t *testing.T) { 226 r := rmemory.NewRegistry() 227 b := bmemory.NewBroker() 228 tr := tgrpc.NewTransport() 229 s := gsrv.NewServer( 230 server.Broker(b), 231 server.Name("foo"), 232 server.Registry(r), 233 server.Transport(tr), 234 server.WrapHandler(func(hf server.HandlerFunc) server.HandlerFunc { 235 return func(ctx context.Context, req server.Request, rsp interface{}) error { 236 // make it panic 237 panic("wrapper panic") 238 } 239 }), 240 ) 241 242 h := &testServer{} 243 pb.RegisterTestHandler(s, h) 244 245 if err := s.Start(); err != nil { 246 t.Fatalf("failed to start: %v", err) 247 } 248 249 // check registration 250 services, err := r.GetService("foo") 251 if err != nil || len(services) == 0 { 252 t.Fatalf("failed to get service: %v # %d", err, len(services)) 253 } 254 255 defer func() { 256 if err := s.Stop(); err != nil { 257 t.Fatalf("failed to stop: %v", err) 258 } 259 }() 260 261 cc, err := grpc.Dial(s.Options().Address, grpc.WithInsecure()) 262 if err != nil { 263 t.Fatalf("failed to dial server: %v", err) 264 } 265 266 rsp := pb.Response{} 267 if err := cc.Invoke(context.Background(), "/test.Test/Call", &pb.Request{Name: "John"}, &rsp); err == nil { 268 t.Fatal("this must return error, as wrapper should be panic") 269 } 270 271 // both wrapper and handler should panic 272 rsp = pb.Response{} 273 if err := cc.Invoke(context.Background(), "/test.Test/Call", &pb.Request{Name: "Panic"}, &rsp); err == nil { 274 t.Fatal("this must return error, as wrapper and handler should be panic") 275 } 276 } 277 278 // TestGRPCServerWithPanicWrapper test grpc server with panic handler 279 // gRPC server should not crash when handler crashed 280 func TestGRPCServerWithPanicHandler(t *testing.T) { 281 r := rmemory.NewRegistry() 282 b := bmemory.NewBroker() 283 tr := tgrpc.NewTransport() 284 s := gsrv.NewServer( 285 server.Broker(b), 286 server.Name("foo"), 287 server.Registry(r), 288 server.Transport(tr), 289 ) 290 291 h := &testServer{} 292 pb.RegisterTestHandler(s, h) 293 294 if err := s.Start(); err != nil { 295 t.Fatalf("failed to start: %v", err) 296 } 297 298 // check registration 299 services, err := r.GetService("foo") 300 if err != nil || len(services) == 0 { 301 t.Fatalf("failed to get service: %v # %d", err, len(services)) 302 } 303 304 defer func() { 305 if err := s.Stop(); err != nil { 306 t.Fatalf("failed to stop: %v", err) 307 } 308 }() 309 310 cc, err := grpc.Dial(s.Options().Address, grpc.WithInsecure()) 311 if err != nil { 312 t.Fatalf("failed to dial server: %v", err) 313 } 314 315 rsp := pb.Response{} 316 if err := cc.Invoke(context.Background(), "/test.Test/Call", &pb.Request{Name: "Panic"}, &rsp); err == nil { 317 t.Fatal("this must return error, as handler should be panic") 318 } 319 }