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  }