gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/grpc/xds/internal/clusterspecifier/rls/rls_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 rls 20 21 import ( 22 "encoding/json" 23 "testing" 24 25 _ "gitee.com/ks-custle/core-gm/grpc/balancer/rls" 26 "gitee.com/ks-custle/core-gm/grpc/internal/grpctest" 27 "gitee.com/ks-custle/core-gm/grpc/internal/proto/grpc_lookup_v1" 28 "gitee.com/ks-custle/core-gm/grpc/internal/testutils" 29 _ "gitee.com/ks-custle/core-gm/grpc/xds/internal/balancer/cdsbalancer" 30 "gitee.com/ks-custle/core-gm/grpc/xds/internal/clusterspecifier" 31 "github.com/golang/protobuf/proto" 32 "github.com/google/go-cmp/cmp" 33 "github.com/google/go-cmp/cmp/cmpopts" 34 "google.golang.org/protobuf/types/known/durationpb" 35 ) 36 37 func init() { 38 clusterspecifier.Register(rls{}) 39 } 40 41 type s struct { 42 grpctest.Tester 43 } 44 45 func Test(t *testing.T) { 46 grpctest.RunSubTests(t, s{}) 47 } 48 49 // TestParseClusterSpecifierConfig tests the parsing functionality of the RLS 50 // Cluster Specifier Plugin. 51 func (s) TestParseClusterSpecifierConfig(t *testing.T) { 52 tests := []struct { 53 name string 54 rlcs proto.Message 55 wantConfig clusterspecifier.BalancerConfig 56 wantErr bool 57 }{ 58 { 59 name: "invalid-rls-cluster-specifier", 60 rlcs: rlsClusterSpecifierConfigError, 61 wantErr: true, 62 }, 63 { 64 name: "valid-rls-cluster-specifier", 65 rlcs: rlsClusterSpecifierConfigWithoutTransformations, 66 wantConfig: configWithoutTransformationsWant, 67 }, 68 } 69 for _, test := range tests { 70 cs := clusterspecifier.Get("type.googleapis.com/grpc.lookup.v1.RouteLookupClusterSpecifier") 71 if cs == nil { 72 t.Fatal("Error getting cluster specifier") 73 } 74 lbCfg, err := cs.ParseClusterSpecifierConfig(test.rlcs) 75 76 if (err != nil) != test.wantErr { 77 t.Fatalf("ParseClusterSpecifierConfig(%+v) returned err: %v, wantErr: %v", test.rlcs, err, test.wantErr) 78 } 79 if test.wantErr { // Successfully received an error. 80 return 81 } 82 // Marshal and then unmarshal into interface{} to get rid of 83 // nondeterministic protojson Marshaling. 84 lbCfgJSON, err := json.Marshal(lbCfg) 85 if err != nil { 86 t.Fatalf("json.Marshal(%+v) returned err %v", lbCfg, err) 87 } 88 var got interface{} 89 err = json.Unmarshal(lbCfgJSON, got) 90 if err != nil { 91 t.Fatalf("json.Unmarshal(%+v) returned err %v", lbCfgJSON, err) 92 } 93 wantCfgJSON, err := json.Marshal(test.wantConfig) 94 if err != nil { 95 t.Fatalf("json.Marshal(%+v) returned err %v", test.wantConfig, err) 96 } 97 var want interface{} 98 err = json.Unmarshal(wantCfgJSON, want) 99 if err != nil { 100 t.Fatalf("json.Unmarshal(%+v) returned err %v", lbCfgJSON, err) 101 } 102 if diff := cmp.Diff(want, got, cmpopts.EquateEmpty()); diff != "" { 103 t.Fatalf("ParseClusterSpecifierConfig(%+v) returned expected, diff (-want +got) %v", test.rlcs, diff) 104 } 105 } 106 } 107 108 // This will error because the required match field is set in grpc key builder. 109 var rlsClusterSpecifierConfigError = testutils.MarshalAny(&grpc_lookup_v1.RouteLookupClusterSpecifier{ 110 RouteLookupConfig: &grpc_lookup_v1.RouteLookupConfig{ 111 GrpcKeybuilders: []*grpc_lookup_v1.GrpcKeyBuilder{ 112 { 113 Names: []*grpc_lookup_v1.GrpcKeyBuilder_Name{ 114 { 115 Service: "service", 116 Method: "method", 117 }, 118 }, 119 Headers: []*grpc_lookup_v1.NameMatcher{ 120 { 121 Key: "k1", 122 RequiredMatch: true, 123 Names: []string{"v1"}, 124 }, 125 }, 126 }, 127 }, 128 }, 129 }) 130 131 // Corresponds to the rls unit test case in 132 // balancer/rls/internal/config_test.go. 133 var rlsClusterSpecifierConfigWithoutTransformations = testutils.MarshalAny(&grpc_lookup_v1.RouteLookupClusterSpecifier{ 134 RouteLookupConfig: &grpc_lookup_v1.RouteLookupConfig{ 135 GrpcKeybuilders: []*grpc_lookup_v1.GrpcKeyBuilder{ 136 { 137 Names: []*grpc_lookup_v1.GrpcKeyBuilder_Name{ 138 { 139 Service: "service", 140 Method: "method", 141 }, 142 }, 143 Headers: []*grpc_lookup_v1.NameMatcher{ 144 { 145 Key: "k1", 146 Names: []string{"v1"}, 147 }, 148 }, 149 }, 150 }, 151 LookupService: "target", 152 LookupServiceTimeout: &durationpb.Duration{Seconds: 100}, 153 MaxAge: &durationpb.Duration{Seconds: 60}, 154 StaleAge: &durationpb.Duration{Seconds: 50}, 155 CacheSizeBytes: 1000, 156 DefaultTarget: "passthrough:///default", 157 }, 158 }) 159 160 var configWithoutTransformationsWant = clusterspecifier.BalancerConfig{{"rls_experimental": &lbConfigJSON{ 161 RouteLookupConfig: []byte(`{"grpcKeybuilders":[{"names":[{"service":"service","method":"method"}],"headers":[{"key":"k1","names":["v1"]}]}],"lookupService":"target","lookupServiceTimeout":"100s","maxAge":"60s","staleAge":"50s","cacheSizeBytes":"1000","defaultTarget":"passthrough:///default"}`), 162 ChildPolicy: []map[string]json.RawMessage{ 163 { 164 "cds_experimental": []byte(`{}`), 165 }, 166 }, 167 ChildPolicyConfigTargetFieldName: "cluster", 168 }}}