github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/internal/xtest/ydb_grpc_mocks.go (about)

     1  package xtest
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net"
     7  	"reflect"
     8  	"strconv"
     9  	"time"
    10  
    11  	"github.com/rekby/fixenv"
    12  	"github.com/rekby/fixenv/sf"
    13  	"github.com/ydb-platform/ydb-go-genproto/Ydb_Discovery_V1"
    14  	"github.com/ydb-platform/ydb-go-genproto/Ydb_Topic_V1"
    15  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb"
    16  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Discovery"
    17  	"github.com/ydb-platform/ydb-go-genproto/protos/Ydb_Operations"
    18  	"google.golang.org/grpc"
    19  	"google.golang.org/protobuf/types/known/anypb"
    20  )
    21  
    22  func GrpcMockTopicConnString(e fixenv.Env, topicServiceImpl Ydb_Topic_V1.TopicServiceServer) string {
    23  	v := reflect.ValueOf(topicServiceImpl)
    24  	addr := v.Pointer()
    25  
    26  	var f fixenv.GenericFixtureFunction[string] = func() (*fixenv.GenericResult[string], error) {
    27  		listener := sf.LocalTCPListenerNamed(e, fmt.Sprintf("ydb-grpc-mock-topic-%v", addr))
    28  		connString := fmt.Sprintf("grpc://%s/local", listener.Addr())
    29  
    30  		mock, err := newGrpcMock(listener, topicServiceImpl)
    31  		if err != nil {
    32  			return nil, fmt.Errorf("failed to create grpc mock: %w", err)
    33  		}
    34  
    35  		clean := func() {
    36  			_ = mock.Close()
    37  		}
    38  
    39  		return fixenv.NewGenericResultWithCleanup(connString, clean), nil
    40  	}
    41  
    42  	return fixenv.CacheResult(e, f, fixenv.CacheOptions{CacheKey: addr})
    43  }
    44  
    45  type grpcMock struct {
    46  	listener   net.Listener
    47  	grpcServer *grpc.Server
    48  	stopChan   chan error
    49  }
    50  
    51  func (m *grpcMock) Close() error {
    52  	m.grpcServer.Stop()
    53  
    54  	return m.listener.Close()
    55  }
    56  
    57  func newGrpcMock(listener net.Listener, topicServiceImpl Ydb_Topic_V1.TopicServiceServer) (*grpcMock, error) {
    58  	res := &grpcMock{
    59  		listener:   listener,
    60  		grpcServer: grpc.NewServer(),
    61  		stopChan:   make(chan error, 1),
    62  	}
    63  
    64  	host, portS, err := net.SplitHostPort(listener.Addr().String())
    65  	if err != nil {
    66  		return nil, fmt.Errorf("failed to split host port addresses: %w", err)
    67  	}
    68  
    69  	port, err := strconv.ParseUint(portS, 10, 32)
    70  	if err != nil {
    71  		return nil, fmt.Errorf("failed convert port to int: %w", err)
    72  	}
    73  	discoveryService := newMockDiscoveryService(host, uint32(port))
    74  
    75  	Ydb_Discovery_V1.RegisterDiscoveryServiceServer(res.grpcServer, discoveryService)
    76  	Ydb_Topic_V1.RegisterTopicServiceServer(res.grpcServer, topicServiceImpl)
    77  
    78  	go func() {
    79  		res.stopChan <- res.grpcServer.Serve(res.listener)
    80  	}()
    81  
    82  	select {
    83  	case <-res.stopChan:
    84  		return nil, err
    85  	case <-time.After(time.Millisecond):
    86  		return res, nil
    87  	}
    88  }
    89  
    90  type mockDiscoveryService struct {
    91  	Ydb_Discovery_V1.UnimplementedDiscoveryServiceServer
    92  	host string
    93  	port uint32
    94  }
    95  
    96  func newMockDiscoveryService(host string, port uint32) *mockDiscoveryService {
    97  	return &mockDiscoveryService{
    98  		host: host,
    99  		port: port,
   100  	}
   101  }
   102  
   103  func (m mockDiscoveryService) ListEndpoints(
   104  	ctx context.Context,
   105  	request *Ydb_Discovery.ListEndpointsRequest,
   106  ) (*Ydb_Discovery.ListEndpointsResponse, error) {
   107  	res := &Ydb_Discovery.ListEndpointsResult{
   108  		Endpoints: []*Ydb_Discovery.EndpointInfo{
   109  			{
   110  				Address:    m.host,
   111  				Port:       m.port,
   112  				LoadFactor: 0,
   113  				Ssl:        false,
   114  				Service:    nil,
   115  				Location:   "",
   116  				NodeId:     1,
   117  				IpV4:       []string{"127.0.0.1"},
   118  			},
   119  		},
   120  		SelfLocation: "",
   121  	}
   122  	resp := &Ydb_Discovery.ListEndpointsResponse{
   123  		Operation: &Ydb_Operations.Operation{
   124  			Id:     "test-list-operation",
   125  			Ready:  true,
   126  			Status: Ydb.StatusIds_SUCCESS,
   127  			Result: &anypb.Any{},
   128  		},
   129  	}
   130  	err := resp.GetOperation().GetResult().MarshalFrom(res)
   131  
   132  	return resp, err
   133  }
   134  
   135  func (m mockDiscoveryService) WhoAmI(
   136  	ctx context.Context,
   137  	request *Ydb_Discovery.WhoAmIRequest,
   138  ) (*Ydb_Discovery.WhoAmIResponse, error) {
   139  	panic("unimplemented")
   140  }