google.golang.org/grpc@v1.74.2/xds/internal/testutils/fakeclient/client.go (about)

     1  /*
     2   *
     3   * Copyright 2019 gRPC authors.
     4   *
     5   * Licensed under the Apache License, Version 2.0 (the "License");
     6   * you may not use this file except in compliance with the License.
     7   * You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   *
    17   */
    18  
    19  // Package fakeclient provides a fake implementation of an xDS client.
    20  package fakeclient
    21  
    22  import (
    23  	"context"
    24  
    25  	"google.golang.org/grpc/internal/testutils"
    26  	"google.golang.org/grpc/internal/xds/bootstrap"
    27  	"google.golang.org/grpc/xds/internal/clients"
    28  	"google.golang.org/grpc/xds/internal/clients/lrsclient"
    29  	"google.golang.org/grpc/xds/internal/xdsclient"
    30  )
    31  
    32  // Client is a fake implementation of an xds client. It exposes a bunch of
    33  // channels to signal the occurrence of various events.
    34  type Client struct {
    35  	// Embed XDSClient so this fake client implements the interface, but it's
    36  	// never set (it's always nil). This may cause nil panic since not all the
    37  	// methods are implemented.
    38  	xdsclient.XDSClient
    39  
    40  	name         string
    41  	loadReportCh *testutils.Channel
    42  	lrsCancelCh  *testutils.Channel
    43  	loadStore    *lrsclient.LoadStore
    44  	bootstrapCfg *bootstrap.Config
    45  }
    46  
    47  // ReportLoadArgs wraps the arguments passed to ReportLoad.
    48  type ReportLoadArgs struct {
    49  	// Server is the name of the server to which the load is reported.
    50  	Server *bootstrap.ServerConfig
    51  }
    52  
    53  type transportBuilder struct {
    54  }
    55  
    56  func (*transportBuilder) Build(clients.ServerIdentifier) (clients.Transport, error) {
    57  	return &transport{}, nil
    58  }
    59  
    60  type transport struct {
    61  }
    62  
    63  func (*transport) NewStream(context.Context, string) (clients.Stream, error) {
    64  	return &stream{}, nil
    65  }
    66  
    67  func (*transport) Close() {
    68  }
    69  
    70  type stream struct {
    71  }
    72  
    73  func (*stream) Send([]byte) error {
    74  	return nil
    75  }
    76  
    77  func (*stream) Recv() ([]byte, error) {
    78  	return nil, nil
    79  
    80  }
    81  
    82  // ReportLoad starts reporting load about clusterName to server.
    83  func (xdsC *Client) ReportLoad(server *bootstrap.ServerConfig) (loadStore *lrsclient.LoadStore, cancel func(context.Context)) {
    84  	lrsClient, _ := lrsclient.New(lrsclient.Config{Node: clients.Node{ID: "fake-node-id"}, TransportBuilder: &transportBuilder{}})
    85  	xdsC.loadStore, _ = lrsClient.ReportLoad(clients.ServerIdentifier{ServerURI: server.ServerURI()})
    86  
    87  	xdsC.loadReportCh.Send(ReportLoadArgs{Server: server})
    88  
    89  	return xdsC.loadStore, func(ctx context.Context) {
    90  		xdsC.loadStore.Stop(ctx)
    91  		xdsC.lrsCancelCh.Send(nil)
    92  	}
    93  }
    94  
    95  // WaitForCancelReportLoad waits for a load report to be cancelled and returns
    96  // context.DeadlineExceeded otherwise.
    97  func (xdsC *Client) WaitForCancelReportLoad(ctx context.Context) error {
    98  	_, err := xdsC.lrsCancelCh.Receive(ctx)
    99  	return err
   100  }
   101  
   102  // LoadStore returns the underlying load data store.
   103  func (xdsC *Client) LoadStore() *lrsclient.LoadStore {
   104  	return xdsC.loadStore
   105  }
   106  
   107  // WaitForReportLoad waits for ReportLoad to be invoked on this client and
   108  // returns the arguments passed to it.
   109  func (xdsC *Client) WaitForReportLoad(ctx context.Context) (ReportLoadArgs, error) {
   110  	val, err := xdsC.loadReportCh.Receive(ctx)
   111  	if err != nil {
   112  		return ReportLoadArgs{}, err
   113  	}
   114  	return val.(ReportLoadArgs), nil
   115  }
   116  
   117  // BootstrapConfig returns the bootstrap config.
   118  func (xdsC *Client) BootstrapConfig() *bootstrap.Config {
   119  	return xdsC.bootstrapCfg
   120  }
   121  
   122  // SetBootstrapConfig updates the bootstrap config.
   123  func (xdsC *Client) SetBootstrapConfig(cfg *bootstrap.Config) {
   124  	xdsC.bootstrapCfg = cfg
   125  }
   126  
   127  // Name returns the name of the xds client.
   128  func (xdsC *Client) Name() string {
   129  	return xdsC.name
   130  }
   131  
   132  // NewClient returns a new fake xds client.
   133  func NewClient() *Client {
   134  	return NewClientWithName("")
   135  }
   136  
   137  // NewClientWithName returns a new fake xds client with the provided name. This
   138  // is used in cases where multiple clients are created in the tests and we need
   139  // to make sure the client is created for the expected balancer name.
   140  func NewClientWithName(name string) *Client {
   141  	return &Client{
   142  		name:         name,
   143  		loadReportCh: testutils.NewChannel(),
   144  		lrsCancelCh:  testutils.NewChannel(),
   145  		bootstrapCfg: &bootstrap.Config{},
   146  	}
   147  }