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  }