@@ -22,6 +22,7 @@ import (
2222 "context"
2323 "encoding/json"
2424 "fmt"
25+ "net/url"
2526 "strings"
2627 "sync"
2728 "testing"
@@ -318,11 +319,59 @@ func (s) TestResolverBadServiceUpdate_NACKedWithoutCache(t *testing.T) {
318319 }
319320 configureResourcesOnManagementServer (ctx , t , mgmtServer , nodeID , []* v3listenerpb.Listener {lis }, nil )
320321
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+ }
326375 }
327376}
328377
0 commit comments