gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/grpc/xds/internal/xdsclient/controller/v2_lds_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  	v2xdspb "gitee.com/ks-custle/core-gm/go-control-plane/envoy/api/v2"
    26  	"gitee.com/ks-custle/core-gm/grpc/xds/internal/xdsclient/xdsresource"
    27  	"github.com/google/go-cmp/cmp/cmpopts"
    28  )
    29  
    30  // TestLDSHandleResponse starts a fake xDS server, makes a ClientConn to it,
    31  // and creates a client using it. Then, it registers a watchLDS and tests
    32  // different LDS responses.
    33  func (s) TestLDSHandleResponse(t *testing.T) {
    34  	tests := []struct {
    35  		name          string
    36  		ldsResponse   *v2xdspb.DiscoveryResponse
    37  		wantErr       bool
    38  		wantUpdate    map[string]xdsresource.ListenerUpdateErrTuple
    39  		wantUpdateMD  xdsresource.UpdateMetadata
    40  		wantUpdateErr bool
    41  	}{
    42  		// Badly marshaled LDS response.
    43  		{
    44  			name:        "badly-marshaled-response",
    45  			ldsResponse: badlyMarshaledLDSResponse,
    46  			wantErr:     true,
    47  			wantUpdate:  nil,
    48  			wantUpdateMD: xdsresource.UpdateMetadata{
    49  				Status: xdsresource.ServiceStatusNACKed,
    50  				ErrState: &xdsresource.UpdateErrorMetadata{
    51  					Err: cmpopts.AnyError,
    52  				},
    53  			},
    54  			wantUpdateErr: false,
    55  		},
    56  		// Response does not contain Listener proto.
    57  		{
    58  			name:        "no-listener-proto-in-response",
    59  			ldsResponse: badResourceTypeInLDSResponse,
    60  			wantErr:     true,
    61  			wantUpdate:  nil,
    62  			wantUpdateMD: xdsresource.UpdateMetadata{
    63  				Status: xdsresource.ServiceStatusNACKed,
    64  				ErrState: &xdsresource.UpdateErrorMetadata{
    65  					Err: cmpopts.AnyError,
    66  				},
    67  			},
    68  			wantUpdateErr: false,
    69  		},
    70  		// No APIListener in the response. Just one test case here for a bad
    71  		// ApiListener, since the others are covered in
    72  		// TestGetRouteConfigNameFromListener.
    73  		{
    74  			name:        "no-apiListener-in-response",
    75  			ldsResponse: noAPIListenerLDSResponse,
    76  			wantErr:     true,
    77  			wantUpdate: map[string]xdsresource.ListenerUpdateErrTuple{
    78  				goodLDSTarget1: {Err: cmpopts.AnyError},
    79  			},
    80  			wantUpdateMD: xdsresource.UpdateMetadata{
    81  				Status: xdsresource.ServiceStatusNACKed,
    82  				ErrState: &xdsresource.UpdateErrorMetadata{
    83  					Err: cmpopts.AnyError,
    84  				},
    85  			},
    86  			wantUpdateErr: false,
    87  		},
    88  		// Response contains one listener and it is good.
    89  		{
    90  			name:        "one-good-listener",
    91  			ldsResponse: goodLDSResponse1,
    92  			wantErr:     false,
    93  			wantUpdate: map[string]xdsresource.ListenerUpdateErrTuple{
    94  				goodLDSTarget1: {Update: xdsresource.ListenerUpdate{RouteConfigName: goodRouteName1, Raw: marshaledListener1}},
    95  			},
    96  			wantUpdateMD: xdsresource.UpdateMetadata{
    97  				Status: xdsresource.ServiceStatusACKed,
    98  			},
    99  			wantUpdateErr: false,
   100  		},
   101  		// Response contains multiple good listeners, including the one we are
   102  		// interested in.
   103  		{
   104  			name:        "multiple-good-listener",
   105  			ldsResponse: ldsResponseWithMultipleResources,
   106  			wantErr:     false,
   107  			wantUpdate: map[string]xdsresource.ListenerUpdateErrTuple{
   108  				goodLDSTarget1: {Update: xdsresource.ListenerUpdate{RouteConfigName: goodRouteName1, Raw: marshaledListener1}},
   109  				goodLDSTarget2: {Update: xdsresource.ListenerUpdate{RouteConfigName: goodRouteName1, Raw: marshaledListener2}},
   110  			},
   111  			wantUpdateMD: xdsresource.UpdateMetadata{
   112  				Status: xdsresource.ServiceStatusACKed,
   113  			},
   114  			wantUpdateErr: false,
   115  		},
   116  		// Response contains two good listeners (one interesting and one
   117  		// uninteresting), and one badly marshaled listener. This will cause a
   118  		// nack because the uninteresting listener will still be parsed.
   119  		{
   120  			name:        "good-bad-ugly-listeners",
   121  			ldsResponse: goodBadUglyLDSResponse,
   122  			wantErr:     true,
   123  			wantUpdate: map[string]xdsresource.ListenerUpdateErrTuple{
   124  				goodLDSTarget1: {Update: xdsresource.ListenerUpdate{RouteConfigName: goodRouteName1, Raw: marshaledListener1}},
   125  				goodLDSTarget2: {Err: cmpopts.AnyError},
   126  			},
   127  			wantUpdateMD: xdsresource.UpdateMetadata{
   128  				Status: xdsresource.ServiceStatusNACKed,
   129  				ErrState: &xdsresource.UpdateErrorMetadata{
   130  					Err: cmpopts.AnyError,
   131  				},
   132  			},
   133  			wantUpdateErr: false,
   134  		},
   135  		// Response contains one listener, but we are not interested in it.
   136  		{
   137  			name:        "one-uninteresting-listener",
   138  			ldsResponse: goodLDSResponse2,
   139  			wantErr:     false,
   140  			wantUpdate: map[string]xdsresource.ListenerUpdateErrTuple{
   141  				goodLDSTarget2: {Update: xdsresource.ListenerUpdate{RouteConfigName: goodRouteName1, Raw: marshaledListener2}},
   142  			},
   143  			wantUpdateMD: xdsresource.UpdateMetadata{
   144  				Status: xdsresource.ServiceStatusACKed,
   145  			},
   146  			wantUpdateErr: false,
   147  		},
   148  		// Response constains no resources. This is the case where the server
   149  		// does not know about the target we are interested in.
   150  		{
   151  			name:        "empty-response",
   152  			ldsResponse: emptyLDSResponse,
   153  			wantErr:     false,
   154  			wantUpdate:  nil,
   155  			wantUpdateMD: xdsresource.UpdateMetadata{
   156  				Status: xdsresource.ServiceStatusACKed,
   157  			},
   158  			wantUpdateErr: false,
   159  		},
   160  	}
   161  
   162  	for _, test := range tests {
   163  		t.Run(test.name, func(t *testing.T) {
   164  			testWatchHandle(t, &watchHandleTestcase{
   165  				rType:            xdsresource.ListenerResource,
   166  				resourceName:     goodLDSTarget1,
   167  				responseToHandle: test.ldsResponse,
   168  				wantHandleErr:    test.wantErr,
   169  				wantUpdate:       test.wantUpdate,
   170  				wantUpdateMD:     test.wantUpdateMD,
   171  				wantUpdateErr:    test.wantUpdateErr,
   172  			})
   173  		})
   174  	}
   175  }
   176  
   177  // TestLDSHandleResponseWithoutWatch tests the case where the client receives
   178  // an LDS response without a registered watcher.
   179  func (s) TestLDSHandleResponseWithoutWatch(t *testing.T) {
   180  	fakeServer, cleanup := startServer(t)
   181  	defer cleanup()
   182  
   183  	v2c, err := newTestController(&testUpdateReceiver{
   184  		f: func(xdsresource.ResourceType, map[string]interface{}, xdsresource.UpdateMetadata) {},
   185  	}, fakeServer.Address, goodNodeProto, func(int) time.Duration { return 0 }, nil)
   186  	if err != nil {
   187  		t.Fatal(err)
   188  	}
   189  	defer v2c.Close()
   190  
   191  	if _, _, _, err := v2c.handleResponse(badResourceTypeInLDSResponse); err == nil {
   192  		t.Fatal("v2c.handleLDSResponse() succeeded, should have failed")
   193  	}
   194  
   195  	if _, _, _, err := v2c.handleResponse(goodLDSResponse1); err != nil {
   196  		t.Fatal("v2c.handleLDSResponse() succeeded, should have failed")
   197  	}
   198  }