Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dataclients/kubernetes: refactor GetEndpointAddresses test #2936

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions dataclients/kubernetes/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package kubernetes_test

import (
"net/http/httptest"
"os"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/zalando/skipper/dataclients/kubernetes"
"github.com/zalando/skipper/dataclients/kubernetes/kubernetestest"
)

func newTestClient(t *testing.T, opts kubernetes.Options, specPath string) *kubernetes.Client {
t.Helper()

yaml, err := os.Open(specPath)
require.NoError(t, err)
defer yaml.Close()

api, err := kubernetestest.NewAPI(kubernetestest.TestAPIOptions{}, yaml)
require.NoError(t, err)

apiServer := httptest.NewServer(api)
t.Cleanup(apiServer.Close)

opts.KubernetesURL = apiServer.URL

client, err := kubernetes.New(opts)
require.NoError(t, err)
t.Cleanup(client.Close)

return client
}

func TestClientGetEndpointAddresses(t *testing.T) {
t.Run("from empty state", func(t *testing.T) {
client := newTestClient(t,
kubernetes.Options{},
"testdata/ingressV1/ingress-data/lb-target-multi.yaml",
)

// client.LoadAll() is not called

addrs := client.GetEndpointAddresses("namespace1", "service1")
assert.Nil(t, addrs)
})

t.Run("from endpoints", func(t *testing.T) {
client := newTestClient(t,
kubernetes.Options{},
"testdata/ingressV1/ingress-data/lb-target-multi.yaml",
)

_, err := client.LoadAll()
require.NoError(t, err)

addrs := client.GetEndpointAddresses("namespace1", "service1")
assert.Equal(t, []string{"42.0.1.2", "42.0.1.3"}, addrs)

// test subsequent call returns the expected values even when previous result was modified
addrs[0] = "modified"

addrs = client.GetEndpointAddresses("namespace1", "service1")
assert.Equal(t, []string{"42.0.1.2", "42.0.1.3"}, addrs)
})

t.Run("from endpointslices", func(t *testing.T) {
client := newTestClient(t,
kubernetes.Options{
KubernetesEnableEndpointslices: true,
},
"testdata/ingressV1/ingress-data/lb-target-multi-multiple-endpointslices-conditions-all-ready.yaml",
)

_, err := client.LoadAll()
require.NoError(t, err)

addrs := client.GetEndpointAddresses("namespace1", "service1")
assert.Equal(t, []string{"42.0.1.1", "42.0.1.2", "42.0.1.3", "42.0.1.4"}, addrs)

// test subsequent call returns the expected values even when previous result was modified
addrs[0] = "modified"

addrs = client.GetEndpointAddresses("namespace1", "service1")
assert.Equal(t, []string{"42.0.1.1", "42.0.1.2", "42.0.1.3", "42.0.1.4"}, addrs)
})
}
186 changes: 7 additions & 179 deletions dataclients/kubernetes/kube_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,13 @@ import (
)

type testAPI struct {
test *testing.T
services *serviceList
endpoints *endpointList
endpointSlices *endpointSliceList
ingresses *definitions.IngressV1List
secrets *secretList
server *httptest.Server
failNext bool
test *testing.T
services *serviceList
endpoints *endpointList
ingresses *definitions.IngressV1List
secrets *secretList
server *httptest.Server
failNext bool
}

func init() {
Expand Down Expand Up @@ -96,55 +95,6 @@ func testEndpoints(namespace, name string, labels map[string]string, base string
return eps
}

func testEndpointSlicesList() *endpointSliceList {
eps := make([]*endpointSlice, 0)
eps = append(eps, testEndpointSlices("namespace1", "service1", map[string]string{}, "1.1.1", 1, map[string]int{"port1": 8080})...)
eps = append(eps, testEndpointSlices("namespace1", "service2", map[string]string{}, "1.1.2", 1, map[string]int{"port2": 8181})...)
eps = append(eps, testEndpointSlices("namespace2", "service3", map[string]string{}, "2.1.3", 1, map[string]int{"port3": 7272})...)
eps = append(eps, testEndpointSlices("namespace2", "service4", map[string]string{}, "2.1.4", 1, map[string]int{"port4": 4444, "port5": 5555})...)
return &endpointSliceList{
Items: eps,
}
}

func testEndpointSlices(namespace, name string, labels map[string]string, base string, n int, ports map[string]int) []*endpointSlice {
eps := make([]*endpointSlice, 0, 1)

eps = append(eps, &endpointSlice{
Meta: &definitions.Metadata{
Namespace: namespace,
Name: name,
Labels: labels,
},
Endpoints: []*EndpointSliceEndpoints{},
Ports: []*endpointSlicePort{},
})
for i := range eps {
for k, v := range ports {
eps[i].Ports = append(eps[i].Ports, &endpointSlicePort{
Name: k,
Port: v,
})
}
}

b := true
for i := range eps {
for j := 0; j < n; j++ {
ip := fmt.Sprintf("%s.%d", base, i)
eps[i].Endpoints = append(eps[i].Endpoints, &EndpointSliceEndpoints{
Addresses: []string{ip},
Zone: "my-zone",
Conditions: &endpointsliceCondition{
Ready: &b,
},
})
}
}

return eps
}

func testSecret(namespace, name string, labels map[string]string, clusterIP, t string, data map[string]string) *secret {
return &secret{
Metadata: &definitions.Metadata{
Expand Down Expand Up @@ -550,128 +500,6 @@ func (api *testAPI) Close() {
api.server.Close()
}

func TestGetEndpointAddresses(t *testing.T) {
api := newTestAPI(t, nil, &definitions.IngressV1List{})
defer api.Close()

t.Run("state not synced", func(t *testing.T) {
api.ingresses.Items = testIngresses()
api.endpoints = testEndpointList()
api.services = testServices()

client, err := New(Options{
KubernetesURL: api.server.URL,
})
if err != nil {
t.Fatalf("Failed to create client: %v", err)
}
defer client.Close()

ns := "namespace1"
name := "service1"
got := client.GetEndpointAddresses(ns, name)
if got != nil {
t.Fatalf("Failed to nil: %v", got)
}
})

t.Run("Ingress with endpointslices", func(t *testing.T) {
api.ingresses.Items = testIngresses()
api.endpointSlices = testEndpointSlicesList()
api.services = testServices()

client, err := New(Options{
KubernetesURL: api.server.URL,
})
if err != nil {
t.Fatalf("Failed to create client: %v", err)
}
defer client.Close()

_, err = client.LoadAll()
if err != nil {
t.Fatalf("Failed to LoadAll: %v", err)
}
if client.state == nil {
t.Fatal("client state is nil")
}

ns := "namespace1"
name := "service1"
got := client.GetEndpointAddresses(ns, name)
expected := []string{"1.1.1.0"}
if len(got) != len(expected) {
t.Fatalf("Failed to get same size: %d != %d", len(expected), len(got))
}
for i := range got {
if got[i] != expected[i] {
t.Fatalf("Failed to get expected %q, got %q", expected[i], got[i])
}
}

// test subsequent call returns the expected values even when previous result was modified
got[0] = "modified"

got = client.GetEndpointAddresses(ns, name)
if len(got) != len(expected) {
t.Fatalf("Failed to get same size: %d != %d", len(expected), len(got))
}
for i := range got {
if got[i] != expected[i] {
t.Fatalf("Failed to get cached result expected %q, got %q", expected[i], got[i])
}
}
})

t.Run("Ingress with endpoints", func(t *testing.T) {
api.ingresses.Items = testIngresses()
api.endpoints = testEndpointList()
api.services = testServices()

client, err := New(Options{
KubernetesURL: api.server.URL,
})
if err != nil {
t.Fatalf("Failed to create client: %v", err)
}
defer client.Close()

_, err = client.LoadAll()
if err != nil {
t.Fatalf("Failed to LoadAll: %v", err)
}
if client.state == nil {
t.Fatal("client state is nil")
}

ns := "namespace1"
name := "service1"
got := client.GetEndpointAddresses(ns, name)
expected := []string{"1.1.1.0"}
if len(got) != len(expected) {
t.Fatalf("Failed to get same size: %d != %d", len(expected), len(got))
}
for i := range got {
if got[i] != expected[i] {
t.Fatalf("Failed to get expected %q, got %q", expected[i], got[i])
}
}

// test subsequent call returns the expected values even when previous result was modified
got[0] = "modified"

got = client.GetEndpointAddresses(ns, name)
if len(got) != len(expected) {
t.Fatalf("Failed to get same size: %d != %d", len(expected), len(got))
}
for i := range got {
if got[i] != expected[i] {
t.Fatalf("Failed to get cached result expected %q, got %q", expected[i], got[i])
}
}
})
}

func TestIngressClassFilter(t *testing.T) {
tests := []struct {
testTitle string
Expand Down
Loading