github.com/annwntech/go-micro/v2@v2.9.5/server/grpc/grpc_test.go (about)

     1  package grpc_test
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"testing"
     7  
     8  	"github.com/annwntech/go-micro/v2"
     9  	bmemory "github.com/annwntech/go-micro/v2/broker/memory"
    10  	"github.com/annwntech/go-micro/v2/client"
    11  	gcli "github.com/annwntech/go-micro/v2/client/grpc"
    12  	"github.com/annwntech/go-micro/v2/errors"
    13  	rmemory "github.com/annwntech/go-micro/v2/registry/memory"
    14  	"github.com/annwntech/go-micro/v2/server"
    15  	gsrv "github.com/annwntech/go-micro/v2/server/grpc"
    16  	tgrpc "github.com/annwntech/go-micro/v2/transport/grpc"
    17  	"google.golang.org/grpc"
    18  	"google.golang.org/grpc/status"
    19  
    20  	pb "github.com/annwntech/go-micro/v2/server/grpc/proto"
    21  )
    22  
    23  // server is used to implement helloworld.GreeterServer.
    24  type testServer struct {
    25  	msgCount int
    26  }
    27  
    28  func (s *testServer) Handle(ctx context.Context, msg *pb.Request) error {
    29  	s.msgCount++
    30  	return nil
    31  }
    32  func (s *testServer) HandleError(ctx context.Context, msg *pb.Request) error {
    33  	return fmt.Errorf("fake")
    34  }
    35  
    36  // TestHello implements helloworld.GreeterServer
    37  func (s *testServer) CallPcre(ctx context.Context, req *pb.Request, rsp *pb.Response) error {
    38  	if req.Name == "Error" {
    39  		return &errors.Error{Id: "1", Code: 99, Detail: "detail"}
    40  	}
    41  
    42  	rsp.Msg = "Hello " + req.Name
    43  	return nil
    44  }
    45  
    46  // TestHello implements helloworld.GreeterServer
    47  func (s *testServer) CallPcreInvalid(ctx context.Context, req *pb.Request, rsp *pb.Response) error {
    48  	if req.Name == "Error" {
    49  		return &errors.Error{Id: "1", Code: 99, Detail: "detail"}
    50  	}
    51  
    52  	rsp.Msg = "Hello " + req.Name
    53  	return nil
    54  }
    55  
    56  // TestHello implements helloworld.GreeterServer
    57  func (s *testServer) Call(ctx context.Context, req *pb.Request, rsp *pb.Response) error {
    58  	if req.Name == "Error" {
    59  		return &errors.Error{Id: "1", Code: 99, Detail: "detail"}
    60  	}
    61  
    62  	rsp.Msg = "Hello " + req.Name
    63  	return nil
    64  }
    65  
    66  /*
    67  func BenchmarkServer(b *testing.B) {
    68  	r := rmemory.NewRegistry()
    69  	br := bmemory.NewBroker()
    70  	tr := tgrpc.NewTransport()
    71  	s := gsrv.NewServer(
    72  		server.Broker(br),
    73  		server.Name("foo"),
    74  		server.Registry(r),
    75  		server.Transport(tr),
    76  	)
    77  	c := gcli.NewClient(
    78  		client.Registry(r),
    79  		client.Broker(br),
    80  		client.Transport(tr),
    81  	)
    82  	ctx := context.TODO()
    83  
    84  	h := &testServer{}
    85  	pb.RegisterTestHandler(s, h)
    86  	if err := s.Start(); err != nil {
    87  		b.Fatalf("failed to start: %v", err)
    88  	}
    89  
    90  	// check registration
    91  	services, err := r.GetService("foo")
    92  	if err != nil || len(services) == 0 {
    93  		b.Fatalf("failed to get service: %v # %d", err, len(services))
    94  	}
    95  
    96  	defer func() {
    97  		if err := s.Stop(); err != nil {
    98  			b.Fatalf("failed to stop: %v", err)
    99  		}
   100  	}()
   101  
   102  	b.ResetTimer()
   103  	for i := 0; i < b.N; i++ {
   104  		c.Call()
   105  	}
   106  
   107  }
   108  */
   109  func TestGRPCServer(t *testing.T) {
   110  	r := rmemory.NewRegistry()
   111  	b := bmemory.NewBroker()
   112  	tr := tgrpc.NewTransport()
   113  	s := gsrv.NewServer(
   114  		server.Broker(b),
   115  		server.Name("foo"),
   116  		server.Registry(r),
   117  		server.Transport(tr),
   118  	)
   119  	c := gcli.NewClient(
   120  		client.Registry(r),
   121  		client.Broker(b),
   122  		client.Transport(tr),
   123  	)
   124  	ctx := context.TODO()
   125  
   126  	h := &testServer{}
   127  	pb.RegisterTestHandler(s, h)
   128  
   129  	if err := micro.RegisterSubscriber("test_topic", s, h.Handle); err != nil {
   130  		t.Fatal(err)
   131  	}
   132  	if err := micro.RegisterSubscriber("error_topic", s, h.HandleError); err != nil {
   133  		t.Fatal(err)
   134  	}
   135  
   136  	if err := s.Start(); err != nil {
   137  		t.Fatalf("failed to start: %v", err)
   138  	}
   139  
   140  	// check registration
   141  	services, err := r.GetService("foo")
   142  	if err != nil || len(services) == 0 {
   143  		t.Fatalf("failed to get service: %v # %d", err, len(services))
   144  	}
   145  
   146  	defer func() {
   147  		if err := s.Stop(); err != nil {
   148  			t.Fatalf("failed to stop: %v", err)
   149  		}
   150  	}()
   151  
   152  	pub := micro.NewEvent("test_topic", c)
   153  	pubErr := micro.NewEvent("error_topic", c)
   154  	cnt := 4
   155  	for i := 0; i < cnt; i++ {
   156  		if err = pub.Publish(ctx, &pb.Request{Name: fmt.Sprintf("msg %d", i)}); err != nil {
   157  			t.Fatal(err)
   158  		}
   159  	}
   160  
   161  	if h.msgCount != cnt {
   162  		t.Fatalf("pub/sub not work, or invalid message count %d", h.msgCount)
   163  	}
   164  	if err = pubErr.Publish(ctx, &pb.Request{}); err == nil {
   165  		t.Fatal("this must return error, as we return error from handler")
   166  	}
   167  
   168  	cc, err := grpc.Dial(s.Options().Address, grpc.WithInsecure())
   169  	if err != nil {
   170  		t.Fatalf("failed to dial server: %v", err)
   171  	}
   172  
   173  	testMethods := []string{"/test.Test/Call", "/go.micro.test.Test/Call"}
   174  
   175  	for _, method := range testMethods {
   176  		rsp := pb.Response{}
   177  
   178  		if err := cc.Invoke(context.Background(), method, &pb.Request{Name: "John"}, &rsp); err != nil {
   179  			t.Fatalf("error calling server: %v", err)
   180  		}
   181  
   182  		if rsp.Msg != "Hello John" {
   183  			t.Fatalf("Got unexpected response %v", rsp.Msg)
   184  		}
   185  	}
   186  
   187  	// Test grpc error
   188  	rsp := pb.Response{}
   189  
   190  	if err := cc.Invoke(context.Background(), "/test.Test/Call", &pb.Request{Name: "Error"}, &rsp); err != nil {
   191  		st, ok := status.FromError(err)
   192  		if !ok {
   193  			t.Fatalf("invalid error received %#+v\n", err)
   194  		}
   195  		verr, ok := st.Details()[0].(*errors.Error)
   196  		if !ok {
   197  			t.Fatalf("invalid error received %#+v\n", st.Details()[0])
   198  		}
   199  		if verr.Code != 99 && verr.Id != "1" && verr.Detail != "detail" {
   200  			t.Fatalf("invalid error received %#+v\n", verr)
   201  		}
   202  	}
   203  }