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 }