google.golang.org/grpc@v1.72.2/test/xds/xds_client_affinity_test.go (about) 1 /* 2 * 3 * Copyright 2021 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 xds_test 20 21 import ( 22 "context" 23 "fmt" 24 "testing" 25 26 "google.golang.org/grpc" 27 "google.golang.org/grpc/credentials/insecure" 28 "google.golang.org/grpc/internal/stubserver" 29 "google.golang.org/grpc/internal/testutils" 30 "google.golang.org/grpc/internal/testutils/xds/e2e" 31 "google.golang.org/grpc/internal/testutils/xds/e2e/setup" 32 33 v3clusterpb "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" 34 v3corepb "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" 35 v3routepb "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" 36 testgrpc "google.golang.org/grpc/interop/grpc_testing" 37 testpb "google.golang.org/grpc/interop/grpc_testing" 38 ) 39 40 // hashRouteConfig returns a RouteConfig resource with hash policy set to 41 // header "session_id". 42 func hashRouteConfig(routeName, ldsTarget, clusterName string) *v3routepb.RouteConfiguration { 43 return &v3routepb.RouteConfiguration{ 44 Name: routeName, 45 VirtualHosts: []*v3routepb.VirtualHost{{ 46 Domains: []string{ldsTarget}, 47 Routes: []*v3routepb.Route{{ 48 Match: &v3routepb.RouteMatch{PathSpecifier: &v3routepb.RouteMatch_Prefix{Prefix: "/"}}, 49 Action: &v3routepb.Route_Route{Route: &v3routepb.RouteAction{ 50 ClusterSpecifier: &v3routepb.RouteAction_Cluster{Cluster: clusterName}, 51 HashPolicy: []*v3routepb.RouteAction_HashPolicy{{ 52 PolicySpecifier: &v3routepb.RouteAction_HashPolicy_Header_{ 53 Header: &v3routepb.RouteAction_HashPolicy_Header{ 54 HeaderName: "session_id", 55 }, 56 }, 57 Terminal: true, 58 }}, 59 }}, 60 }}, 61 }}, 62 } 63 } 64 65 // ringhashCluster returns a Cluster resource that picks ringhash as the lb 66 // policy. 67 func ringhashCluster(clusterName, edsServiceName string) *v3clusterpb.Cluster { 68 return &v3clusterpb.Cluster{ 69 Name: clusterName, 70 ClusterDiscoveryType: &v3clusterpb.Cluster_Type{Type: v3clusterpb.Cluster_EDS}, 71 EdsClusterConfig: &v3clusterpb.Cluster_EdsClusterConfig{ 72 EdsConfig: &v3corepb.ConfigSource{ 73 ConfigSourceSpecifier: &v3corepb.ConfigSource_Ads{ 74 Ads: &v3corepb.AggregatedConfigSource{}, 75 }, 76 }, 77 ServiceName: edsServiceName, 78 }, 79 LbPolicy: v3clusterpb.Cluster_RING_HASH, 80 } 81 } 82 83 // TestClientSideAffinitySanityCheck tests that the affinity config can be 84 // propagated to pick the ring_hash policy. It doesn't test the affinity 85 // behavior in ring_hash policy. 86 func (s) TestClientSideAffinitySanityCheck(t *testing.T) { 87 managementServer, nodeID, _, xdsResolver := setup.ManagementServerAndResolver(t) 88 89 server := stubserver.StartTestService(t, nil) 90 defer server.Stop() 91 92 const serviceName = "my-service-client-side-xds" 93 resources := e2e.DefaultClientResources(e2e.ResourceParams{ 94 DialTarget: serviceName, 95 NodeID: nodeID, 96 Host: "localhost", 97 Port: testutils.ParsePort(t, server.Address), 98 SecLevel: e2e.SecurityLevelNone, 99 }) 100 // Replace RDS and CDS resources with ringhash config, but keep the resource 101 // names. 102 resources.Routes = []*v3routepb.RouteConfiguration{hashRouteConfig( 103 resources.Routes[0].Name, 104 resources.Listeners[0].Name, 105 resources.Clusters[0].Name, 106 )} 107 resources.Clusters = []*v3clusterpb.Cluster{ringhashCluster( 108 resources.Clusters[0].Name, 109 resources.Clusters[0].EdsClusterConfig.ServiceName, 110 )} 111 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 112 defer cancel() 113 if err := managementServer.Update(ctx, resources); err != nil { 114 t.Fatal(err) 115 } 116 117 // Create a ClientConn and make a successful RPC. 118 cc, err := grpc.NewClient(fmt.Sprintf("xds:///%s", serviceName), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithResolvers(xdsResolver)) 119 if err != nil { 120 t.Fatalf("failed to create a client for server: %v", err) 121 } 122 defer cc.Close() 123 124 client := testgrpc.NewTestServiceClient(cc) 125 if _, err := client.EmptyCall(ctx, &testpb.Empty{}, grpc.WaitForReady(true)); err != nil { 126 t.Fatalf("rpc EmptyCall() failed: %v", err) 127 } 128 }