@@ -98,6 +98,10 @@ func startXDS(t *testing.T, xdsname string, v2c *v2Client, reqChan *testutils.Ch
98
98
//
99
99
// It also waits and checks that the ack request contains the given version, and
100
100
// the generated nonce.
101
+ //
102
+ // TODO: make this and other helper function either consistently return error,
103
+ // and fatal() in the test code, or all call t.Fatal(), and mark them as
104
+ // helper().
101
105
func sendGoodResp (t * testing.T , xdsname string , fakeServer * fakeserver.Server , version int , goodResp * xdspb.DiscoveryResponse , wantReq * xdspb.DiscoveryRequest , callbackCh * testutils.Channel ) (nonce string ) {
102
106
nonce = sendXDSRespWithVersion (fakeServer .XDSResponseChan , goodResp , version )
103
107
t .Logf ("Good %s response pushed to fakeServer..." , xdsname )
@@ -263,3 +267,110 @@ func (s) TestV2ClientAckNackAfterNewWatch(t *testing.T) {
263
267
sendGoodResp (t , "LDS" , fakeServer , versionLDS , goodLDSResponse1 , goodLDSRequest , cbLDS )
264
268
versionLDS ++
265
269
}
270
+
271
+ // TestV2ClientAckNewWatchAfterCancel verifies the new request for a new watch
272
+ // after the previous watch is canceled, has the right version.
273
+ func (s ) TestV2ClientAckNewWatchAfterCancel (t * testing.T ) {
274
+ var versionCDS = 3000
275
+
276
+ fakeServer , cc , cleanup := startServerAndGetCC (t )
277
+ defer cleanup ()
278
+ v2c := newV2Client (cc , goodNodeProto , func (int ) time.Duration { return 0 }, nil )
279
+ defer v2c .close ()
280
+ t .Log ("Started xds v2Client..." )
281
+
282
+ // Start a CDS watch.
283
+ callbackCh := testutils .NewChannel ()
284
+ cancel := v2c .watchCDS (goodClusterName1 , func (u CDSUpdate , err error ) {
285
+ t .Logf ("Received %s callback with ldsUpdate {%+v} and error {%v}" , "CDS" , u , err )
286
+ callbackCh .Send (struct {}{})
287
+ })
288
+ if err := compareXDSRequest (fakeServer .XDSRequestChan , goodCDSRequest , "" , "" ); err != nil {
289
+ t .Fatal (err )
290
+ }
291
+ t .Logf ("FakeServer received %s request..." , "CDS" )
292
+
293
+ // Send a good CDS response, this function waits for the ACK with the right
294
+ // version.
295
+ nonce := sendGoodResp (t , "CDS" , fakeServer , versionCDS , goodCDSResponse1 , goodCDSRequest , callbackCh )
296
+
297
+ // Cancel the CDS watch, and start a new one. The new watch should have the
298
+ // version from the response above.
299
+ cancel ()
300
+ v2c .watchCDS (goodClusterName1 , func (u CDSUpdate , err error ) {
301
+ t .Logf ("Received %s callback with ldsUpdate {%+v} and error {%v}" , "CDS" , u , err )
302
+ callbackCh .Send (struct {}{})
303
+ })
304
+ if err := compareXDSRequest (fakeServer .XDSRequestChan , goodCDSRequest , strconv .Itoa (versionCDS ), nonce ); err != nil {
305
+ t .Fatalf ("Failed to receive %s request: %v" , "CDS" , err )
306
+ }
307
+ versionCDS ++
308
+
309
+ // Send a bad response with the next version.
310
+ sendBadResp (t , "CDS" , fakeServer , versionCDS , goodCDSRequest )
311
+ versionCDS ++
312
+
313
+ // send another good response, and check for ack, with the new version.
314
+ sendGoodResp (t , "CDS" , fakeServer , versionCDS , goodCDSResponse1 , goodCDSRequest , callbackCh )
315
+ versionCDS ++
316
+ }
317
+
318
+ // TestV2ClientAckCancelResponseRace verifies if the response and ACK request
319
+ // race with cancel (which means the ACK request will not be sent on wire,
320
+ // because there's no active watch), the nonce will still be updated, and the
321
+ // new request with the new watch will have the correct nonce.
322
+ func (s ) TestV2ClientAckCancelResponseRace (t * testing.T ) {
323
+ var versionCDS = 3000
324
+
325
+ fakeServer , cc , cleanup := startServerAndGetCC (t )
326
+ defer cleanup ()
327
+ v2c := newV2Client (cc , goodNodeProto , func (int ) time.Duration { return 0 }, nil )
328
+ defer v2c .close ()
329
+ t .Log ("Started xds v2Client..." )
330
+
331
+ // Start a CDS watch.
332
+ callbackCh := testutils .NewChannel ()
333
+ cancel := v2c .watchCDS (goodClusterName1 , func (u CDSUpdate , err error ) {
334
+ t .Logf ("Received %s callback with ldsUpdate {%+v} and error {%v}" , "CDS" , u , err )
335
+ callbackCh .Send (struct {}{})
336
+ })
337
+ if err := compareXDSRequest (fakeServer .XDSRequestChan , goodCDSRequest , "" , "" ); err != nil {
338
+ t .Fatalf ("Failed to receive %s request: %v" , "CDS" , err )
339
+ }
340
+ t .Logf ("FakeServer received %s request..." , "CDS" )
341
+
342
+ // send another good response, and check for ack, with the new version.
343
+ sendGoodResp (t , "CDS" , fakeServer , versionCDS , goodCDSResponse1 , goodCDSRequest , callbackCh )
344
+ versionCDS ++
345
+
346
+ // Cancel the watch before the next response is sent. This mimics the case
347
+ // watch is canceled while response is on wire.
348
+ cancel ()
349
+
350
+ // Send a good response.
351
+ nonce := sendXDSRespWithVersion (fakeServer .XDSResponseChan , goodCDSResponse1 , versionCDS )
352
+ t .Logf ("Good %s response pushed to fakeServer..." , "CDS" )
353
+
354
+ // Expect no ACK because watch was canceled.
355
+ if req , err := fakeServer .XDSRequestChan .Receive (); err != testutils .ErrRecvTimeout {
356
+ t .Fatalf ("Got unexpected xds request after watch is canceled: %v" , req )
357
+ }
358
+
359
+ // Start a new watch. The new watch should have the nonce from the response
360
+ // above, and version from the first good response.
361
+ v2c .watchCDS (goodClusterName1 , func (u CDSUpdate , err error ) {
362
+ t .Logf ("Received %s callback with ldsUpdate {%+v} and error {%v}" , "CDS" , u , err )
363
+ callbackCh .Send (struct {}{})
364
+ })
365
+ if err := compareXDSRequest (fakeServer .XDSRequestChan , goodCDSRequest , strconv .Itoa (versionCDS - 1 ), nonce ); err != nil {
366
+ t .Fatalf ("Failed to receive %s request: %v" , "CDS" , err )
367
+ }
368
+
369
+ // Send a bad response with the next version.
370
+ sendBadResp (t , "CDS" , fakeServer , versionCDS , goodCDSRequest )
371
+ versionCDS ++
372
+
373
+ // send another good response, and check for ack, with the new version.
374
+ sendGoodResp (t , "CDS" , fakeServer , versionCDS , goodCDSResponse1 , goodCDSRequest , callbackCh )
375
+ versionCDS ++
376
+ }
0 commit comments