mirror of https://github.com/grpc/grpc-go.git
470 lines
9.8 KiB
Go
470 lines
9.8 KiB
Go
/*
|
|
*
|
|
* Copyright 2020 gRPC authors.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
*/
|
|
|
|
package matcher
|
|
|
|
import (
|
|
"regexp"
|
|
"testing"
|
|
|
|
"google.golang.org/grpc/metadata"
|
|
)
|
|
|
|
func TestHeaderExactMatcherMatch(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
key, exact string
|
|
md metadata.MD
|
|
want bool
|
|
invert bool
|
|
}{
|
|
{
|
|
name: "one value one match",
|
|
key: "th",
|
|
exact: "tv",
|
|
md: metadata.Pairs("th", "tv"),
|
|
want: true,
|
|
},
|
|
{
|
|
name: "two value one match",
|
|
key: "th",
|
|
exact: "tv",
|
|
md: metadata.Pairs("th", "abc", "th", "tv"),
|
|
// Doesn't match comma-concatenated string.
|
|
want: false,
|
|
},
|
|
{
|
|
name: "two value match concatenated",
|
|
key: "th",
|
|
exact: "abc,tv",
|
|
md: metadata.Pairs("th", "abc", "th", "tv"),
|
|
want: true,
|
|
},
|
|
{
|
|
name: "not match",
|
|
key: "th",
|
|
exact: "tv",
|
|
md: metadata.Pairs("th", "abc"),
|
|
want: false,
|
|
},
|
|
{
|
|
name: "invert header not present",
|
|
key: "th",
|
|
exact: "tv",
|
|
md: metadata.Pairs(":method", "GET"),
|
|
want: false,
|
|
invert: true,
|
|
},
|
|
{
|
|
name: "invert header match",
|
|
key: "th",
|
|
exact: "tv",
|
|
md: metadata.Pairs("th", "tv"),
|
|
want: false,
|
|
invert: true,
|
|
},
|
|
{
|
|
name: "invert header not match",
|
|
key: "th",
|
|
exact: "tv",
|
|
md: metadata.Pairs("th", "tvv"),
|
|
want: true,
|
|
invert: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
hem := NewHeaderExactMatcher(tt.key, tt.exact, tt.invert)
|
|
if got := hem.Match(tt.md); got != tt.want {
|
|
t.Errorf("match() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHeaderRegexMatcherMatch(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
key, regexStr string
|
|
md metadata.MD
|
|
want bool
|
|
invert bool
|
|
}{
|
|
{
|
|
name: "one value one match",
|
|
key: "th",
|
|
regexStr: "^t+v*$",
|
|
md: metadata.Pairs("th", "tttvv"),
|
|
want: true,
|
|
},
|
|
{
|
|
name: "two value one match",
|
|
key: "th",
|
|
regexStr: "^t+v*$",
|
|
md: metadata.Pairs("th", "abc", "th", "tttvv"),
|
|
want: false,
|
|
},
|
|
{
|
|
name: "two value match concatenated",
|
|
key: "th",
|
|
regexStr: "^[abc]*,t+v*$",
|
|
md: metadata.Pairs("th", "abc", "th", "tttvv"),
|
|
want: true,
|
|
},
|
|
{
|
|
name: "no match",
|
|
key: "th",
|
|
regexStr: "^t+v*$",
|
|
md: metadata.Pairs("th", "abc"),
|
|
want: false,
|
|
},
|
|
{
|
|
name: "no match because only part of value matches with regex",
|
|
key: "header",
|
|
regexStr: "^a+$",
|
|
md: metadata.Pairs("header", "ab"),
|
|
want: false,
|
|
},
|
|
{
|
|
name: "match because full value matches with regex",
|
|
key: "header",
|
|
regexStr: "^a+$",
|
|
md: metadata.Pairs("header", "aa"),
|
|
want: true,
|
|
},
|
|
{
|
|
name: "invert header not present",
|
|
key: "th",
|
|
regexStr: "^t+v*$",
|
|
md: metadata.Pairs(":method", "GET"),
|
|
want: false,
|
|
invert: true,
|
|
},
|
|
{
|
|
name: "invert header match",
|
|
key: "th",
|
|
regexStr: "^t+v*$",
|
|
md: metadata.Pairs("th", "tttvv"),
|
|
want: false,
|
|
invert: true,
|
|
},
|
|
{
|
|
name: "invert header not match",
|
|
key: "th",
|
|
regexStr: "^t+v*$",
|
|
md: metadata.Pairs("th", "abc"),
|
|
want: true,
|
|
invert: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
hrm := NewHeaderRegexMatcher(tt.key, regexp.MustCompile(tt.regexStr), tt.invert)
|
|
if got := hrm.Match(tt.md); got != tt.want {
|
|
t.Errorf("match() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHeaderRangeMatcherMatch(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
key string
|
|
start, end int64
|
|
md metadata.MD
|
|
want bool
|
|
invert bool
|
|
}{
|
|
{
|
|
name: "match",
|
|
key: "th",
|
|
start: 1, end: 10,
|
|
md: metadata.Pairs("th", "5"),
|
|
want: true,
|
|
},
|
|
{
|
|
name: "equal to start",
|
|
key: "th",
|
|
start: 1, end: 10,
|
|
md: metadata.Pairs("th", "1"),
|
|
want: true,
|
|
},
|
|
{
|
|
name: "equal to end",
|
|
key: "th",
|
|
start: 1, end: 10,
|
|
md: metadata.Pairs("th", "10"),
|
|
want: false,
|
|
},
|
|
{
|
|
name: "negative",
|
|
key: "th",
|
|
start: -10, end: 10,
|
|
md: metadata.Pairs("th", "-5"),
|
|
want: true,
|
|
},
|
|
{
|
|
name: "invert header not present",
|
|
key: "th",
|
|
start: 1, end: 10,
|
|
md: metadata.Pairs(":method", "GET"),
|
|
want: false,
|
|
invert: true,
|
|
},
|
|
{
|
|
name: "invert header match",
|
|
key: "th",
|
|
start: 1, end: 10,
|
|
md: metadata.Pairs("th", "5"),
|
|
want: false,
|
|
invert: true,
|
|
},
|
|
{
|
|
name: "invert header not match",
|
|
key: "th",
|
|
start: 1, end: 9,
|
|
md: metadata.Pairs("th", "10"),
|
|
want: true,
|
|
invert: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
hrm := NewHeaderRangeMatcher(tt.key, tt.start, tt.end, tt.invert)
|
|
if got := hrm.Match(tt.md); got != tt.want {
|
|
t.Errorf("match() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHeaderPresentMatcherMatch(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
key string
|
|
present bool
|
|
md metadata.MD
|
|
want bool
|
|
invert bool
|
|
}{
|
|
{
|
|
name: "want present is present",
|
|
key: "th",
|
|
present: true,
|
|
md: metadata.Pairs("th", "tv"),
|
|
want: true,
|
|
},
|
|
{
|
|
name: "want present not present",
|
|
key: "th",
|
|
present: true,
|
|
md: metadata.Pairs("abc", "tv"),
|
|
want: false,
|
|
},
|
|
{
|
|
name: "want not present is present",
|
|
key: "th",
|
|
present: false,
|
|
md: metadata.Pairs("th", "tv"),
|
|
want: false,
|
|
},
|
|
{
|
|
name: "want not present is not present",
|
|
key: "th",
|
|
present: false,
|
|
md: metadata.Pairs("abc", "tv"),
|
|
want: true,
|
|
},
|
|
{
|
|
name: "invert header not present",
|
|
key: "th",
|
|
present: true,
|
|
md: metadata.Pairs(":method", "GET"),
|
|
want: true,
|
|
invert: true,
|
|
},
|
|
{
|
|
name: "invert header match",
|
|
key: "th",
|
|
present: true,
|
|
md: metadata.Pairs("th", "tv"),
|
|
want: false,
|
|
invert: true,
|
|
},
|
|
{
|
|
name: "invert header not match",
|
|
key: "th",
|
|
present: true,
|
|
md: metadata.Pairs(":method", "GET"),
|
|
want: true,
|
|
invert: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
hpm := NewHeaderPresentMatcher(tt.key, tt.present, tt.invert)
|
|
if got := hpm.Match(tt.md); got != tt.want {
|
|
t.Errorf("match() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHeaderPrefixMatcherMatch(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
key, prefix string
|
|
md metadata.MD
|
|
want bool
|
|
invert bool
|
|
}{
|
|
{
|
|
name: "one value one match",
|
|
key: "th",
|
|
prefix: "tv",
|
|
md: metadata.Pairs("th", "tv123"),
|
|
want: true,
|
|
},
|
|
{
|
|
name: "two value one match",
|
|
key: "th",
|
|
prefix: "tv",
|
|
md: metadata.Pairs("th", "abc", "th", "tv123"),
|
|
want: false,
|
|
},
|
|
{
|
|
name: "two value match concatenated",
|
|
key: "th",
|
|
prefix: "tv",
|
|
md: metadata.Pairs("th", "tv123", "th", "abc"),
|
|
want: true,
|
|
},
|
|
{
|
|
name: "not match",
|
|
key: "th",
|
|
prefix: "tv",
|
|
md: metadata.Pairs("th", "abc"),
|
|
want: false,
|
|
},
|
|
{
|
|
name: "invert header not present",
|
|
key: "th",
|
|
prefix: "tv",
|
|
md: metadata.Pairs(":method", "GET"),
|
|
want: false,
|
|
invert: true,
|
|
},
|
|
{
|
|
name: "invert header match",
|
|
key: "th",
|
|
prefix: "tv",
|
|
md: metadata.Pairs("th", "tv123"),
|
|
want: false,
|
|
invert: true,
|
|
},
|
|
{
|
|
name: "invert header not match",
|
|
key: "th",
|
|
prefix: "tv",
|
|
md: metadata.Pairs("th", "abc"),
|
|
want: true,
|
|
invert: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
hpm := NewHeaderPrefixMatcher(tt.key, tt.prefix, tt.invert)
|
|
if got := hpm.Match(tt.md); got != tt.want {
|
|
t.Errorf("match() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestHeaderSuffixMatcherMatch(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
key, suffix string
|
|
md metadata.MD
|
|
want bool
|
|
invert bool
|
|
}{
|
|
{
|
|
name: "one value one match",
|
|
key: "th",
|
|
suffix: "tv",
|
|
md: metadata.Pairs("th", "123tv"),
|
|
want: true,
|
|
},
|
|
{
|
|
name: "two value one match",
|
|
key: "th",
|
|
suffix: "tv",
|
|
md: metadata.Pairs("th", "123tv", "th", "abc"),
|
|
want: false,
|
|
},
|
|
{
|
|
name: "two value match concatenated",
|
|
key: "th",
|
|
suffix: "tv",
|
|
md: metadata.Pairs("th", "abc", "th", "123tv"),
|
|
want: true,
|
|
},
|
|
{
|
|
name: "not match",
|
|
key: "th",
|
|
suffix: "tv",
|
|
md: metadata.Pairs("th", "abc"),
|
|
want: false,
|
|
},
|
|
{
|
|
name: "invert header not present",
|
|
key: "th",
|
|
suffix: "tv",
|
|
md: metadata.Pairs(":method", "GET"),
|
|
want: false,
|
|
invert: true,
|
|
},
|
|
{
|
|
name: "invert header match",
|
|
key: "th",
|
|
suffix: "tv",
|
|
md: metadata.Pairs("th", "123tv"),
|
|
want: false,
|
|
invert: true,
|
|
},
|
|
{
|
|
name: "invert header not match",
|
|
key: "th",
|
|
suffix: "tv",
|
|
md: metadata.Pairs("th", "abc"),
|
|
want: true,
|
|
invert: true,
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
hsm := NewHeaderSuffixMatcher(tt.key, tt.suffix, tt.invert)
|
|
if got := hsm.Match(tt.md); got != tt.want {
|
|
t.Errorf("match() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|