@@ -22,6 +22,7 @@ import (
22
22
"context"
23
23
"encoding/json"
24
24
"fmt"
25
+ "net/url"
25
26
"strings"
26
27
"sync"
27
28
"testing"
@@ -318,11 +319,59 @@ func (s) TestResolverBadServiceUpdate_NACKedWithoutCache(t *testing.T) {
318
319
}
319
320
configureResourcesOnManagementServer (ctx , t , mgmtServer , nodeID , []* v3listenerpb.Listener {lis }, nil )
320
321
321
- // Build the resolver and expect an error update from it. Since the
322
- // resource is not cached, it should be received as resource error.
323
- _ , errCh , _ := buildResolverForTarget (t , resolver.Target {URL : * testutils .MustParseURL ("xds:///" + defaultTestServiceName )}, bc )
324
- if err := waitForErrorFromResolver (ctx , errCh , "no RouteSpecifier" , nodeID ); err != nil {
325
- t .Fatal (err )
322
+ // Build the resolver inline (duplicating buildResolverForTarget internals)
323
+ // to avoid issues with blocked channel writes when NACKs occur.
324
+ target := resolver.Target {URL : * testutils .MustParseURL ("xds:///" + defaultTestServiceName )}
325
+ var builder resolver.Builder
326
+ if bc != nil {
327
+ // Create an xDS resolver with the provided bootstrap configuration.
328
+ if internal .NewXDSResolverWithConfigForTesting == nil {
329
+ t .Fatalf ("internal.NewXDSResolverWithConfigForTesting is nil" )
330
+ }
331
+ var err error
332
+ builder , err = internal .NewXDSResolverWithConfigForTesting .(func ([]byte ) (resolver.Builder , error ))(bc )
333
+ if err != nil {
334
+ t .Fatalf ("Failed to create xDS resolver for testing: %v" , err )
335
+ }
336
+ } else {
337
+ builder = resolver .Get ("xds" )
338
+ if builder == nil {
339
+ t .Fatalf ("Scheme %q is not registered" , "xds" )
340
+ }
341
+ }
342
+
343
+ // Use testutils.Channel for the error channel to handle continuous NACKs
344
+ errCh := testutils .NewChannel ()
345
+ reportErrorF := func (err error ) {
346
+ errCh .Replace (err )
347
+ }
348
+ tcc := & testutils.ResolverClientConn {Logger : t , ReportErrorF : reportErrorF }
349
+ r , err := builder .Build (target , tcc , resolver.BuildOptions {
350
+ Authority : url .PathEscape (target .Endpoint ()),
351
+ })
352
+ if err != nil {
353
+ t .Fatalf ("Failed to build xDS resolver for target %q: %v" , target , err )
354
+ }
355
+ t .Cleanup (func () {
356
+ r .Close ()
357
+ })
358
+
359
+ // Wait for and verify the error update from the resolver.
360
+ // Since the resource is not cached, it should be received as resource error.
361
+ select {
362
+ case <- ctx .Done ():
363
+ t .Fatalf ("Timeout waiting for error to be propagated to the ClientConn" )
364
+ case gotErr := <- errCh .C :
365
+ if gotErr == nil {
366
+ t .Fatalf ("got nil error from resolver, want error containing 'no RouteSpecifier'" )
367
+ }
368
+ errStr := fmt .Sprint (gotErr )
369
+ if ! strings .Contains (errStr , "no RouteSpecifier" ) {
370
+ t .Fatalf ("got error from resolver %q, want error containing 'no RouteSpecifier'" , errStr )
371
+ }
372
+ if ! strings .Contains (errStr , nodeID ) {
373
+ t .Fatalf ("got error from resolver %q, want nodeID %q" , errStr , nodeID )
374
+ }
326
375
}
327
376
}
328
377
0 commit comments