client_test.go 5.7 KB

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