[#76] chain: Increase unit-test coverage for chain related types
DCO action / DCO (pull_request) Successful in 1m8s Details
Tests and linters / Tests (1.20) (pull_request) Successful in 1m22s Details
Tests and linters / Tests (1.21) (pull_request) Successful in 1m17s Details
Tests and linters / Staticcheck (pull_request) Successful in 1m31s Details
Tests and linters / Tests with -race (pull_request) Successful in 1m43s Details
Tests and linters / Lint (pull_request) Successful in 2m17s Details

* Add more unit-test cases.

Signed-off-by: Airat Arifullin <aarifullin@yadro.com>
pull/77/head
Airat Arifullin 2024-05-22 13:49:42 +03:00
parent 1f6f4163d4
commit d7ed188f68
1 changed files with 795 additions and 54 deletions

View File

@ -1,6 +1,8 @@
package chain
import (
"fmt"
"strings"
"testing"
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/resource/testutil"
@ -50,7 +52,7 @@ func TestEncodeDecode(t *testing.T) {
require.Equal(t, expected, actual)
}
func TestReturnFirstMatch(t *testing.T) {
func TestChainMatch(t *testing.T) {
ch := Chain{
Rules: []Rule{
{
@ -87,9 +89,195 @@ func TestReturnFirstMatch(t *testing.T) {
require.True(t, found)
require.Equal(t, Allow, st)
})
t.Run("unknown match", func(t *testing.T) {
ch.MatchType = MatchType(255)
request := testutil.NewRequest(native.MethodGetObject, resource, nil)
require.PanicsWithValue(t, "unknown MatchType 255", func() {
ch.Match(request)
})
})
t.Run("no rule found", func(t *testing.T) {
ch.MatchType = MatchTypeFirstMatch
request := testutil.NewRequest(native.MethodGetObject, resource, nil)
st, found := ch.Match(request)
require.False(t, found)
require.Equal(t, NoRuleFound, st)
})
}
func TestCondSliceContainsMatch(t *testing.T) {
func TestAnyAllConditionMatch(t *testing.T) {
ch := Chain{
Rules: []Rule{
{
Status: Allow,
Actions: Actions{Names: []string{native.MethodPutObject}},
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
Condition: []Condition{
{
Op: CondIPAddress,
Kind: KindRequest,
Key: common.PropertyKeyFrostFSSourceIP,
Value: "192.92.1.1/20",
},
{
Op: CondStringEquals,
Kind: KindRequest,
Key: native.PropertyKeyActorRole,
Value: "owner",
},
{
Op: CondStringEquals,
Kind: KindResource,
Key: native.PropertyKeyObjectID,
Value: "79xGoKYwhyJQhrDNb7bHhY1WCvN6trHJPTjKkw24c6W9",
},
},
},
}}
t.Run("match by all conditions", func(t *testing.T) {
ch.Rules[0].Any = false
resource := testutil.NewResource(native.ResourceFormatRootContainers, map[string]string{
native.PropertyKeyObjectID: "79xGoKYwhyJQhrDNb7bHhY1WCvN6trHJPTjKkw24c6W9",
})
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
native.PropertyKeyActorRole: "owner",
})
st, found := ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
common.PropertyKeyFrostFSSourceIP: "192.93.1.91",
})
st, found = ch.Match(request)
require.False(t, found)
require.Equal(t, NoRuleFound, st)
})
t.Run("match by any condition", func(t *testing.T) {
ch.Rules[0].Any = true
resource := testutil.NewResource(native.ResourceFormatRootContainers, map[string]string{
native.PropertyKeyObjectID: "79xGoKYwhyJQhrDNb7bHhY1WCvN6trHJPTjKkw24c6W9",
})
request := testutil.NewRequest(native.MethodPutObject, resource, nil)
st, found := ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
native.PropertyKeyActorRole: "owner",
})
st, found = ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
resource = testutil.NewResource(native.ResourceFormatRootContainers, map[string]string{})
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
})
st, found = ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
common.PropertyKeyFrostFSSourceIP: "192.93.1.91",
})
st, found = ch.Match(request)
require.False(t, found)
require.Equal(t, NoRuleFound, st)
})
}
func TestConditionMatch(t *testing.T) {
t.Run("condition types", func(t *testing.T) {
t.Run("slice condition type", testCondSliceContainsMatch)
t.Run("numeric condition types", testNumericConditionsMatch)
t.Run("string condition types", testStringConiditionsMatch)
t.Run("ip conidition types", testIPConditionMatch)
t.Run("unknown condition type", func(t *testing.T) {
ch := Chain{Rules: []Rule{{
Status: Allow,
Actions: Actions{Names: []string{native.MethodPutObject}},
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
Condition: []Condition{{
Op: ConditionType(255),
Kind: KindRequest,
Key: common.PropertyKeyFrostFSSourceIP,
Value: "192.92.1.1/20",
}},
}}}
resource := testutil.NewResource(native.ResourceFormatRootContainers, map[string]string{
native.PropertyKeyObjectID: "79xGoKYwhyJQhrDNb7bHhY1WCvN6trHJPTjKkw24c6W9",
})
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
native.PropertyKeyActorRole: "owner",
})
require.PanicsWithValue(t, "unimplemented: 255", func() {
ch.Match(request)
})
})
})
t.Run("kind", func(t *testing.T) {
resource := testutil.NewResource(native.ResourceFormatRootContainers, map[string]string{
native.PropertyKeyObjectID: "79xGoKYwhyJQhrDNb7bHhY1WCvN6trHJPTjKkw24c6W9",
})
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
native.PropertyKeyActorRole: "owner",
})
t.Run("resource", func(t *testing.T) {
cond := Condition{
Op: CondStringEquals,
Kind: KindResource,
Key: native.PropertyKeyObjectID,
Value: "79xGoKYwhyJQhrDNb7bHhY1WCvN6trHJPTjKkw24c6W9",
}
found := cond.Match(request)
require.True(t, found)
})
t.Run("request", func(t *testing.T) {
cond := Condition{
Op: CondStringEquals,
Kind: KindRequest,
Key: native.PropertyKeyActorRole,
Value: "owner",
}
found := cond.Match(request)
require.True(t, found)
})
t.Run("unknown", func(t *testing.T) {
cond := Condition{
Op: CondStringEquals,
Kind: ConditionKindType(255),
Key: native.PropertyKeyActorRole,
Value: "owner",
}
require.PanicsWithValue(t, "unknown condition type: 255", func() {
cond.Match(request)
})
})
})
}
func testCondSliceContainsMatch(t *testing.T) {
propKey := common.PropertyKeyFrostFSIDGroupID
groupID := "1"
@ -151,7 +339,7 @@ func TestCondSliceContainsMatch(t *testing.T) {
}
}
func TestNumericConditionsMatch(t *testing.T) {
func testNumericConditionsMatch(t *testing.T) {
propKey := s3.PropertyKeyMaxKeys
for _, tc := range []struct {
@ -227,61 +415,614 @@ func TestNumericConditionsMatch(t *testing.T) {
}
}
func TestInvalidNumericValues(t *testing.T) {
propKey := s3.PropertyKeyMaxKeys
propValues := []string{"", "invalid"}
func testStringConiditionsMatch(t *testing.T) {
propKey := fmt.Sprintf(common.PropertyKeyFormatFrostFSIDUserClaim, "some-tag")
val := "tag-value"
for _, tc := range []struct {
name string
conditionType ConditionType
match bool
}{
{
name: "NumericEquals condition",
conditionType: CondNumericEquals,
match: false,
},
{
name: "NumericNotEquals condition",
conditionType: CondNumericNotEquals,
match: true,
},
{
name: "NumericLessThan condition",
conditionType: CondNumericLessThan,
match: false,
},
{
name: "NumericLessThanEquals condition",
conditionType: CondNumericLessThanEquals,
match: false,
},
{
name: "NumericGreaterThan condition",
conditionType: CondNumericGreaterThan,
match: false,
},
{
name: "NumericGreaterThanEquals condition",
conditionType: CondNumericGreaterThanEquals,
match: false,
},
} {
t.Run(tc.name, func(t *testing.T) {
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
condition := Condition{
Op: tc.conditionType,
t.Run(CondStringEquals.String(), func(t *testing.T) {
ch := Chain{Rules: []Rule{{
Status: Allow,
Actions: Actions{Names: []string{native.MethodPutObject}},
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
Condition: []Condition{{
Op: CondStringEquals,
Kind: KindRequest,
Key: propKey,
Value: "50",
}
Value: val,
}},
}}}
for _, propValue := range propValues {
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{propKey: propValue})
match := condition.Match(request)
require.Equal(t, tc.match, match)
}
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: val,
})
st, found := ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: "distort_tag_value" + val,
})
st, found = ch.Match(request)
require.False(t, found)
require.Equal(t, NoRuleFound, st)
})
t.Run(CondStringNotEquals.String(), func(t *testing.T) {
ch := Chain{Rules: []Rule{{
Status: Allow,
Actions: Actions{Names: []string{native.MethodPutObject}},
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
Condition: []Condition{{
Op: CondStringNotEquals,
Kind: KindRequest,
Key: propKey,
Value: val,
}},
}}}
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: "distort_tag_value" + val,
})
st, found := ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: val,
})
st, found = ch.Match(request)
require.False(t, found)
require.Equal(t, NoRuleFound, st)
})
t.Run(CondStringEqualsIgnoreCase.String(), func(t *testing.T) {
ch := Chain{Rules: []Rule{{
Status: Allow,
Actions: Actions{Names: []string{native.MethodPutObject}},
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
Condition: []Condition{{
Op: CondStringEqualsIgnoreCase,
Kind: KindRequest,
Key: propKey,
Value: val,
}},
}}}
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: strings.ToUpper(val),
})
st, found := ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: strings.ToUpper("distort_tag_value" + val),
})
st, found = ch.Match(request)
require.False(t, found)
require.Equal(t, NoRuleFound, st)
})
t.Run(CondStringNotEqualsIgnoreCase.String(), func(t *testing.T) {
ch := Chain{Rules: []Rule{{
Status: Allow,
Actions: Actions{Names: []string{native.MethodPutObject}},
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
Condition: []Condition{{
Op: CondStringNotEqualsIgnoreCase,
Kind: KindRequest,
Key: propKey,
Value: val,
}},
}}}
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: strings.ToUpper("distort_tag_value" + val),
})
st, found := ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: strings.ToUpper(val),
})
st, found = ch.Match(request)
require.False(t, found)
require.Equal(t, NoRuleFound, st)
})
t.Run(CondStringLike.String(), func(t *testing.T) {
ch := Chain{Rules: []Rule{{
Status: Allow,
Actions: Actions{Names: []string{native.MethodPutObject}},
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
Condition: []Condition{{
Op: CondStringLike,
Kind: KindRequest,
Key: propKey,
Value: val + "*",
}},
}}}
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: val + "suffix",
})
st, found := ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: string([]byte(val)[:len(val)-1]), //cut last letter
})
st, found = ch.Match(request)
require.False(t, found)
require.Equal(t, NoRuleFound, st)
})
t.Run(CondStringNotLike.String(), func(t *testing.T) {
ch := Chain{Rules: []Rule{{
Status: Allow,
Actions: Actions{Names: []string{native.MethodPutObject}},
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
Condition: []Condition{{
Op: CondStringNotLike,
Kind: KindRequest,
Key: propKey,
Value: "prefix" + val + "*",
}},
}}}
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: val + "suffix",
})
st, found := ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: "prefix" + val,
})
st, found = ch.Match(request)
require.False(t, found)
require.Equal(t, NoRuleFound, st)
})
t.Run(CondStringLessThan.String(), func(t *testing.T) {
ch := Chain{Rules: []Rule{{
Status: Allow,
Actions: Actions{Names: []string{native.MethodPutObject}},
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
Condition: []Condition{{
Op: CondStringLessThan,
Kind: KindRequest,
Key: propKey,
Value: val + "b",
}},
}}}
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: val + "a",
})
st, found := ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: val + "c",
})
st, found = ch.Match(request)
require.False(t, found)
require.Equal(t, NoRuleFound, st)
})
t.Run(CondStringLessThanEquals.String(), func(t *testing.T) {
ch := Chain{Rules: []Rule{{
Status: Allow,
Actions: Actions{Names: []string{native.MethodPutObject}},
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
Condition: []Condition{{
Op: CondStringLessThanEquals,
Kind: KindRequest,
Key: propKey,
Value: val + "b",
}},
}}}
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: val + "a",
})
st, found := ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: val + "b",
})
st, found = ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
})
t.Run(CondStringGreaterThan.String(), func(t *testing.T) {
ch := Chain{Rules: []Rule{{
Status: Allow,
Actions: Actions{Names: []string{native.MethodPutObject}},
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
Condition: []Condition{{
Op: CondStringGreaterThan,
Kind: KindRequest,
Key: propKey,
Value: val + "b",
}},
}}}
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: val + "c",
})
st, found := ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: val + "b",
})
st, found = ch.Match(request)
require.False(t, found)
require.Equal(t, NoRuleFound, st)
})
t.Run(CondStringGreaterThanEquals.String(), func(t *testing.T) {
ch := Chain{Rules: []Rule{{
Status: Allow,
Actions: Actions{Names: []string{native.MethodPutObject}},
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
Condition: []Condition{{
Op: CondStringGreaterThanEquals,
Kind: KindRequest,
Key: propKey,
Value: val + "b",
}},
}}}
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: val + "c",
})
st, found := ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
propKey: val + "b",
})
st, found = ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
})
}
func testIPConditionMatch(t *testing.T) {
t.Run(CondIPAddress.String(), func(t *testing.T) {
ch := Chain{Rules: []Rule{{
Status: Allow,
Actions: Actions{Names: []string{native.MethodPutObject}},
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
Condition: []Condition{{
Op: CondIPAddress,
Kind: KindRequest,
Key: common.PropertyKeyFrostFSSourceIP,
Value: "192.92.1.1/20",
}},
}}}
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
})
st, found := ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
common.PropertyKeyFrostFSSourceIP: "192.93.1.91",
})
st, found = ch.Match(request)
require.False(t, found)
require.Equal(t, NoRuleFound, st)
})
t.Run(CondNotIPAddress.String(), func(t *testing.T) {
ch := Chain{Rules: []Rule{{
Status: Allow,
Actions: Actions{Names: []string{native.MethodPutObject}},
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
Condition: []Condition{{
Op: CondNotIPAddress,
Kind: KindRequest,
Key: common.PropertyKeyFrostFSSourceIP,
Value: "192.92.1.1/20",
}},
}}}
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
common.PropertyKeyFrostFSSourceIP: "192.93.1.91",
})
st, found := ch.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
request = testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
})
st, found = ch.Match(request)
require.False(t, found)
require.Equal(t, NoRuleFound, st)
})
t.Run("invalid ip address condition value", func(t *testing.T) {
ch := Chain{Rules: []Rule{{
Status: Allow,
Actions: Actions{Names: []string{native.MethodPutObject}},
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
Condition: []Condition{{
Op: CondIPAddress,
Kind: KindRequest,
Key: common.PropertyKeyFrostFSSourceIP,
Value: "192.92.1.1:33333",
}},
}}}
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
})
st, found := ch.Match(request)
require.False(t, found)
require.Equal(t, NoRuleFound, st)
})
t.Run("match ip", func(t *testing.T) {
cond := Condition{
Op: CondIPAddress,
Kind: KindRequest,
Key: common.PropertyKeyFrostFSSourceIP,
Value: "192.92.1.1/10",
}
require.NotPanics(t, func() {
cond.matchIP("192.92.1.91")
})
require.PanicsWithValue(t, "unimplemented: 10", func() {
cond.Op = CondNumericEquals
cond.matchIP("192.92.1.91")
})
})
}
func TestInvalidNumericValues(t *testing.T) {
t.Run("invalid request property", func(t *testing.T) {
propKey := s3.PropertyKeyMaxKeys
propValues := []string{"", "invalid"}
for _, tc := range []struct {
name string
conditionType ConditionType
match bool
}{
{
name: "NumericEquals condition",
conditionType: CondNumericEquals,
match: false,
},
{
name: "NumericNotEquals condition",
conditionType: CondNumericNotEquals,
match: true,
},
{
name: "NumericLessThan condition",
conditionType: CondNumericLessThan,
match: false,
},
{
name: "NumericLessThanEquals condition",
conditionType: CondNumericLessThanEquals,
match: false,
},
{
name: "NumericGreaterThan condition",
conditionType: CondNumericGreaterThan,
match: false,
},
{
name: "NumericGreaterThanEquals condition",
conditionType: CondNumericGreaterThanEquals,
match: false,
},
} {
t.Run(tc.name, func(t *testing.T) {
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
condition := Condition{
Op: tc.conditionType,
Kind: KindRequest,
Key: propKey,
Value: "50",
}
for _, propValue := range propValues {
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{propKey: propValue})
match := condition.Match(request)
require.Equal(t, tc.match, match)
}
})
}
})
t.Run("invalid condition numeric value", func(t *testing.T) {
propKey := s3.PropertyKeyMaxKeys
condition := Condition{
Kind: KindRequest,
Key: propKey,
Value: "invalid",
}
t.Run("match on CondNumericNotEquals", func(t *testing.T) {
condition.Op = CondNumericNotEquals
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{propKey: "50"})
match := condition.Match(request)
require.Equal(t, true, match)
})
t.Run("non-match on non-CondNumericNotEquals", func(t *testing.T) {
condition.Op = CondNumericEquals
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{propKey: "50"})
match := condition.Match(request)
require.Equal(t, false, match)
})
t.Run("match numeric", func(t *testing.T) {
cond := Condition{
Op: CondNumericLessThan,
Kind: KindRequest,
Key: s3.PropertyKeyMaxKeys,
Value: "5",
}
require.NotPanics(t, func() {
cond.matchNumeric("6")
})
require.PanicsWithValue(t, "unimplemented: 0", func() {
cond.Op = CondStringEquals
cond.matchNumeric("10")
})
})
})
}
func TestCondTypeStringification(t *testing.T) {
for _, pair := range []struct {
cond ConditionType
expectedString string
}{
{CondStringEquals, "StringEquals"},
{CondStringNotEquals, "StringNotEquals"},
{CondStringEqualsIgnoreCase, "StringEqualsIgnoreCase"},
{CondStringNotEqualsIgnoreCase, "StringNotEqualsIgnoreCase"},
{CondStringLike, "StringLike"},
{CondStringNotLike, "StringNotLike"},
{CondStringLessThan, "StringLessThan"},
{CondStringLessThanEquals, "StringLessThanEquals"},
{CondStringGreaterThan, "StringGreaterThan"},
{CondStringGreaterThanEquals, "StringGreaterThanEquals"},
{CondNumericEquals, "NumericEquals"},
{CondNumericNotEquals, "NumericNotEquals"},
{CondNumericLessThan, "NumericLessThan"},
{CondNumericLessThanEquals, "NumericLessThanEquals"},
{CondNumericGreaterThan, "NumericGreaterThan"},
{CondNumericGreaterThanEquals, "NumericGreaterThanEquals"},
{CondSliceContains, "SliceContains"},
{CondIPAddress, "IPAddress"},
{CondNotIPAddress, "NotIPAddress"},
{ConditionType(255), "unknown condition type"},
} {
require.Equal(t, pair.expectedString, pair.cond.String())
}
}
func TestRuleMatch(t *testing.T) {
rule := Rule{
Status: Allow,
Actions: Actions{Names: []string{native.MethodPutObject}},
Resources: Resources{Names: []string{native.ResourceFormatRootContainers}},
Condition: []Condition{{
Op: CondIPAddress,
Kind: KindRequest,
Key: common.PropertyKeyFrostFSSourceIP,
Value: "192.92.1.1/20",
}},
}
t.Run("match", func(t *testing.T) {
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
})
st, found := rule.Match(request)
require.True(t, found)
require.Equal(t, Allow, st)
})
t.Run("not matching resource name", func(t *testing.T) {
resource := testutil.NewResource(fmt.Sprintf(native.ResourceFormatNamespaceContainers, "namespicy"), nil)
request := testutil.NewRequest(native.MethodPutObject, resource, map[string]string{
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
})
st, found := rule.Match(request)
require.False(t, found)
require.Equal(t, NoRuleFound, st)
})
t.Run("not matching action", func(t *testing.T) {
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodGetObject, resource, map[string]string{
common.PropertyKeyFrostFSSourceIP: "192.92.1.91",
})
st, found := rule.Match(request)
require.False(t, found)
require.Equal(t, NoRuleFound, st)
})
t.Run("not matching condition", func(t *testing.T) {
resource := testutil.NewResource(native.ResourceFormatRootContainers, nil)
request := testutil.NewRequest(native.MethodGetObject, resource, map[string]string{
common.PropertyKeyFrostFSSourceIP: "192.93.1.91",
})
st, found := rule.Match(request)
require.False(t, found)
require.Equal(t, NoRuleFound, st)
})
}