gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/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  	"gitee.com/ks-custle/core-gm/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  }