github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/grpc/metadata/metadata_test.go (about) 1 /* 2 * 3 * Copyright 2014 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 metadata 20 21 import ( 22 "context" 23 "reflect" 24 "strconv" 25 "testing" 26 "time" 27 28 "github.com/hxx258456/ccgo/grpc/internal/grpctest" 29 ) 30 31 const defaultTestTimeout = 10 * time.Second 32 33 type s struct { 34 grpctest.Tester 35 } 36 37 func Test(t *testing.T) { 38 grpctest.RunSubTests(t, s{}) 39 } 40 41 func (s) TestPairsMD(t *testing.T) { 42 for _, test := range []struct { 43 // input 44 kv []string 45 // output 46 md MD 47 }{ 48 {[]string{}, MD{}}, 49 {[]string{"k1", "v1", "k1", "v2"}, MD{"k1": []string{"v1", "v2"}}}, 50 } { 51 md := Pairs(test.kv...) 52 if !reflect.DeepEqual(md, test.md) { 53 t.Fatalf("Pairs(%v) = %v, want %v", test.kv, md, test.md) 54 } 55 } 56 } 57 58 func (s) TestCopy(t *testing.T) { 59 const key, val = "key", "val" 60 orig := Pairs(key, val) 61 cpy := orig.Copy() 62 if !reflect.DeepEqual(orig, cpy) { 63 t.Errorf("copied value not equal to the original, got %v, want %v", cpy, orig) 64 } 65 orig[key][0] = "foo" 66 if v := cpy[key][0]; v != val { 67 t.Errorf("change in original should not affect copy, got %q, want %q", v, val) 68 } 69 } 70 71 func (s) TestJoin(t *testing.T) { 72 for _, test := range []struct { 73 mds []MD 74 want MD 75 }{ 76 {[]MD{}, MD{}}, 77 {[]MD{Pairs("foo", "bar")}, Pairs("foo", "bar")}, 78 {[]MD{Pairs("foo", "bar"), Pairs("foo", "baz")}, Pairs("foo", "bar", "foo", "baz")}, 79 {[]MD{Pairs("foo", "bar"), Pairs("foo", "baz"), Pairs("zip", "zap")}, Pairs("foo", "bar", "foo", "baz", "zip", "zap")}, 80 } { 81 md := Join(test.mds...) 82 if !reflect.DeepEqual(md, test.want) { 83 t.Errorf("context's metadata is %v, want %v", md, test.want) 84 } 85 } 86 } 87 88 func (s) TestGet(t *testing.T) { 89 for _, test := range []struct { 90 md MD 91 key string 92 wantVals []string 93 }{ 94 {md: Pairs("My-Optional-Header", "42"), key: "My-Optional-Header", wantVals: []string{"42"}}, 95 {md: Pairs("Header", "42", "Header", "43", "Header", "44", "other", "1"), key: "HEADER", wantVals: []string{"42", "43", "44"}}, 96 {md: Pairs("HEADER", "10"), key: "HEADER", wantVals: []string{"10"}}, 97 } { 98 vals := test.md.Get(test.key) 99 if !reflect.DeepEqual(vals, test.wantVals) { 100 t.Errorf("value of metadata %v is %v, want %v", test.key, vals, test.wantVals) 101 } 102 } 103 } 104 105 func (s) TestSet(t *testing.T) { 106 for _, test := range []struct { 107 md MD 108 setKey string 109 setVals []string 110 want MD 111 }{ 112 { 113 md: Pairs("My-Optional-Header", "42", "other-key", "999"), 114 setKey: "Other-Key", 115 setVals: []string{"1"}, 116 want: Pairs("my-optional-header", "42", "other-key", "1"), 117 }, 118 { 119 md: Pairs("My-Optional-Header", "42"), 120 setKey: "Other-Key", 121 setVals: []string{"1", "2", "3"}, 122 want: Pairs("my-optional-header", "42", "other-key", "1", "other-key", "2", "other-key", "3"), 123 }, 124 { 125 md: Pairs("My-Optional-Header", "42"), 126 setKey: "Other-Key", 127 setVals: []string{}, 128 want: Pairs("my-optional-header", "42"), 129 }, 130 } { 131 test.md.Set(test.setKey, test.setVals...) 132 if !reflect.DeepEqual(test.md, test.want) { 133 t.Errorf("value of metadata is %v, want %v", test.md, test.want) 134 } 135 } 136 } 137 138 func (s) TestAppend(t *testing.T) { 139 for _, test := range []struct { 140 md MD 141 appendKey string 142 appendVals []string 143 want MD 144 }{ 145 { 146 md: Pairs("My-Optional-Header", "42"), 147 appendKey: "Other-Key", 148 appendVals: []string{"1"}, 149 want: Pairs("my-optional-header", "42", "other-key", "1"), 150 }, 151 { 152 md: Pairs("My-Optional-Header", "42"), 153 appendKey: "my-OptIoNal-HeAder", 154 appendVals: []string{"1", "2", "3"}, 155 want: Pairs("my-optional-header", "42", "my-optional-header", "1", 156 "my-optional-header", "2", "my-optional-header", "3"), 157 }, 158 { 159 md: Pairs("My-Optional-Header", "42"), 160 appendKey: "my-OptIoNal-HeAder", 161 appendVals: []string{}, 162 want: Pairs("my-optional-header", "42"), 163 }, 164 } { 165 test.md.Append(test.appendKey, test.appendVals...) 166 if !reflect.DeepEqual(test.md, test.want) { 167 t.Errorf("value of metadata is %v, want %v", test.md, test.want) 168 } 169 } 170 } 171 172 func (s) TestDelete(t *testing.T) { 173 for _, test := range []struct { 174 md MD 175 deleteKey string 176 want MD 177 }{ 178 { 179 md: Pairs("My-Optional-Header", "42"), 180 deleteKey: "My-Optional-Header", 181 want: Pairs(), 182 }, 183 { 184 md: Pairs("My-Optional-Header", "42"), 185 deleteKey: "Other-Key", 186 want: Pairs("my-optional-header", "42"), 187 }, 188 { 189 md: Pairs("My-Optional-Header", "42"), 190 deleteKey: "my-OptIoNal-HeAder", 191 want: Pairs(), 192 }, 193 } { 194 test.md.Delete(test.deleteKey) 195 if !reflect.DeepEqual(test.md, test.want) { 196 t.Errorf("value of metadata is %v, want %v", test.md, test.want) 197 } 198 } 199 } 200 201 func (s) TestAppendToOutgoingContext(t *testing.T) { 202 // Pre-existing metadata 203 tCtx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 204 defer cancel() 205 ctx := NewOutgoingContext(tCtx, Pairs("k1", "v1", "k2", "v2")) 206 ctx = AppendToOutgoingContext(ctx, "k1", "v3") 207 ctx = AppendToOutgoingContext(ctx, "k1", "v4") 208 md, ok := FromOutgoingContext(ctx) 209 if !ok { 210 t.Errorf("Expected MD to exist in ctx, but got none") 211 } 212 want := Pairs("k1", "v1", "k1", "v3", "k1", "v4", "k2", "v2") 213 if !reflect.DeepEqual(md, want) { 214 t.Errorf("context's metadata is %v, want %v", md, want) 215 } 216 217 // No existing metadata 218 ctx = AppendToOutgoingContext(tCtx, "k1", "v1") 219 md, ok = FromOutgoingContext(ctx) 220 if !ok { 221 t.Errorf("Expected MD to exist in ctx, but got none") 222 } 223 want = Pairs("k1", "v1") 224 if !reflect.DeepEqual(md, want) { 225 t.Errorf("context's metadata is %v, want %v", md, want) 226 } 227 } 228 229 func (s) TestAppendToOutgoingContext_Repeated(t *testing.T) { 230 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 231 defer cancel() 232 233 for i := 0; i < 100; i = i + 2 { 234 ctx1 := AppendToOutgoingContext(ctx, "k", strconv.Itoa(i)) 235 ctx2 := AppendToOutgoingContext(ctx, "k", strconv.Itoa(i+1)) 236 237 md1, _ := FromOutgoingContext(ctx1) 238 md2, _ := FromOutgoingContext(ctx2) 239 240 if reflect.DeepEqual(md1, md2) { 241 t.Fatalf("md1, md2 = %v, %v; should not be equal", md1, md2) 242 } 243 244 ctx = ctx1 245 } 246 } 247 248 func (s) TestAppendToOutgoingContext_FromKVSlice(t *testing.T) { 249 const k, v = "a", "b" 250 kv := []string{k, v} 251 tCtx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 252 defer cancel() 253 ctx := AppendToOutgoingContext(tCtx, kv...) 254 md, _ := FromOutgoingContext(ctx) 255 if md[k][0] != v { 256 t.Fatalf("md[%q] = %q; want %q", k, md[k], v) 257 } 258 kv[1] = "xxx" 259 md, _ = FromOutgoingContext(ctx) 260 if md[k][0] != v { 261 t.Fatalf("md[%q] = %q; want %q", k, md[k], v) 262 } 263 } 264 265 // Old/slow approach to adding metadata to context 266 func Benchmark_AddingMetadata_ContextManipulationApproach(b *testing.B) { 267 // TODO: Add in N=1-100 tests once Go1.6 support is removed. 268 const num = 10 269 for n := 0; n < b.N; n++ { 270 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 271 defer cancel() 272 for i := 0; i < num; i++ { 273 md, _ := FromOutgoingContext(ctx) 274 NewOutgoingContext(ctx, Join(Pairs("k1", "v1", "k2", "v2"), md)) 275 } 276 } 277 } 278 279 // Newer/faster approach to adding metadata to context 280 func BenchmarkAppendToOutgoingContext(b *testing.B) { 281 const num = 10 282 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 283 defer cancel() 284 for n := 0; n < b.N; n++ { 285 for i := 0; i < num; i++ { 286 ctx = AppendToOutgoingContext(ctx, "k1", "v1", "k2", "v2") 287 } 288 } 289 } 290 291 func BenchmarkFromOutgoingContext(b *testing.B) { 292 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 293 defer cancel() 294 ctx = NewOutgoingContext(ctx, MD{"k3": {"v3", "v4"}}) 295 ctx = AppendToOutgoingContext(ctx, "k1", "v1", "k2", "v2") 296 297 for n := 0; n < b.N; n++ { 298 FromOutgoingContext(ctx) 299 } 300 }