google.golang.org/grpc@v1.62.1/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 32 v3clusterpb "github.com/envoyproxy/go-control-plane/envoy/config/cluster/v3" 33 v3corepb "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" 34 v3routepb "github.com/envoyproxy/go-control-plane/envoy/config/route/v3" 35 testgrpc "google.golang.org/grpc/interop/grpc_testing" 36 testpb "google.golang.org/grpc/interop/grpc_testing" 37 ) 38 39 // hashRouteConfig returns a RouteConfig resource with hash policy set to 40 // header "session_id". 41 func hashRouteConfig(routeName, ldsTarget, clusterName string) *v3routepb.RouteConfiguration { 42 return &v3routepb.RouteConfiguration{ 43 Name: routeName, 44 VirtualHosts: []*v3routepb.VirtualHost{{ 45 Domains: []string{ldsTarget}, 46 Routes: []*v3routepb.Route{{ 47 Match: &v3routepb.RouteMatch{PathSpecifier: &v3routepb.RouteMatch_Prefix{Prefix: "/"}}, 48 Action: &v3routepb.Route_Route{Route: &v3routepb.RouteAction{ 49 ClusterSpecifier: &v3routepb.RouteAction_Cluster{Cluster: clusterName}, 50 HashPolicy: []*v3routepb.RouteAction_HashPolicy{{ 51 PolicySpecifier: &v3routepb.RouteAction_HashPolicy_Header_{ 52 Header: &v3routepb.RouteAction_HashPolicy_Header{ 53 HeaderName: "session_id", 54 }, 55 }, 56 Terminal: true, 57 }}, 58 }}, 59 }}, 60 }}, 61 } 62 } 63 64 // ringhashCluster returns a Cluster resource that picks ringhash as the lb 65 // policy. 66 func ringhashCluster(clusterName, edsServiceName string) *v3clusterpb.Cluster { 67 return &v3clusterpb.Cluster{ 68 Name: clusterName, 69 ClusterDiscoveryType: &v3clusterpb.Cluster_Type{Type: v3clusterpb.Cluster_EDS}, 70 EdsClusterConfig: &v3clusterpb.Cluster_EdsClusterConfig{ 71 EdsConfig: &v3corepb.ConfigSource{ 72 ConfigSourceSpecifier: &v3corepb.ConfigSource_Ads{ 73 Ads: &v3corepb.AggregatedConfigSource{}, 74 }, 75 }, 76 ServiceName: edsServiceName, 77 }, 78 LbPolicy: v3clusterpb.Cluster_RING_HASH, 79 } 80 } 81 82 // TestClientSideAffinitySanityCheck tests that the affinity config can be 83 // propagated to pick the ring_hash policy. It doesn't test the affinity 84 // behavior in ring_hash policy. 85 func (s) TestClientSideAffinitySanityCheck(t *testing.T) { 86 managementServer, nodeID, _, resolver, cleanup1 := e2e.SetupManagementServer(t, e2e.ManagementServerOptions{}) 87 defer cleanup1() 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.Dial(fmt.Sprintf("xds:///%s", serviceName), grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithResolvers(resolver)) 119 if err != nil { 120 t.Fatalf("failed to dial local test 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 }