github.com/lingyao2333/mo-zero@v1.4.1/zrpc/client_test.go (about) 1 package zrpc 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 "net" 8 "testing" 9 "time" 10 11 "github.com/lingyao2333/mo-zero/core/discov" 12 "github.com/lingyao2333/mo-zero/core/logx" 13 "github.com/lingyao2333/mo-zero/zrpc/internal/mock" 14 "github.com/stretchr/testify/assert" 15 "google.golang.org/grpc" 16 "google.golang.org/grpc/codes" 17 "google.golang.org/grpc/credentials/insecure" 18 "google.golang.org/grpc/status" 19 "google.golang.org/grpc/test/bufconn" 20 ) 21 22 func init() { 23 logx.Disable() 24 } 25 26 func dialer() func(context.Context, string) (net.Conn, error) { 27 listener := bufconn.Listen(1024 * 1024) 28 server := grpc.NewServer() 29 mock.RegisterDepositServiceServer(server, &mock.DepositServer{}) 30 31 go func() { 32 if err := server.Serve(listener); err != nil { 33 log.Fatal(err) 34 } 35 }() 36 37 return func(context.Context, string) (net.Conn, error) { 38 return listener.Dial() 39 } 40 } 41 42 func TestDepositServer_Deposit(t *testing.T) { 43 tests := []struct { 44 name string 45 amount float32 46 res *mock.DepositResponse 47 errCode codes.Code 48 errMsg string 49 }{ 50 { 51 "invalid request with negative amount", 52 -1.11, 53 nil, 54 codes.InvalidArgument, 55 fmt.Sprintf("cannot deposit %v", -1.11), 56 }, 57 { 58 "valid request with non negative amount", 59 0.00, 60 &mock.DepositResponse{Ok: true}, 61 codes.OK, 62 "", 63 }, 64 { 65 "valid request with long handling time", 66 2000.00, 67 nil, 68 codes.DeadlineExceeded, 69 "context deadline exceeded", 70 }, 71 } 72 73 directClient := MustNewClient( 74 RpcClientConf{ 75 Endpoints: []string{"foo"}, 76 App: "foo", 77 Token: "bar", 78 Timeout: 1000, 79 }, 80 WithDialOption(grpc.WithContextDialer(dialer())), 81 WithUnaryClientInterceptor(func(ctx context.Context, method string, req, reply interface{}, 82 cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { 83 return invoker(ctx, method, req, reply, cc, opts...) 84 }), 85 ) 86 nonBlockClient := MustNewClient( 87 RpcClientConf{ 88 Endpoints: []string{"foo"}, 89 App: "foo", 90 Token: "bar", 91 Timeout: 1000, 92 NonBlock: true, 93 }, 94 WithDialOption(grpc.WithContextDialer(dialer())), 95 WithUnaryClientInterceptor(func(ctx context.Context, method string, req, reply interface{}, 96 cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { 97 return invoker(ctx, method, req, reply, cc, opts...) 98 }), 99 ) 100 tarConfClient := MustNewClient( 101 RpcClientConf{ 102 Target: "foo", 103 App: "foo", 104 Token: "bar", 105 Timeout: 1000, 106 }, 107 WithDialOption(grpc.WithTransportCredentials(insecure.NewCredentials())), 108 WithDialOption(grpc.WithContextDialer(dialer())), 109 WithUnaryClientInterceptor(func(ctx context.Context, method string, req, reply interface{}, 110 cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { 111 return invoker(ctx, method, req, reply, cc, opts...) 112 }), 113 ) 114 targetClient, err := NewClientWithTarget("foo", 115 WithDialOption(grpc.WithTransportCredentials(insecure.NewCredentials())), 116 WithDialOption(grpc.WithContextDialer(dialer())), WithUnaryClientInterceptor( 117 func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, 118 invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { 119 return invoker(ctx, method, req, reply, cc, opts...) 120 }), WithTimeout(1000*time.Millisecond)) 121 assert.Nil(t, err) 122 clients := []Client{ 123 directClient, 124 nonBlockClient, 125 tarConfClient, 126 targetClient, 127 } 128 SetClientSlowThreshold(time.Second) 129 130 for _, tt := range tests { 131 tt := tt 132 for _, client := range clients { 133 client := client 134 t.Run(tt.name, func(t *testing.T) { 135 t.Parallel() 136 cli := mock.NewDepositServiceClient(client.Conn()) 137 request := &mock.DepositRequest{Amount: tt.amount} 138 response, err := cli.Deposit(context.Background(), request) 139 if response != nil { 140 assert.True(t, len(response.String()) > 0) 141 if response.GetOk() != tt.res.GetOk() { 142 t.Error("response: expected", tt.res.GetOk(), "received", response.GetOk()) 143 } 144 } 145 if err != nil { 146 if e, ok := status.FromError(err); ok { 147 if e.Code() != tt.errCode { 148 t.Error("error code: expected", codes.InvalidArgument, "received", e.Code()) 149 } 150 if e.Message() != tt.errMsg { 151 t.Error("error message: expected", tt.errMsg, "received", e.Message()) 152 } 153 } 154 } 155 }) 156 } 157 } 158 } 159 160 func TestNewClientWithError(t *testing.T) { 161 _, err := NewClient( 162 RpcClientConf{ 163 App: "foo", 164 Token: "bar", 165 Timeout: 1000, 166 }, 167 WithDialOption(grpc.WithTransportCredentials(insecure.NewCredentials())), 168 WithDialOption(grpc.WithContextDialer(dialer())), 169 WithUnaryClientInterceptor(func(ctx context.Context, method string, req, reply interface{}, 170 cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { 171 return invoker(ctx, method, req, reply, cc, opts...) 172 }), 173 ) 174 assert.NotNil(t, err) 175 176 _, err = NewClient( 177 RpcClientConf{ 178 Etcd: discov.EtcdConf{ 179 Hosts: []string{"localhost:2379"}, 180 Key: "mock", 181 }, 182 App: "foo", 183 Token: "bar", 184 Timeout: 1, 185 }, 186 WithDialOption(grpc.WithTransportCredentials(insecure.NewCredentials())), 187 WithDialOption(grpc.WithContextDialer(dialer())), 188 WithUnaryClientInterceptor(func(ctx context.Context, method string, req, reply interface{}, 189 cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { 190 return invoker(ctx, method, req, reply, cc, opts...) 191 }), 192 ) 193 assert.NotNil(t, err) 194 }