github.com/cloudwego/kitex@v0.9.0/pkg/generic/binary_test/generic_init.go (about)

     1  /*
     2   * Copyright 2021 CloudWeGo Authors
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  // Package test ...
    18  package test
    19  
    20  import (
    21  	"context"
    22  	"encoding/binary"
    23  	"errors"
    24  	"fmt"
    25  	"net"
    26  	"time"
    27  
    28  	"github.com/apache/thrift/lib/go/thrift"
    29  
    30  	"github.com/cloudwego/kitex/client"
    31  	"github.com/cloudwego/kitex/client/genericclient"
    32  	kt "github.com/cloudwego/kitex/internal/mocks/thrift"
    33  	"github.com/cloudwego/kitex/internal/test"
    34  	"github.com/cloudwego/kitex/pkg/generic"
    35  	"github.com/cloudwego/kitex/pkg/serviceinfo"
    36  	"github.com/cloudwego/kitex/pkg/utils"
    37  	"github.com/cloudwego/kitex/server"
    38  	"github.com/cloudwego/kitex/server/genericserver"
    39  )
    40  
    41  var (
    42  	reqMsg  = "Hello Kitex"
    43  	respMsg = "Hi, I am Kitex"
    44  	errResp = "Test Error"
    45  )
    46  
    47  func newGenericClient(destService string, g generic.Generic, targetIPPort string, opts ...client.Option) genericclient.Client {
    48  	opts = append(opts, client.WithHostPorts(targetIPPort))
    49  	genericCli, _ := genericclient.NewClient(destService, g, opts...)
    50  	return genericCli
    51  }
    52  
    53  func newGenericServer(g generic.Generic, addr net.Addr, handler generic.Service) server.Server {
    54  	var opts []server.Option
    55  	opts = append(opts, server.WithServiceAddr(addr), server.WithExitWaitTime(time.Microsecond*10))
    56  	svr := genericserver.NewServer(handler, g, opts...)
    57  	go func() {
    58  		err := svr.Run()
    59  		if err != nil {
    60  			panic(err)
    61  		}
    62  	}()
    63  	test.WaitServerStart(addr.String())
    64  	return svr
    65  }
    66  
    67  // GenericServiceImpl ...
    68  type GenericServiceImpl struct{}
    69  
    70  // GenericCall ...
    71  func (g *GenericServiceImpl) GenericCall(ctx context.Context, method string, request interface{}) (response interface{}, err error) {
    72  	req := request.([]byte)
    73  	fmt.Printf("Recv: %v\n", string(req[8+len(method):]))
    74  
    75  	buf := genBinaryResp(method)
    76  	return buf, nil
    77  }
    78  
    79  // GenericServiceErrorImpl ...
    80  type GenericServiceErrorImpl struct{}
    81  
    82  // GenericCall ...
    83  func (g *GenericServiceErrorImpl) GenericCall(ctx context.Context, method string, request interface{}) (response interface{}, err error) {
    84  	return response, errors.New(errResp)
    85  }
    86  
    87  // GenericServiceMockImpl ...
    88  type GenericServiceMockImpl struct{}
    89  
    90  // GenericCall ...
    91  func (g *GenericServiceMockImpl) GenericCall(ctx context.Context, method string, request interface{}) (response interface{}, err error) {
    92  	rc := utils.NewThriftMessageCodec()
    93  	buf := request.([]byte)
    94  
    95  	var args2 kt.MockTestArgs
    96  	mth, seqID, err := rc.Decode(buf, &args2)
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  
   101  	if args2.Req.Msg != reqMsg {
   102  		return nil, fmt.Errorf("msg is not %s", reqMsg)
   103  	}
   104  
   105  	resp := respMsg
   106  	result := kt.NewMockTestResult()
   107  	result.Success = &resp
   108  
   109  	buf, err = rc.Encode(mth, thrift.REPLY, seqID, result)
   110  	return buf, err
   111  }
   112  
   113  // NewMockServer normal server
   114  func NewMockServer(handler kt.Mock, addr net.Addr, opts ...server.Option) server.Server {
   115  	var options []server.Option
   116  	opts = append(opts, server.WithServiceAddr(addr), server.WithExitWaitTime(time.Microsecond*10))
   117  	options = append(options, opts...)
   118  
   119  	svr := server.NewServer(options...)
   120  	if err := svr.RegisterService(serviceInfo(), handler); err != nil {
   121  		panic(err)
   122  	}
   123  	go func() {
   124  		err := svr.Run()
   125  		if err != nil {
   126  			panic(err)
   127  		}
   128  	}()
   129  	test.WaitServerStart(addr.String())
   130  	return svr
   131  }
   132  
   133  func serviceInfo() *serviceinfo.ServiceInfo {
   134  	destService := "Mock"
   135  	handlerType := (*kt.Mock)(nil)
   136  	methods := map[string]serviceinfo.MethodInfo{
   137  		"Test": serviceinfo.NewMethodInfo(testHandler, newMockTestArgs, newMockTestResult, false),
   138  	}
   139  	svcInfo := &serviceinfo.ServiceInfo{
   140  		ServiceName: destService,
   141  		HandlerType: handlerType,
   142  		Methods:     methods,
   143  		Extra:       make(map[string]interface{}),
   144  	}
   145  	return svcInfo
   146  }
   147  
   148  func newMockTestArgs() interface{} {
   149  	return kt.NewMockTestArgs()
   150  }
   151  
   152  func newMockTestResult() interface{} {
   153  	return kt.NewMockTestResult()
   154  }
   155  
   156  func testHandler(ctx context.Context, handler, arg, result interface{}) error {
   157  	realArg := arg.(*kt.MockTestArgs)
   158  	realResult := result.(*kt.MockTestResult)
   159  	success, err := handler.(kt.Mock).Test(ctx, realArg.Req)
   160  	if err != nil {
   161  		return err
   162  	}
   163  	realResult.Success = &success
   164  	return nil
   165  }
   166  
   167  // MockImpl is used for test
   168  type MockImpl struct{}
   169  
   170  // Test ...
   171  func (m *MockImpl) Test(ctx context.Context, req *kt.MockReq) (r string, err error) {
   172  	if req.Msg != reqMsg {
   173  		return "", fmt.Errorf("msg is not %s", reqMsg)
   174  	}
   175  	return respMsg, nil
   176  }
   177  
   178  // ExceptionTest ...
   179  func (m *MockImpl) ExceptionTest(ctx context.Context, req *kt.MockReq) (r string, err error) {
   180  	return "", kt.NewException()
   181  }
   182  
   183  func genBinaryResp(method string) []byte {
   184  	idx := 0
   185  	buf := make([]byte, 12+len(method)+len(respMsg))
   186  	binary.BigEndian.PutUint32(buf, thrift.VERSION_1)
   187  	idx += 4
   188  	binary.BigEndian.PutUint32(buf[idx:idx+4], uint32(len(method)))
   189  	idx += 4
   190  	copy(buf[idx:idx+len(method)], method)
   191  	idx += len(method)
   192  	binary.BigEndian.PutUint32(buf[idx:idx+4], 100)
   193  	idx += 4
   194  	copy(buf[idx:idx+len(respMsg)], respMsg)
   195  	return buf
   196  }