mirror of
https://github.com/outbackdingo/matchbox.git
synced 2026-01-27 10:19:35 +00:00
167 lines
4.6 KiB
Go
167 lines
4.6 KiB
Go
package api
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"sort"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"golang.org/x/net/context"
|
|
)
|
|
|
|
var (
|
|
validMACStr = "52:da:00:89:d8:10"
|
|
nonNormalizedMACStr = "52:dA:00:89:d8:10"
|
|
testGroup = Group{
|
|
Name: "test group",
|
|
Spec: "g1h2i3j4",
|
|
Metadata: map[string]interface{}{
|
|
"k8s_version": "v1.1.2",
|
|
"pod_network": "10.2.0.0/16",
|
|
"service_name": "etcd2",
|
|
},
|
|
Matcher: RequirementSet(map[string]string{"uuid": "a1b2c3d4"}),
|
|
}
|
|
testGroupWithMAC = Group{
|
|
Name: "machine with a MAC",
|
|
Spec: "g1h2i3j4",
|
|
Matcher: RequirementSet(map[string]string{"mac": validMACStr}),
|
|
}
|
|
testGroupNoSpec = &Group{
|
|
Name: "test group with missing spec",
|
|
Spec: "",
|
|
Matcher: RequirementSet(map[string]string{"uuid": "a1b2c3d4"}),
|
|
}
|
|
)
|
|
|
|
func TestByMatcherSort(t *testing.T) {
|
|
oneCondition := Group{
|
|
Name: "two matcher conditions",
|
|
Matcher: RequirementSet(map[string]string{
|
|
"region": "a",
|
|
}),
|
|
}
|
|
twoConditions := Group{
|
|
Name: "group with two matcher conditions",
|
|
Matcher: RequirementSet(map[string]string{
|
|
"region": "a",
|
|
"zone": "z",
|
|
}),
|
|
}
|
|
dualConditions := Group{
|
|
Name: "another group with two matcher conditions",
|
|
Matcher: RequirementSet(map[string]string{
|
|
"region": "b",
|
|
"zone": "z",
|
|
}),
|
|
}
|
|
cases := []struct {
|
|
input []Group
|
|
expected []Group
|
|
}{
|
|
{[]Group{oneCondition, dualConditions, twoConditions}, []Group{oneCondition, twoConditions, dualConditions}},
|
|
{[]Group{twoConditions, dualConditions, oneCondition}, []Group{oneCondition, twoConditions, dualConditions}},
|
|
{[]Group{testGroup, testGroupWithMAC, oneCondition, twoConditions, dualConditions}, []Group{testGroupWithMAC, oneCondition, testGroup, twoConditions, dualConditions}},
|
|
}
|
|
// assert that
|
|
// - groups are sorted in increasing Matcher length
|
|
// - when Matcher lengths are equal, groups are sorted by key=value strings.
|
|
// - group ordering is deterministic
|
|
for _, c := range cases {
|
|
sort.Sort(byMatcher(c.input))
|
|
assert.Equal(t, c.expected, c.input)
|
|
}
|
|
}
|
|
|
|
func TestNewGroupsResource(t *testing.T) {
|
|
store := &fixedStore{}
|
|
gr := newGroupsResource(store)
|
|
assert.Equal(t, store, gr.store)
|
|
}
|
|
|
|
func TestGroupsResource_ListGroups(t *testing.T) {
|
|
expectedGroups := []Group{Group{Name: "test group"}}
|
|
store := &fixedStore{
|
|
Groups: expectedGroups,
|
|
}
|
|
res := newGroupsResource(store)
|
|
groups, err := res.listGroups()
|
|
assert.Nil(t, err)
|
|
assert.Equal(t, expectedGroups, groups)
|
|
}
|
|
|
|
func TestGroupsResource_MatchSpecHandler(t *testing.T) {
|
|
store := &fixedStore{
|
|
Groups: []Group{testGroup},
|
|
Specs: map[string]*Spec{testGroup.Spec: testSpec},
|
|
}
|
|
gr := newGroupsResource(store)
|
|
next := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
|
|
spec, err := specFromContext(ctx)
|
|
assert.Nil(t, err)
|
|
assert.Equal(t, testSpec, spec)
|
|
fmt.Fprintf(w, "next handler called")
|
|
}
|
|
// assert that:
|
|
// - request arguments are used to match uuid=a1b2c3d4 -> testGroup
|
|
// - the group's Spec is found by id and added to the context
|
|
// - next handler is called
|
|
h := gr.matchSpecHandler(ContextHandlerFunc(next))
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "?uuid=a1b2c3d4", nil)
|
|
h.ServeHTTP(context.Background(), w, req)
|
|
assert.Equal(t, "next handler called", w.Body.String())
|
|
}
|
|
|
|
func TestGroupsResource_MatchGroupHandler(t *testing.T) {
|
|
store := &fixedStore{
|
|
Groups: []Group{testGroup},
|
|
}
|
|
gr := newGroupsResource(store)
|
|
next := func(ctx context.Context, w http.ResponseWriter, req *http.Request) {
|
|
group, err := groupFromContext(ctx)
|
|
assert.Nil(t, err)
|
|
assert.Equal(t, &testGroup, group)
|
|
fmt.Fprintf(w, "next handler called")
|
|
}
|
|
// assert that:
|
|
// - request arguments are used to match uuid=a1b2c3d4 -> testGroup
|
|
// - next handler is called
|
|
h := gr.matchGroupHandler(ContextHandlerFunc(next))
|
|
w := httptest.NewRecorder()
|
|
req, _ := http.NewRequest("GET", "?uuid=a1b2c3d4", nil)
|
|
h.ServeHTTP(context.Background(), w, req)
|
|
assert.Equal(t, "next handler called", w.Body.String())
|
|
}
|
|
|
|
func TestGroupsResource_FindMatch(t *testing.T) {
|
|
store := &fixedStore{
|
|
Groups: []Group{testGroup},
|
|
Specs: map[string]*Spec{testGroup.Spec: testSpec},
|
|
}
|
|
uuidLabel := LabelSet(map[string]string{
|
|
"uuid": "a1b2c3d4",
|
|
})
|
|
|
|
cases := []struct {
|
|
store Store
|
|
labels Labels
|
|
expectedGroup *Group
|
|
expectedErr error
|
|
}{
|
|
{store, uuidLabel, &testGroup, nil},
|
|
{store, nil, nil, errNoMatchingGroup},
|
|
// no groups in the store
|
|
{&emptyStore{}, uuidLabel, nil, errNoMatchingGroup},
|
|
}
|
|
|
|
for _, c := range cases {
|
|
gr := newGroupsResource(c.store)
|
|
group, err := gr.findMatch(c.labels)
|
|
assert.Equal(t, c.expectedGroup, group)
|
|
assert.Equal(t, c.expectedErr, err)
|
|
}
|
|
}
|