2018-03-02 19:53:40 +00:00
|
|
|
package structs
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sort"
|
2018-03-03 17:43:37 +00:00
|
|
|
"strings"
|
2018-03-02 19:53:40 +00:00
|
|
|
"testing"
|
2018-03-06 18:35:20 +00:00
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
2018-03-02 19:53:40 +00:00
|
|
|
)
|
|
|
|
|
2018-03-05 02:46:33 +00:00
|
|
|
func TestIntentionGetACLPrefix(t *testing.T) {
|
|
|
|
cases := []struct {
|
|
|
|
Name string
|
|
|
|
Input *Intention
|
|
|
|
Expected string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"unset name",
|
|
|
|
&Intention{DestinationName: ""},
|
|
|
|
"",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
"set name",
|
|
|
|
&Intention{DestinationName: "fo"},
|
|
|
|
"fo",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
|
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
|
|
actual, ok := tc.Input.GetACLPrefix()
|
|
|
|
if tc.Expected == "" {
|
|
|
|
if !ok {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
t.Fatal("should not be ok")
|
|
|
|
}
|
|
|
|
|
|
|
|
if actual != tc.Expected {
|
|
|
|
t.Fatalf("bad: %q", actual)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-03 17:43:37 +00:00
|
|
|
func TestIntentionValidate(t *testing.T) {
|
|
|
|
cases := []struct {
|
|
|
|
Name string
|
|
|
|
Modify func(*Intention)
|
|
|
|
Err string
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"long description",
|
|
|
|
func(x *Intention) {
|
|
|
|
x.Description = strings.Repeat("x", metaValueMaxLength+1)
|
|
|
|
},
|
|
|
|
"description exceeds",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
"no action set",
|
|
|
|
func(x *Intention) { x.Action = "" },
|
|
|
|
"action must be set",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
"no SourceNS",
|
|
|
|
func(x *Intention) { x.SourceNS = "" },
|
|
|
|
"SourceNS must be set",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
"no SourceName",
|
|
|
|
func(x *Intention) { x.SourceName = "" },
|
|
|
|
"SourceName must be set",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
"no DestinationNS",
|
|
|
|
func(x *Intention) { x.DestinationNS = "" },
|
|
|
|
"DestinationNS must be set",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
"no DestinationName",
|
|
|
|
func(x *Intention) { x.DestinationName = "" },
|
|
|
|
"DestinationName must be set",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
"SourceNS partial wildcard",
|
|
|
|
func(x *Intention) { x.SourceNS = "foo*" },
|
|
|
|
"partial value",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
"SourceName partial wildcard",
|
|
|
|
func(x *Intention) { x.SourceName = "foo*" },
|
|
|
|
"partial value",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
"SourceName exact following wildcard",
|
|
|
|
func(x *Intention) {
|
|
|
|
x.SourceNS = "*"
|
|
|
|
x.SourceName = "foo"
|
|
|
|
},
|
|
|
|
"follow wildcard",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
"DestinationNS partial wildcard",
|
|
|
|
func(x *Intention) { x.DestinationNS = "foo*" },
|
|
|
|
"partial value",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
"DestinationName partial wildcard",
|
|
|
|
func(x *Intention) { x.DestinationName = "foo*" },
|
|
|
|
"partial value",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
"DestinationName exact following wildcard",
|
|
|
|
func(x *Intention) {
|
|
|
|
x.DestinationNS = "*"
|
|
|
|
x.DestinationName = "foo"
|
|
|
|
},
|
|
|
|
"follow wildcard",
|
|
|
|
},
|
2018-03-03 17:55:27 +00:00
|
|
|
|
|
|
|
{
|
|
|
|
"SourceType is not set",
|
|
|
|
func(x *Intention) { x.SourceType = "" },
|
|
|
|
"SourceType must",
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
"SourceType is other",
|
|
|
|
func(x *Intention) { x.SourceType = IntentionSourceType("other") },
|
|
|
|
"SourceType must",
|
|
|
|
},
|
2018-03-03 17:43:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
|
|
|
t.Run(tc.Name, func(t *testing.T) {
|
2018-03-06 18:35:20 +00:00
|
|
|
assert := assert.New(t)
|
2018-03-03 17:43:37 +00:00
|
|
|
ixn := TestIntention(t)
|
|
|
|
tc.Modify(ixn)
|
|
|
|
|
|
|
|
err := ixn.Validate()
|
2018-03-06 18:35:20 +00:00
|
|
|
assert.Equal(err != nil, tc.Err != "", err)
|
2018-03-03 17:43:37 +00:00
|
|
|
if err == nil {
|
|
|
|
return
|
|
|
|
}
|
2018-03-06 18:35:20 +00:00
|
|
|
|
|
|
|
assert.Contains(strings.ToLower(err.Error()), strings.ToLower(tc.Err))
|
2018-03-03 17:43:37 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-02 19:53:40 +00:00
|
|
|
func TestIntentionPrecedenceSorter(t *testing.T) {
|
|
|
|
cases := []struct {
|
|
|
|
Name string
|
|
|
|
Input [][]string // SrcNS, SrcN, DstNS, DstN
|
|
|
|
Expected [][]string // Same structure as Input
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
"exhaustive list",
|
|
|
|
[][]string{
|
|
|
|
{"*", "*", "exact", "*"},
|
|
|
|
{"*", "*", "*", "*"},
|
|
|
|
{"exact", "*", "exact", "exact"},
|
|
|
|
{"*", "*", "exact", "exact"},
|
|
|
|
{"exact", "exact", "*", "*"},
|
|
|
|
{"exact", "exact", "exact", "exact"},
|
|
|
|
{"exact", "exact", "exact", "*"},
|
|
|
|
{"exact", "*", "exact", "*"},
|
|
|
|
{"exact", "*", "*", "*"},
|
|
|
|
},
|
|
|
|
[][]string{
|
|
|
|
{"exact", "exact", "exact", "exact"},
|
|
|
|
{"exact", "*", "exact", "exact"},
|
|
|
|
{"*", "*", "exact", "exact"},
|
|
|
|
{"exact", "exact", "exact", "*"},
|
|
|
|
{"exact", "*", "exact", "*"},
|
|
|
|
{"*", "*", "exact", "*"},
|
|
|
|
{"exact", "exact", "*", "*"},
|
|
|
|
{"exact", "*", "*", "*"},
|
|
|
|
{"*", "*", "*", "*"},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range cases {
|
|
|
|
t.Run(tc.Name, func(t *testing.T) {
|
2018-03-06 18:35:20 +00:00
|
|
|
assert := assert.New(t)
|
|
|
|
|
2018-03-02 19:53:40 +00:00
|
|
|
var input Intentions
|
|
|
|
for _, v := range tc.Input {
|
|
|
|
input = append(input, &Intention{
|
|
|
|
SourceNS: v[0],
|
|
|
|
SourceName: v[1],
|
|
|
|
DestinationNS: v[2],
|
|
|
|
DestinationName: v[3],
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// Sort
|
|
|
|
sort.Sort(IntentionPrecedenceSorter(input))
|
|
|
|
|
|
|
|
// Get back into a comparable form
|
|
|
|
var actual [][]string
|
|
|
|
for _, v := range input {
|
|
|
|
actual = append(actual, []string{
|
|
|
|
v.SourceNS,
|
|
|
|
v.SourceName,
|
|
|
|
v.DestinationNS,
|
|
|
|
v.DestinationName,
|
|
|
|
})
|
|
|
|
}
|
2018-03-06 18:35:20 +00:00
|
|
|
assert.Equal(tc.Expected, actual)
|
2018-03-02 19:53:40 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|