github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/xds/internal/xdsclient/loadreport_test.go (about)

     1  /*
     2   *
     3   * Copyright 2020 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 xdsclient
    20  
    21  import (
    22  	"context"
    23  	"testing"
    24  	"time"
    25  
    26  	durationpb "github.com/golang/protobuf/ptypes/duration"
    27  	"github.com/google/go-cmp/cmp"
    28  	v2corepb "github.com/hxx258456/ccgo/go-control-plane/envoy/api/v2/core"
    29  	endpointpb "github.com/hxx258456/ccgo/go-control-plane/envoy/api/v2/endpoint"
    30  	lrspb "github.com/hxx258456/ccgo/go-control-plane/envoy/service/load_stats/v2"
    31  	grpc "github.com/hxx258456/ccgo/grpc"
    32  	"github.com/hxx258456/ccgo/grpc/codes"
    33  	"github.com/hxx258456/ccgo/grpc/credentials/insecure"
    34  	"github.com/hxx258456/ccgo/grpc/status"
    35  	"github.com/hxx258456/ccgo/grpc/xds/internal/testutils/fakeserver"
    36  	"github.com/hxx258456/ccgo/grpc/xds/internal/xdsclient/bootstrap"
    37  	"github.com/hxx258456/ccgo/grpc/xds/internal/xdsclient/xdsresource/version"
    38  	"google.golang.org/protobuf/testing/protocmp"
    39  
    40  	_ "github.com/hxx258456/ccgo/grpc/xds/internal/xdsclient/controller/version/v2" // Register the v2 xDS API client.
    41  )
    42  
    43  const (
    44  	defaultClientWatchExpiryTimeout = 15 * time.Second
    45  )
    46  
    47  func (s) TestLRSClient(t *testing.T) {
    48  	fs, sCleanup, err := fakeserver.StartServer()
    49  	if err != nil {
    50  		t.Fatalf("failed to start fake xDS server: %v", err)
    51  	}
    52  	defer sCleanup()
    53  
    54  	xdsC, err := NewWithConfigForTesting(&bootstrap.Config{
    55  		XDSServer: &bootstrap.ServerConfig{
    56  			ServerURI:    fs.Address,
    57  			Creds:        grpc.WithTransportCredentials(insecure.NewCredentials()),
    58  			TransportAPI: version.TransportV2,
    59  			NodeProto:    &v2corepb.Node{},
    60  		},
    61  	}, defaultClientWatchExpiryTimeout)
    62  	if err != nil {
    63  		t.Fatalf("failed to create xds client: %v", err)
    64  	}
    65  	defer xdsC.Close()
    66  	ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
    67  	defer cancel()
    68  
    69  	// Report to the same address should not create new ClientConn.
    70  	store1, lrsCancel1 := xdsC.ReportLoad(fs.Address)
    71  	defer lrsCancel1()
    72  
    73  	if u, err := fs.NewConnChan.Receive(ctx); err != nil {
    74  		t.Errorf("unexpected timeout: %v, %v, want NewConn", u, err)
    75  	}
    76  
    77  	sCtx, sCancel := context.WithTimeout(context.Background(), defaultTestShortTimeout)
    78  	defer sCancel()
    79  	if u, err := fs.NewConnChan.Receive(sCtx); err != context.DeadlineExceeded {
    80  		t.Errorf("unexpected NewConn: %v, %v, want channel recv timeout", u, err)
    81  	}
    82  
    83  	fs2, sCleanup2, err := fakeserver.StartServer()
    84  	if err != nil {
    85  		t.Fatalf("failed to start fake xDS server: %v", err)
    86  	}
    87  	defer sCleanup2()
    88  
    89  	// Report to a different address should create new ClientConn.
    90  	store2, lrsCancel2 := xdsC.ReportLoad(fs2.Address)
    91  	defer lrsCancel2()
    92  	if u, err := fs2.NewConnChan.Receive(ctx); err != nil {
    93  		t.Errorf("unexpected timeout: %v, %v, want NewConn", u, err)
    94  	}
    95  
    96  	if store1 == store2 {
    97  		t.Fatalf("got same store for different servers, want different")
    98  	}
    99  
   100  	if u, err := fs2.LRSRequestChan.Receive(ctx); err != nil {
   101  		t.Errorf("unexpected timeout: %v, %v, want NewConn", u, err)
   102  	}
   103  	store2.PerCluster("cluster", "eds").CallDropped("test")
   104  
   105  	// Send one resp to the client.
   106  	fs2.LRSResponseChan <- &fakeserver.Response{
   107  		Resp: &lrspb.LoadStatsResponse{
   108  			SendAllClusters:       true,
   109  			LoadReportingInterval: &durationpb.Duration{Nanos: 50000000},
   110  		},
   111  	}
   112  
   113  	// Server should receive a req with the loads.
   114  	u, err := fs2.LRSRequestChan.Receive(ctx)
   115  	if err != nil {
   116  		t.Fatalf("unexpected LRS request: %v, %v, want error canceled", u, err)
   117  	}
   118  	receivedLoad := u.(*fakeserver.Request).Req.(*lrspb.LoadStatsRequest).ClusterStats
   119  	if len(receivedLoad) <= 0 {
   120  		t.Fatalf("unexpected load received, want load for cluster, eds, dropped for test")
   121  	}
   122  	receivedLoad[0].LoadReportInterval = nil
   123  	want := &endpointpb.ClusterStats{
   124  		ClusterName:          "cluster",
   125  		ClusterServiceName:   "eds",
   126  		TotalDroppedRequests: 1,
   127  		DroppedRequests:      []*endpointpb.ClusterStats_DroppedRequests{{Category: "test", DroppedCount: 1}},
   128  	}
   129  	if d := cmp.Diff(want, receivedLoad[0], protocmp.Transform()); d != "" {
   130  		t.Fatalf("unexpected load received, want load for cluster, eds, dropped for test, diff (-want +got):\n%s", d)
   131  	}
   132  
   133  	// Cancel this load reporting stream, server should see error canceled.
   134  	lrsCancel2()
   135  
   136  	// Server should receive a stream canceled error.
   137  	if u, err := fs2.LRSRequestChan.Receive(ctx); err != nil || status.Code(u.(*fakeserver.Request).Err) != codes.Canceled {
   138  		t.Errorf("unexpected LRS request: %v, %v, want error canceled", u, err)
   139  	}
   140  }