gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/grpc/internal/xds/matcher/matcher_header_test.go (about)

     1  /*
     2   *
     3   * Copyright 2020 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 matcher
    20  
    21  import (
    22  	"regexp"
    23  	"testing"
    24  
    25  	"gitee.com/ks-custle/core-gm/grpc/metadata"
    26  )
    27  
    28  func TestHeaderExactMatcherMatch(t *testing.T) {
    29  	tests := []struct {
    30  		name       string
    31  		key, exact string
    32  		md         metadata.MD
    33  		want       bool
    34  		invert     bool
    35  	}{
    36  		{
    37  			name:  "one value one match",
    38  			key:   "th",
    39  			exact: "tv",
    40  			md:    metadata.Pairs("th", "tv"),
    41  			want:  true,
    42  		},
    43  		{
    44  			name:  "two value one match",
    45  			key:   "th",
    46  			exact: "tv",
    47  			md:    metadata.Pairs("th", "abc", "th", "tv"),
    48  			// Doesn't match comma-concatenated string.
    49  			want: false,
    50  		},
    51  		{
    52  			name:  "two value match concatenated",
    53  			key:   "th",
    54  			exact: "abc,tv",
    55  			md:    metadata.Pairs("th", "abc", "th", "tv"),
    56  			want:  true,
    57  		},
    58  		{
    59  			name:  "not match",
    60  			key:   "th",
    61  			exact: "tv",
    62  			md:    metadata.Pairs("th", "abc"),
    63  			want:  false,
    64  		},
    65  		{
    66  			name:   "invert header not present",
    67  			key:    "th",
    68  			exact:  "tv",
    69  			md:     metadata.Pairs(":method", "GET"),
    70  			want:   false,
    71  			invert: true,
    72  		},
    73  		{
    74  			name:   "invert header match",
    75  			key:    "th",
    76  			exact:  "tv",
    77  			md:     metadata.Pairs("th", "tv"),
    78  			want:   false,
    79  			invert: true,
    80  		},
    81  		{
    82  			name:   "invert header not match",
    83  			key:    "th",
    84  			exact:  "tv",
    85  			md:     metadata.Pairs("th", "tvv"),
    86  			want:   true,
    87  			invert: true,
    88  		},
    89  	}
    90  	for _, tt := range tests {
    91  		t.Run(tt.name, func(t *testing.T) {
    92  			hem := NewHeaderExactMatcher(tt.key, tt.exact, tt.invert)
    93  			if got := hem.Match(tt.md); got != tt.want {
    94  				t.Errorf("match() = %v, want %v", got, tt.want)
    95  			}
    96  		})
    97  	}
    98  }
    99  
   100  func TestHeaderRegexMatcherMatch(t *testing.T) {
   101  	tests := []struct {
   102  		name          string
   103  		key, regexStr string
   104  		md            metadata.MD
   105  		want          bool
   106  		invert        bool
   107  	}{
   108  		{
   109  			name:     "one value one match",
   110  			key:      "th",
   111  			regexStr: "^t+v*$",
   112  			md:       metadata.Pairs("th", "tttvv"),
   113  			want:     true,
   114  		},
   115  		{
   116  			name:     "two value one match",
   117  			key:      "th",
   118  			regexStr: "^t+v*$",
   119  			md:       metadata.Pairs("th", "abc", "th", "tttvv"),
   120  			want:     false,
   121  		},
   122  		{
   123  			name:     "two value match concatenated",
   124  			key:      "th",
   125  			regexStr: "^[abc]*,t+v*$",
   126  			md:       metadata.Pairs("th", "abc", "th", "tttvv"),
   127  			want:     true,
   128  		},
   129  		{
   130  			name:     "no match",
   131  			key:      "th",
   132  			regexStr: "^t+v*$",
   133  			md:       metadata.Pairs("th", "abc"),
   134  			want:     false,
   135  		},
   136  		{
   137  			name:     "no match because only part of value matches with regex",
   138  			key:      "header",
   139  			regexStr: "^a+$",
   140  			md:       metadata.Pairs("header", "ab"),
   141  			want:     false,
   142  		},
   143  		{
   144  			name:     "match because full value matches with regex",
   145  			key:      "header",
   146  			regexStr: "^a+$",
   147  			md:       metadata.Pairs("header", "aa"),
   148  			want:     true,
   149  		},
   150  		{
   151  			name:     "invert header not present",
   152  			key:      "th",
   153  			regexStr: "^t+v*$",
   154  			md:       metadata.Pairs(":method", "GET"),
   155  			want:     false,
   156  			invert:   true,
   157  		},
   158  		{
   159  			name:     "invert header match",
   160  			key:      "th",
   161  			regexStr: "^t+v*$",
   162  			md:       metadata.Pairs("th", "tttvv"),
   163  			want:     false,
   164  			invert:   true,
   165  		},
   166  		{
   167  			name:     "invert header not match",
   168  			key:      "th",
   169  			regexStr: "^t+v*$",
   170  			md:       metadata.Pairs("th", "abc"),
   171  			want:     true,
   172  			invert:   true,
   173  		},
   174  	}
   175  	for _, tt := range tests {
   176  		t.Run(tt.name, func(t *testing.T) {
   177  			hrm := NewHeaderRegexMatcher(tt.key, regexp.MustCompile(tt.regexStr), tt.invert)
   178  			if got := hrm.Match(tt.md); got != tt.want {
   179  				t.Errorf("match() = %v, want %v", got, tt.want)
   180  			}
   181  		})
   182  	}
   183  }
   184  
   185  func TestHeaderRangeMatcherMatch(t *testing.T) {
   186  	tests := []struct {
   187  		name       string
   188  		key        string
   189  		start, end int64
   190  		md         metadata.MD
   191  		want       bool
   192  		invert     bool
   193  	}{
   194  		{
   195  			name:  "match",
   196  			key:   "th",
   197  			start: 1, end: 10,
   198  			md:   metadata.Pairs("th", "5"),
   199  			want: true,
   200  		},
   201  		{
   202  			name:  "equal to start",
   203  			key:   "th",
   204  			start: 1, end: 10,
   205  			md:   metadata.Pairs("th", "1"),
   206  			want: true,
   207  		},
   208  		{
   209  			name:  "equal to end",
   210  			key:   "th",
   211  			start: 1, end: 10,
   212  			md:   metadata.Pairs("th", "10"),
   213  			want: false,
   214  		},
   215  		{
   216  			name:  "negative",
   217  			key:   "th",
   218  			start: -10, end: 10,
   219  			md:   metadata.Pairs("th", "-5"),
   220  			want: true,
   221  		},
   222  		{
   223  			name:  "invert header not present",
   224  			key:   "th",
   225  			start: 1, end: 10,
   226  			md:     metadata.Pairs(":method", "GET"),
   227  			want:   false,
   228  			invert: true,
   229  		},
   230  		{
   231  			name:  "invert header match",
   232  			key:   "th",
   233  			start: 1, end: 10,
   234  			md:     metadata.Pairs("th", "5"),
   235  			want:   false,
   236  			invert: true,
   237  		},
   238  		{
   239  			name:  "invert header not match",
   240  			key:   "th",
   241  			start: 1, end: 9,
   242  			md:     metadata.Pairs("th", "10"),
   243  			want:   true,
   244  			invert: true,
   245  		},
   246  	}
   247  	for _, tt := range tests {
   248  		t.Run(tt.name, func(t *testing.T) {
   249  			hrm := NewHeaderRangeMatcher(tt.key, tt.start, tt.end, tt.invert)
   250  			if got := hrm.Match(tt.md); got != tt.want {
   251  				t.Errorf("match() = %v, want %v", got, tt.want)
   252  			}
   253  		})
   254  	}
   255  }
   256  
   257  func TestHeaderPresentMatcherMatch(t *testing.T) {
   258  	tests := []struct {
   259  		name    string
   260  		key     string
   261  		present bool
   262  		md      metadata.MD
   263  		want    bool
   264  		invert  bool
   265  	}{
   266  		{
   267  			name:    "want present is present",
   268  			key:     "th",
   269  			present: true,
   270  			md:      metadata.Pairs("th", "tv"),
   271  			want:    true,
   272  		},
   273  		{
   274  			name:    "want present not present",
   275  			key:     "th",
   276  			present: true,
   277  			md:      metadata.Pairs("abc", "tv"),
   278  			want:    false,
   279  		},
   280  		{
   281  			name:    "want not present is present",
   282  			key:     "th",
   283  			present: false,
   284  			md:      metadata.Pairs("th", "tv"),
   285  			want:    false,
   286  		},
   287  		{
   288  			name:    "want not present is not present",
   289  			key:     "th",
   290  			present: false,
   291  			md:      metadata.Pairs("abc", "tv"),
   292  			want:    true,
   293  		},
   294  		{
   295  			name:    "invert header not present",
   296  			key:     "th",
   297  			present: true,
   298  			md:      metadata.Pairs(":method", "GET"),
   299  			want:    true,
   300  			invert:  true,
   301  		},
   302  		{
   303  			name:    "invert header match",
   304  			key:     "th",
   305  			present: true,
   306  			md:      metadata.Pairs("th", "tv"),
   307  			want:    false,
   308  			invert:  true,
   309  		},
   310  		{
   311  			name:    "invert header not match",
   312  			key:     "th",
   313  			present: true,
   314  			md:      metadata.Pairs(":method", "GET"),
   315  			want:    true,
   316  			invert:  true,
   317  		},
   318  	}
   319  	for _, tt := range tests {
   320  		t.Run(tt.name, func(t *testing.T) {
   321  			hpm := NewHeaderPresentMatcher(tt.key, tt.present, tt.invert)
   322  			if got := hpm.Match(tt.md); got != tt.want {
   323  				t.Errorf("match() = %v, want %v", got, tt.want)
   324  			}
   325  		})
   326  	}
   327  }
   328  
   329  func TestHeaderPrefixMatcherMatch(t *testing.T) {
   330  	tests := []struct {
   331  		name        string
   332  		key, prefix string
   333  		md          metadata.MD
   334  		want        bool
   335  		invert      bool
   336  	}{
   337  		{
   338  			name:   "one value one match",
   339  			key:    "th",
   340  			prefix: "tv",
   341  			md:     metadata.Pairs("th", "tv123"),
   342  			want:   true,
   343  		},
   344  		{
   345  			name:   "two value one match",
   346  			key:    "th",
   347  			prefix: "tv",
   348  			md:     metadata.Pairs("th", "abc", "th", "tv123"),
   349  			want:   false,
   350  		},
   351  		{
   352  			name:   "two value match concatenated",
   353  			key:    "th",
   354  			prefix: "tv",
   355  			md:     metadata.Pairs("th", "tv123", "th", "abc"),
   356  			want:   true,
   357  		},
   358  		{
   359  			name:   "not match",
   360  			key:    "th",
   361  			prefix: "tv",
   362  			md:     metadata.Pairs("th", "abc"),
   363  			want:   false,
   364  		},
   365  		{
   366  			name:   "invert header not present",
   367  			key:    "th",
   368  			prefix: "tv",
   369  			md:     metadata.Pairs(":method", "GET"),
   370  			want:   false,
   371  			invert: true,
   372  		},
   373  		{
   374  			name:   "invert header match",
   375  			key:    "th",
   376  			prefix: "tv",
   377  			md:     metadata.Pairs("th", "tv123"),
   378  			want:   false,
   379  			invert: true,
   380  		},
   381  		{
   382  			name:   "invert header not match",
   383  			key:    "th",
   384  			prefix: "tv",
   385  			md:     metadata.Pairs("th", "abc"),
   386  			want:   true,
   387  			invert: true,
   388  		},
   389  	}
   390  	for _, tt := range tests {
   391  		t.Run(tt.name, func(t *testing.T) {
   392  			hpm := NewHeaderPrefixMatcher(tt.key, tt.prefix, tt.invert)
   393  			if got := hpm.Match(tt.md); got != tt.want {
   394  				t.Errorf("match() = %v, want %v", got, tt.want)
   395  			}
   396  		})
   397  	}
   398  }
   399  
   400  func TestHeaderSuffixMatcherMatch(t *testing.T) {
   401  	tests := []struct {
   402  		name        string
   403  		key, suffix string
   404  		md          metadata.MD
   405  		want        bool
   406  		invert      bool
   407  	}{
   408  		{
   409  			name:   "one value one match",
   410  			key:    "th",
   411  			suffix: "tv",
   412  			md:     metadata.Pairs("th", "123tv"),
   413  			want:   true,
   414  		},
   415  		{
   416  			name:   "two value one match",
   417  			key:    "th",
   418  			suffix: "tv",
   419  			md:     metadata.Pairs("th", "123tv", "th", "abc"),
   420  			want:   false,
   421  		},
   422  		{
   423  			name:   "two value match concatenated",
   424  			key:    "th",
   425  			suffix: "tv",
   426  			md:     metadata.Pairs("th", "abc", "th", "123tv"),
   427  			want:   true,
   428  		},
   429  		{
   430  			name:   "not match",
   431  			key:    "th",
   432  			suffix: "tv",
   433  			md:     metadata.Pairs("th", "abc"),
   434  			want:   false,
   435  		},
   436  		{
   437  			name:   "invert header not present",
   438  			key:    "th",
   439  			suffix: "tv",
   440  			md:     metadata.Pairs(":method", "GET"),
   441  			want:   false,
   442  			invert: true,
   443  		},
   444  		{
   445  			name:   "invert header match",
   446  			key:    "th",
   447  			suffix: "tv",
   448  			md:     metadata.Pairs("th", "123tv"),
   449  			want:   false,
   450  			invert: true,
   451  		},
   452  		{
   453  			name:   "invert header not match",
   454  			key:    "th",
   455  			suffix: "tv",
   456  			md:     metadata.Pairs("th", "abc"),
   457  			want:   true,
   458  			invert: true,
   459  		},
   460  	}
   461  	for _, tt := range tests {
   462  		t.Run(tt.name, func(t *testing.T) {
   463  			hsm := NewHeaderSuffixMatcher(tt.key, tt.suffix, tt.invert)
   464  			if got := hsm.Match(tt.md); got != tt.want {
   465  				t.Errorf("match() = %v, want %v", got, tt.want)
   466  			}
   467  		})
   468  	}
   469  }