diff --git a/xds/internal/balancer/clusterresolver/clusterresolver_test.go b/xds/internal/balancer/clusterresolver/clusterresolver_test.go index 6d798a1543b0..2f4fc703f177 100644 --- a/xds/internal/balancer/clusterresolver/clusterresolver_test.go +++ b/xds/internal/balancer/clusterresolver/clusterresolver_test.go @@ -240,84 +240,6 @@ func (s) TestSubConnStateChange(t *testing.T) { } } -// Given a list of resource names, verifies that EDS requests for the same are -// sent by the EDS balancer, through the fake xDS client. -func verifyExpectedRequests(ctx context.Context, fc *fakeclient.Client, resourceNames ...string) error { - for _, name := range resourceNames { - if name == "" { - // ResourceName empty string indicates a cancel. - if _, err := fc.WaitForCancelEDSWatch(ctx); err != nil { - return fmt.Errorf("timed out when expecting resource %q", name) - } - continue - } - - resName, err := fc.WaitForWatchEDS(ctx) - if err != nil { - return fmt.Errorf("timed out when expecting resource %q, %p", name, fc) - } - if resName != name { - return fmt.Errorf("got EDS request for resource %q, expected: %q", resName, name) - } - } - return nil -} - -// TestClientWatchEDS verifies that the xdsClient inside the top-level EDS LB -// policy registers an EDS watch for expected resource upon receiving an update -// from gRPC. -func (s) TestClientWatchEDS(t *testing.T) { - edsLBCh := testutils.NewChannel() - xdsC, cleanup := setup(edsLBCh) - defer cleanup() - - builder := balancer.Get(Name) - edsB := builder.Build(newNoopTestClientConn(), balancer.BuildOptions{}) - if edsB == nil { - t.Fatalf("builder.Build(%s) failed and returned nil", Name) - } - defer edsB.Close() - - ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) - defer cancel() - // If eds service name is not set, should watch for cluster name. - if err := edsB.UpdateClientConnState(balancer.ClientConnState{ - ResolverState: xdsclient.SetClient(resolver.State{}, xdsC), - BalancerConfig: newLBConfigWithOneEDS("cluster-1"), - }); err != nil { - t.Fatal(err) - } - if err := verifyExpectedRequests(ctx, xdsC, "cluster-1"); err != nil { - t.Fatal(err) - } - - // Update with an non-empty edsServiceName should trigger an EDS watch for - // the same. - if err := edsB.UpdateClientConnState(balancer.ClientConnState{ - ResolverState: xdsclient.SetClient(resolver.State{}, xdsC), - BalancerConfig: newLBConfigWithOneEDS("foobar-1"), - }); err != nil { - t.Fatal(err) - } - if err := verifyExpectedRequests(ctx, xdsC, "", "foobar-1"); err != nil { - t.Fatal(err) - } - - // Also test the case where the edsServerName changes from one non-empty - // name to another, and make sure a new watch is registered. The previously - // registered watch will be cancelled, which will result in an EDS request - // with no resource names being sent to the server. - if err := edsB.UpdateClientConnState(balancer.ClientConnState{ - ResolverState: xdsclient.SetClient(resolver.State{}, xdsC), - BalancerConfig: newLBConfigWithOneEDS("foobar-2"), - }); err != nil { - t.Fatal(err) - } - if err := verifyExpectedRequests(ctx, xdsC, "", "foobar-2"); err != nil { - t.Fatal(err) - } -} - func newLBConfigWithOneEDS(edsServiceName string) *LBConfig { return &LBConfig{ DiscoveryMechanisms: []DiscoveryMechanism{{ diff --git a/xds/internal/balancer/clusterresolver/priority_test.go b/xds/internal/balancer/clusterresolver/priority_test.go index 4d2904c67ff6..526204ca22c6 100644 --- a/xds/internal/balancer/clusterresolver/priority_test.go +++ b/xds/internal/balancer/clusterresolver/priority_test.go @@ -832,108 +832,3 @@ func (s) TestEDSPriority_FirstPriorityRemoved(t *testing.T) { t.Fatal(err) } } - -// Watch resources from EDS and DNS, with EDS as the higher priority. Lower -// priority is used when higher priority is not ready. -func (s) TestFallbackToDNS(t *testing.T) { - const testDNSEndpointAddr = "3.1.4.1:5" - // dnsTargetCh, dnsCloseCh, resolveNowCh, dnsR, cleanup := setupDNS() - dnsTargetCh, _, resolveNowCh, dnsR, cleanupDNS := setupDNS() - defer cleanupDNS() - edsb, cc, xdsC, cleanup := setupTestEDS(t, nil) - defer cleanup() - - if err := edsb.UpdateClientConnState(balancer.ClientConnState{ - BalancerConfig: &LBConfig{ - DiscoveryMechanisms: []DiscoveryMechanism{ - { - Type: DiscoveryMechanismTypeEDS, - Cluster: testClusterName, - }, - { - Type: DiscoveryMechanismTypeLogicalDNS, - DNSHostname: testDNSTarget, - }, - }, - xdsLBPolicy: *wrrLocalityLBConfig, - }, - }); err != nil { - t.Fatal(err) - } - - ctx, ctxCancel := context.WithTimeout(context.Background(), defaultTestTimeout) - defer ctxCancel() - select { - case target := <-dnsTargetCh: - if diff := cmp.Diff(target, resolver.Target{Scheme: "dns", URL: *testutils.MustParseURL("dns:///" + testDNSTarget)}); diff != "" { - t.Fatalf("got unexpected DNS target to watch, diff (-got, +want): %v", diff) - } - case <-ctx.Done(): - t.Fatal("Timed out waiting for building DNS resolver") - } - - // One locality with one backend. - clab1 := xdstestutils.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil) - clab1.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil) - xdsC.InvokeWatchEDSCallback("", parseEDSRespProtoForTesting(clab1.Build()), nil) - - // Also send a DNS update, because the balancer needs both updates from all - // resources to move on. - dnsR.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: testDNSEndpointAddr}}}) - - addrs0 := <-cc.NewSubConnAddrsCh - if got, want := addrs0[0].Addr, testEndpointAddrs[0]; got != want { - t.Fatalf("sc is created with addr %v, want %v", got, want) - } - sc0 := <-cc.NewSubConnCh - - // p0 is ready. - edsb.UpdateSubConnState(sc0, balancer.SubConnState{ConnectivityState: connectivity.Connecting}) - edsb.UpdateSubConnState(sc0, balancer.SubConnState{ConnectivityState: connectivity.Ready}) - - // Test roundrobin with only p0 subconns. - if err := cc.WaitForRoundRobinPicker(ctx, sc0); err != nil { - t.Fatal(err) - } - - // Turn down 0, p1 (DNS) will be used. - edsb.UpdateSubConnState(sc0, balancer.SubConnState{ConnectivityState: connectivity.TransientFailure}) - - // The transient failure above should not trigger a re-resolve to the DNS - // resolver. Need to read to clear the channel, to avoid potential deadlock - // writing to the channel later. - shortCtx, shortCancel := context.WithTimeout(context.Background(), defaultTestShortTimeout) - defer shortCancel() - select { - case <-resolveNowCh: - t.Fatal("unexpected re-resolve trigger by transient failure from EDS endpoint") - case <-shortCtx.Done(): - } - - // The addresses used to create new SubConn should be the DNS endpoint. - addrs1 := <-cc.NewSubConnAddrsCh - if got, want := addrs1[0].Addr, testDNSEndpointAddr; got != want { - t.Fatalf("sc is created with addr %v, want %v", got, want) - } - sc1 := <-cc.NewSubConnCh - edsb.UpdateSubConnState(sc1, balancer.SubConnState{ConnectivityState: connectivity.Connecting}) - edsb.UpdateSubConnState(sc1, balancer.SubConnState{ConnectivityState: connectivity.Ready}) - - // Test pick with 1. - if err := cc.WaitForRoundRobinPicker(ctx, sc1); err != nil { - t.Fatal(err) - } - - // Turn down the DNS endpoint, this should trigger an re-resolve in the DNS - // resolver. - edsb.UpdateSubConnState(sc1, balancer.SubConnState{ConnectivityState: connectivity.TransientFailure}) - - // The transient failure above should trigger a re-resolve to the DNS - // resolver. Need to read to clear the channel, to avoid potential deadlock - // writing to the channel later. - select { - case <-resolveNowCh: - case <-ctx.Done(): - t.Fatal("Timed out waiting for re-resolve") - } -} diff --git a/xds/internal/balancer/clusterresolver/resource_resolver_test.go b/xds/internal/balancer/clusterresolver/resource_resolver_test.go deleted file mode 100644 index 0ae151ee5215..000000000000 --- a/xds/internal/balancer/clusterresolver/resource_resolver_test.go +++ /dev/null @@ -1,59 +0,0 @@ -/* - * - * Copyright 2021 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package clusterresolver - -import ( - "google.golang.org/grpc/resolver" - "google.golang.org/grpc/resolver/manual" - xdstestutils "google.golang.org/grpc/xds/internal/testutils" - "google.golang.org/grpc/xds/internal/xdsclient/xdsresource" -) - -const ( - testDNSTarget = "dns.com" -) - -var ( - testEDSUpdates []xdsresource.EndpointsUpdate -) - -func init() { - clab1 := xdstestutils.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil) - clab1.AddLocality(testSubZones[0], 1, 0, testEndpointAddrs[:1], nil) - testEDSUpdates = append(testEDSUpdates, parseEDSRespProtoForTesting(clab1.Build())) - clab2 := xdstestutils.NewClusterLoadAssignmentBuilder(testClusterNames[0], nil) - clab2.AddLocality(testSubZones[1], 1, 0, testEndpointAddrs[1:2], nil) - testEDSUpdates = append(testEDSUpdates, parseEDSRespProtoForTesting(clab2.Build())) -} - -func setupDNS() (chan resolver.Target, chan struct{}, chan resolver.ResolveNowOptions, *manual.Resolver, func()) { - dnsTargetCh := make(chan resolver.Target, 1) - dnsCloseCh := make(chan struct{}, 1) - resolveNowCh := make(chan resolver.ResolveNowOptions, 1) - - mr := manual.NewBuilderWithScheme("dns") - mr.BuildCallback = func(target resolver.Target, _ resolver.ClientConn, _ resolver.BuildOptions) { dnsTargetCh <- target } - mr.CloseCallback = func() { dnsCloseCh <- struct{}{} } - mr.ResolveNowCallback = func(opts resolver.ResolveNowOptions) { resolveNowCh <- opts } - oldNewDNS := newDNS - newDNS = func(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) { - return mr.Build(target, cc, opts) - } - return dnsTargetCh, dnsCloseCh, resolveNowCh, mr, func() { newDNS = oldNewDNS } -}