google.golang.org/grpc@v1.72.2/xds/internal/balancer/ringhash/config_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 ringhash 20 21 import ( 22 "encoding/json" 23 "testing" 24 25 "github.com/google/go-cmp/cmp" 26 "google.golang.org/grpc/internal/envconfig" 27 "google.golang.org/grpc/internal/testutils" 28 ) 29 30 func (s) TestParseConfig(t *testing.T) { 31 tests := []struct { 32 name string 33 js string 34 envConfigCap uint64 35 requestHeaderEnvVar bool 36 want *LBConfig 37 wantErr bool 38 }{ 39 { 40 name: "OK", 41 js: `{"minRingSize": 1, "maxRingSize": 2}`, 42 requestHeaderEnvVar: true, 43 want: &LBConfig{MinRingSize: 1, MaxRingSize: 2}, 44 }, 45 { 46 name: "OK with default min", 47 js: `{"maxRingSize": 2000}`, 48 requestHeaderEnvVar: true, 49 want: &LBConfig{MinRingSize: defaultMinSize, MaxRingSize: 2000}, 50 }, 51 { 52 name: "OK with default max", 53 js: `{"minRingSize": 2000}`, 54 requestHeaderEnvVar: true, 55 want: &LBConfig{MinRingSize: 2000, MaxRingSize: defaultMaxSize}, 56 }, 57 { 58 name: "min greater than max", 59 js: `{"minRingSize": 10, "maxRingSize": 2}`, 60 requestHeaderEnvVar: true, 61 want: nil, 62 wantErr: true, 63 }, 64 { 65 name: "min greater than max greater than global limit", 66 js: `{"minRingSize": 6000, "maxRingSize": 5000}`, 67 requestHeaderEnvVar: true, 68 want: nil, 69 wantErr: true, 70 }, 71 { 72 name: "max greater than global limit", 73 js: `{"minRingSize": 1, "maxRingSize": 6000}`, 74 requestHeaderEnvVar: true, 75 want: &LBConfig{MinRingSize: 1, MaxRingSize: 4096}, 76 }, 77 { 78 name: "min and max greater than global limit", 79 js: `{"minRingSize": 5000, "maxRingSize": 6000}`, 80 requestHeaderEnvVar: true, 81 want: &LBConfig{MinRingSize: 4096, MaxRingSize: 4096}, 82 }, 83 { 84 name: "min and max less than raised global limit", 85 js: `{"minRingSize": 5000, "maxRingSize": 6000}`, 86 envConfigCap: 8000, 87 requestHeaderEnvVar: true, 88 want: &LBConfig{MinRingSize: 5000, MaxRingSize: 6000}, 89 }, 90 { 91 name: "min and max greater than raised global limit", 92 js: `{"minRingSize": 10000, "maxRingSize": 10000}`, 93 envConfigCap: 8000, 94 requestHeaderEnvVar: true, 95 want: &LBConfig{MinRingSize: 8000, MaxRingSize: 8000}, 96 }, 97 { 98 name: "min greater than upper bound", 99 js: `{"minRingSize": 8388610, "maxRingSize": 10}`, 100 requestHeaderEnvVar: true, 101 want: nil, 102 wantErr: true, 103 }, 104 { 105 name: "max greater than upper bound", 106 js: `{"minRingSize": 10, "maxRingSize": 8388610}`, 107 requestHeaderEnvVar: true, 108 want: nil, 109 wantErr: true, 110 }, 111 { 112 name: "request metadata key set", 113 js: `{"requestHashHeader": "x-foo"}`, 114 requestHeaderEnvVar: true, 115 want: &LBConfig{ 116 MinRingSize: defaultMinSize, 117 MaxRingSize: defaultMaxSize, 118 RequestHashHeader: "x-foo", 119 }, 120 }, 121 { 122 name: "request metadata key set with uppercase letters", 123 js: `{"requestHashHeader": "x-FOO"}`, 124 requestHeaderEnvVar: true, 125 want: &LBConfig{ 126 MinRingSize: defaultMinSize, 127 MaxRingSize: defaultMaxSize, 128 RequestHashHeader: "x-foo", 129 }, 130 }, 131 { 132 name: "invalid request hash header", 133 js: `{"requestHashHeader": "!invalid"}`, 134 requestHeaderEnvVar: true, 135 want: nil, 136 wantErr: true, 137 }, 138 { 139 name: "binary request hash header", 140 js: `{"requestHashHeader": "header-with-bin"}`, 141 requestHeaderEnvVar: true, 142 want: nil, 143 wantErr: true, 144 }, 145 { 146 name: "request hash header cleared when RingHashSetRequestHashKey env var is false", 147 js: `{"requestHashHeader": "x-foo"}`, 148 requestHeaderEnvVar: false, 149 want: &LBConfig{ 150 MinRingSize: defaultMinSize, 151 MaxRingSize: defaultMaxSize, 152 }, 153 }, 154 } 155 for _, tt := range tests { 156 t.Run(tt.name, func(t *testing.T) { 157 if tt.envConfigCap != 0 { 158 testutils.SetEnvConfig(t, &envconfig.RingHashCap, tt.envConfigCap) 159 } 160 testutils.SetEnvConfig(t, &envconfig.RingHashSetRequestHashKey, tt.requestHeaderEnvVar) 161 got, err := parseConfig(json.RawMessage(tt.js)) 162 if (err != nil) != tt.wantErr { 163 t.Errorf("parseConfig() error = %v, wantErr %v", err, tt.wantErr) 164 return 165 } 166 if diff := cmp.Diff(got, tt.want); diff != "" { 167 t.Errorf("parseConfig() got unexpected output, diff (-got +want): %v", diff) 168 } 169 }) 170 } 171 }