Skip to content

Commit

Permalink
test: add gRPC matcher tests
Browse files Browse the repository at this point in the history
  • Loading branch information
hperl authored and aeneasr committed Sep 14, 2022
1 parent 210aa5e commit dc8c361
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 20 deletions.
62 changes: 42 additions & 20 deletions rule/matcher_test.go
Expand Up @@ -66,6 +66,15 @@ var testRules = []Rule{
Mutators: []Handler{{Handler: "id_token"}},
Upstream: Upstream{URL: "http://localhost:3333/", StripPath: "/foo", PreserveHost: false},
},
{
ID: "grpc1",
Match: &MatchGRPC{Authority: "<baz|bar>.example.com", FullMethod: "grpc.api/Call"},
Description: "gRPC Rule",
Authorizer: Handler{Handler: "allow", Config: []byte(`{"type":"any"}`)},
Authenticators: []Handler{{Handler: "anonymous", Config: []byte(`{"name":"anonymous1"}`)}},
Mutators: []Handler{{Handler: "id_token", Config: []byte(`{"issuer":"anything"}`)}},
Upstream: Upstream{URL: "http://bar.example.com/", PreserveHost: false},
},
}

var testRulesGlob = []Rule{
Expand Down Expand Up @@ -96,6 +105,15 @@ var testRulesGlob = []Rule{
Mutators: []Handler{{Handler: "id_token"}},
Upstream: Upstream{URL: "http://localhost:3333/", StripPath: "/foo", PreserveHost: false},
},
{
ID: "grpc1",
Match: &MatchGRPC{Authority: "<{baz*,bar*}>.example.com", FullMethod: "grpc.api/Call"},
Description: "gRPC Rule",
Authorizer: Handler{Handler: "allow", Config: []byte(`{"type":"any"}`)},
Authenticators: []Handler{{Handler: "anonymous", Config: []byte(`{"name":"anonymous1"}`)}},
Mutators: []Handler{{Handler: "id_token", Config: []byte(`{"issuer":"anything"}`)}},
Upstream: Upstream{URL: "http://bar.example.com/", PreserveHost: false},
},
}

func TestMatcher(t *testing.T) {
Expand All @@ -104,8 +122,8 @@ func TestMatcher(t *testing.T) {
Repository
}

var testMatcher = func(t *testing.T, matcher Matcher, method string, url string, expectErr bool, expect *Rule) {
r, err := matcher.Match(context.Background(), method, mustParseURL(t, url), ProtocolHTTP)
var testMatcher = func(t *testing.T, matcher Matcher, method string, url string, protocol Protocol, expectErr bool, expect *Rule) {
r, err := matcher.Match(context.Background(), method, mustParseURL(t, url), protocol)
if expectErr {
require.Error(t, err)
} else {
Expand All @@ -119,17 +137,20 @@ func TestMatcher(t *testing.T) {
} {
t.Run(fmt.Sprintf("regexp matcher=%s", name), func(t *testing.T) {
t.Run("case=empty", func(t *testing.T) {
testMatcher(t, matcher, "GET", "https://localhost:34/baz", true, nil)
testMatcher(t, matcher, "POST", "https://localhost:1234/foo", true, nil)
testMatcher(t, matcher, "DELETE", "https://localhost:1234/foo", true, nil)
testMatcher(t, matcher, "GET", "https://localhost:34/baz", ProtocolHTTP, true, nil)
testMatcher(t, matcher, "POST", "https://localhost:1234/foo", ProtocolHTTP, true, nil)
testMatcher(t, matcher, "DELETE", "https://localhost:1234/foo", ProtocolHTTP, true, nil)
})

require.NoError(t, matcher.Set(context.Background(), testRules))

t.Run("case=created", func(t *testing.T) {
testMatcher(t, matcher, "GET", "https://localhost:34/baz", false, &testRules[1])
testMatcher(t, matcher, "POST", "https://localhost:1234/foo", false, &testRules[0])
testMatcher(t, matcher, "DELETE", "https://localhost:1234/foo", true, nil)
testMatcher(t, matcher, "GET", "https://localhost:34/baz", ProtocolHTTP, false, &testRules[1])
testMatcher(t, matcher, "GET", "https://localhost:34/baz", ProtocolGRPC, true, nil)
testMatcher(t, matcher, "POST", "https://localhost:1234/foo", ProtocolHTTP, false, &testRules[0])
testMatcher(t, matcher, "POST", "https://localhost:1234/foo", ProtocolGRPC, true, nil)
testMatcher(t, matcher, "DELETE", "https://localhost:1234/foo", ProtocolHTTP, true, nil)
testMatcher(t, matcher, "POST", "grpc://bar.example.com/grpc.api/Call", ProtocolGRPC, false, &testRules[3])
})

t.Run("case=cache", func(t *testing.T) {
Expand All @@ -148,26 +169,27 @@ func TestMatcher(t *testing.T) {
require.NoError(t, matcher.Set(context.Background(), testRules[1:]))

t.Run("case=updated", func(t *testing.T) {
testMatcher(t, matcher, "GET", "https://localhost:34/baz", false, &testRules[1])
testMatcher(t, matcher, "POST", "https://localhost:1234/foo", true, nil)
testMatcher(t, matcher, "DELETE", "https://localhost:1234/foo", true, nil)
testMatcher(t, matcher, "GET", "https://localhost:34/baz", ProtocolHTTP, false, &testRules[1])
testMatcher(t, matcher, "POST", "https://localhost:1234/foo", ProtocolHTTP, true, nil)
testMatcher(t, matcher, "DELETE", "https://localhost:1234/foo", ProtocolHTTP, true, nil)
})
})
t.Run(fmt.Sprintf("glob matcher=%s", name), func(t *testing.T) {
require.NoError(t, matcher.SetMatchingStrategy(context.Background(), configuration.Glob))
require.NoError(t, matcher.Set(context.Background(), []Rule{}))
t.Run("case=empty", func(t *testing.T) {
testMatcher(t, matcher, "GET", "https://localhost:34/baz", true, nil)
testMatcher(t, matcher, "POST", "https://localhost:1234/foo", true, nil)
testMatcher(t, matcher, "DELETE", "https://localhost:1234/foo", true, nil)
testMatcher(t, matcher, "GET", "https://localhost:34/baz", ProtocolHTTP, true, nil)
testMatcher(t, matcher, "POST", "https://localhost:1234/foo", ProtocolHTTP, true, nil)
testMatcher(t, matcher, "DELETE", "https://localhost:1234/foo", ProtocolHTTP, true, nil)
})

require.NoError(t, matcher.Set(context.Background(), testRulesGlob))

t.Run("case=created", func(t *testing.T) {
testMatcher(t, matcher, "GET", "https://localhost:34/baz", false, &testRulesGlob[1])
testMatcher(t, matcher, "POST", "https://localhost:1234/foo", false, &testRulesGlob[0])
testMatcher(t, matcher, "DELETE", "https://localhost:1234/foo", true, nil)
testMatcher(t, matcher, "GET", "https://localhost:34/baz", ProtocolHTTP, false, &testRulesGlob[1])
testMatcher(t, matcher, "POST", "https://localhost:1234/foo", ProtocolHTTP, false, &testRulesGlob[0])
testMatcher(t, matcher, "DELETE", "https://localhost:1234/foo", ProtocolHTTP, true, nil)
testMatcher(t, matcher, "POST", "grpc://bar.example.com/grpc.api/Call", ProtocolGRPC, false, &testRulesGlob[3])
})

t.Run("case=cache", func(t *testing.T) {
Expand All @@ -181,9 +203,9 @@ func TestMatcher(t *testing.T) {
require.NoError(t, matcher.Set(context.Background(), testRulesGlob[1:]))

t.Run("case=updated", func(t *testing.T) {
testMatcher(t, matcher, "GET", "https://localhost:34/baz", false, &testRulesGlob[1])
testMatcher(t, matcher, "POST", "https://localhost:1234/foo", true, nil)
testMatcher(t, matcher, "DELETE", "https://localhost:1234/foo", true, nil)
testMatcher(t, matcher, "GET", "https://localhost:34/baz", ProtocolHTTP, false, &testRulesGlob[1])
testMatcher(t, matcher, "POST", "https://localhost:1234/foo", ProtocolHTTP, true, nil)
testMatcher(t, matcher, "DELETE", "https://localhost:1234/foo", ProtocolHTTP, true, nil)
})
})
}
Expand Down
79 changes: 79 additions & 0 deletions rule/rule_test.go
Expand Up @@ -21,6 +21,7 @@
package rule

import (
"encoding/json"
"net/url"
"strconv"
"testing"
Expand Down Expand Up @@ -187,3 +188,81 @@ func TestRuleWithCustomMethod(t *testing.T) {
})
}
}

func TestRule_UnmarshalJSON(t *testing.T) {
var tests = []struct {
name string
json string
expected Rule
err assert.ErrorAssertionFunc
}{

{name: "unmarshal gRPC match",
json: `
{
"id": "123",
"description": "description",
"authorizers": "nil",
"match": { "authority": "example.com", "full_method": "/full/method" }
}
`,
expected: Rule{
ID: "123",
Description: "description",
Match: &MatchGRPC{Authority: "example.com", FullMethod: "/full/method"},
},
err: assert.NoError,
},

{name: "unmarshal HTTP match",
json: `
{
"id": "123",
"description": "description",
"authorizers": "nil",
"match": { "url": "example.com/some/method", "methods": ["GET", "PUT"] }
}
`,
expected: Rule{
ID: "123",
Description: "description",
Match: &Match{Methods: []string{"GET", "PUT"}, URL: "example.com/some/method"},
},
err: assert.NoError,
},

{name: "err on invalid version",
json: `
{
"id": "123",
"version": "42"
}
`,
err: assert.Error,
},

{name: "err on invalid match",
json: `
{
"id": "123",
"description": "description",
"authorizers": "nil",
"match": { foo }
}
`,
err: assert.Error,
},
}

for _, tc := range tests {
t.Run("case="+tc.name, func(t *testing.T) {
var (
actual Rule
err error
)
err = json.Unmarshal([]byte(tc.json), &actual)
assert.Equal(t, tc.expected, actual)
tc.err(t, err)
})
}
}

0 comments on commit dc8c361

Please sign in to comment.