gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/grpc/xds/internal/xdsclient/controller/v2_cds_test.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 controller
    20  
    21  import (
    22  	"testing"
    23  	"time"
    24  
    25  	xdspb "gitee.com/ks-custle/core-gm/go-control-plane/envoy/api/v2"
    26  	corepb "gitee.com/ks-custle/core-gm/go-control-plane/envoy/api/v2/core"
    27  	"gitee.com/ks-custle/core-gm/grpc/internal/testutils"
    28  	"gitee.com/ks-custle/core-gm/grpc/xds/internal/xdsclient/xdsresource"
    29  	"gitee.com/ks-custle/core-gm/grpc/xds/internal/xdsclient/xdsresource/version"
    30  	anypb "github.com/golang/protobuf/ptypes/any"
    31  	"github.com/google/go-cmp/cmp/cmpopts"
    32  )
    33  
    34  const (
    35  	serviceName1 = "foo-service"
    36  	serviceName2 = "bar-service"
    37  )
    38  
    39  var (
    40  	badlyMarshaledCDSResponse = &xdspb.DiscoveryResponse{
    41  		Resources: []*anypb.Any{
    42  			{
    43  				TypeUrl: version.V2ClusterURL,
    44  				Value:   []byte{1, 2, 3, 4},
    45  			},
    46  		},
    47  		TypeUrl: version.V2ClusterURL,
    48  	}
    49  	goodCluster1 = &xdspb.Cluster{
    50  		Name:                 goodClusterName1,
    51  		ClusterDiscoveryType: &xdspb.Cluster_Type{Type: xdspb.Cluster_EDS},
    52  		EdsClusterConfig: &xdspb.Cluster_EdsClusterConfig{
    53  			EdsConfig: &corepb.ConfigSource{
    54  				ConfigSourceSpecifier: &corepb.ConfigSource_Ads{
    55  					Ads: &corepb.AggregatedConfigSource{},
    56  				},
    57  			},
    58  			ServiceName: serviceName1,
    59  		},
    60  		LbPolicy: xdspb.Cluster_ROUND_ROBIN,
    61  		LrsServer: &corepb.ConfigSource{
    62  			ConfigSourceSpecifier: &corepb.ConfigSource_Self{
    63  				Self: &corepb.SelfConfigSource{},
    64  			},
    65  		},
    66  	}
    67  	marshaledCluster1 = testutils.MarshalAny(goodCluster1)
    68  	goodCluster2      = &xdspb.Cluster{
    69  		Name:                 goodClusterName2,
    70  		ClusterDiscoveryType: &xdspb.Cluster_Type{Type: xdspb.Cluster_EDS},
    71  		EdsClusterConfig: &xdspb.Cluster_EdsClusterConfig{
    72  			EdsConfig: &corepb.ConfigSource{
    73  				ConfigSourceSpecifier: &corepb.ConfigSource_Ads{
    74  					Ads: &corepb.AggregatedConfigSource{},
    75  				},
    76  			},
    77  			ServiceName: serviceName2,
    78  		},
    79  		LbPolicy: xdspb.Cluster_ROUND_ROBIN,
    80  	}
    81  	marshaledCluster2 = testutils.MarshalAny(goodCluster2)
    82  	goodCDSResponse1  = &xdspb.DiscoveryResponse{
    83  		Resources: []*anypb.Any{
    84  			marshaledCluster1,
    85  		},
    86  		TypeUrl: version.V2ClusterURL,
    87  	}
    88  	goodCDSResponse2 = &xdspb.DiscoveryResponse{
    89  		Resources: []*anypb.Any{
    90  			marshaledCluster2,
    91  		},
    92  		TypeUrl: version.V2ClusterURL,
    93  	}
    94  )
    95  
    96  // TestCDSHandleResponse starts a fake xDS server, makes a ClientConn to it,
    97  // and creates a v2Client using it. Then, it registers a CDS watcher and tests
    98  // different CDS responses.
    99  func (s) TestCDSHandleResponse(t *testing.T) {
   100  	tests := []struct {
   101  		name          string
   102  		cdsResponse   *xdspb.DiscoveryResponse
   103  		wantErr       bool
   104  		wantUpdate    map[string]xdsresource.ClusterUpdateErrTuple
   105  		wantUpdateMD  xdsresource.UpdateMetadata
   106  		wantUpdateErr bool
   107  	}{
   108  		// Badly marshaled CDS response.
   109  		{
   110  			name:        "badly-marshaled-response",
   111  			cdsResponse: badlyMarshaledCDSResponse,
   112  			wantErr:     true,
   113  			wantUpdate:  nil,
   114  			wantUpdateMD: xdsresource.UpdateMetadata{
   115  				Status: xdsresource.ServiceStatusNACKed,
   116  				ErrState: &xdsresource.UpdateErrorMetadata{
   117  					Err: cmpopts.AnyError,
   118  				},
   119  			},
   120  			wantUpdateErr: false,
   121  		},
   122  		// Response contains one good cluster we are not interested in.
   123  		{
   124  			name:        "one-uninteresting-cluster",
   125  			cdsResponse: goodCDSResponse2,
   126  			wantErr:     false,
   127  			wantUpdate: map[string]xdsresource.ClusterUpdateErrTuple{
   128  				goodClusterName2: {Update: xdsresource.ClusterUpdate{ClusterName: goodClusterName2, EDSServiceName: serviceName2, Raw: marshaledCluster2}},
   129  			},
   130  			wantUpdateMD: xdsresource.UpdateMetadata{
   131  				Status: xdsresource.ServiceStatusACKed,
   132  			},
   133  			wantUpdateErr: false,
   134  		},
   135  		// Response contains one cluster and it is good.
   136  		{
   137  			name:        "one-good-cluster",
   138  			cdsResponse: goodCDSResponse1,
   139  			wantErr:     false,
   140  			wantUpdate: map[string]xdsresource.ClusterUpdateErrTuple{
   141  				goodClusterName1: {Update: xdsresource.ClusterUpdate{ClusterName: goodClusterName1, EDSServiceName: serviceName1, EnableLRS: true, Raw: marshaledCluster1}},
   142  			},
   143  			wantUpdateMD: xdsresource.UpdateMetadata{
   144  				Status: xdsresource.ServiceStatusACKed,
   145  			},
   146  			wantUpdateErr: false,
   147  		},
   148  	}
   149  	for _, test := range tests {
   150  		t.Run(test.name, func(t *testing.T) {
   151  			testWatchHandle(t, &watchHandleTestcase{
   152  				rType:        xdsresource.ClusterResource,
   153  				resourceName: goodClusterName1,
   154  
   155  				responseToHandle: test.cdsResponse,
   156  				wantHandleErr:    test.wantErr,
   157  				wantUpdate:       test.wantUpdate,
   158  				wantUpdateMD:     test.wantUpdateMD,
   159  				wantUpdateErr:    test.wantUpdateErr,
   160  			})
   161  		})
   162  	}
   163  }
   164  
   165  // TestCDSHandleResponseWithoutWatch tests the case where the v2Client receives
   166  // a CDS response without a registered watcher.
   167  func (s) TestCDSHandleResponseWithoutWatch(t *testing.T) {
   168  	fakeServer, cleanup := startServer(t)
   169  	defer cleanup()
   170  
   171  	v2c, err := newTestController(&testUpdateReceiver{
   172  		f: func(xdsresource.ResourceType, map[string]interface{}, xdsresource.UpdateMetadata) {},
   173  	}, fakeServer.Address, goodNodeProto, func(int) time.Duration { return 0 }, nil)
   174  	if err != nil {
   175  		t.Fatal(err)
   176  	}
   177  	defer v2c.Close()
   178  
   179  	if _, _, _, err := v2c.handleResponse(badResourceTypeInLDSResponse); err == nil {
   180  		t.Fatal("v2c.handleCDSResponse() succeeded, should have failed")
   181  	}
   182  
   183  	if _, _, _, err := v2c.handleResponse(goodCDSResponse1); err != nil {
   184  		t.Fatal("v2c.handleCDSResponse() succeeded, should have failed")
   185  	}
   186  }