client_test.go 6.3 KB

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