Skip to content

Commit

Permalink
NamespaceClient tests
Browse files Browse the repository at this point in the history
Signed-off-by: Frank Jogeleit <[email protected]>
  • Loading branch information
Frank Jogeleit committed Apr 28, 2024
1 parent 76797be commit 6410d00
Show file tree
Hide file tree
Showing 3 changed files with 253 additions and 1 deletion.
3 changes: 2 additions & 1 deletion pkg/helper/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import (
"strings"
"testing"

"github.com/kyverno/policy-reporter/pkg/helper"
"github.com/stretchr/testify/assert"

"github.com/kyverno/policy-reporter/pkg/helper"
)

func TestContains(t *testing.T) {
Expand Down
100 changes: 100 additions & 0 deletions pkg/kubernetes/namespaces/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package namespaces_test

import (
"context"
"errors"
"testing"

gocache "github.com/patrickmn/go-cache"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
v1 "k8s.io/client-go/kubernetes/typed/core/v1"

"github.com/kyverno/policy-reporter/pkg/kubernetes/namespaces"
)

func newFakeClient() v1.NamespaceInterface {
return fake.NewSimpleClientset(
&corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "default",
Labels: map[string]string{
"team": "team-a",
"name": "default",
},
},
},
&corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "user",
Labels: map[string]string{
"team": "team-a",
"name": "user",
},
},
},
).CoreV1().Namespaces()
}

type nsErrorClient struct {
v1.NamespaceInterface
}

func (s *nsErrorClient) List(ctx context.Context, opts metav1.ListOptions) (*corev1.NamespaceList, error) {
return nil, errors.New("error")
}

func TestClient(t *testing.T) {
t.Run("read from api", func(t *testing.T) {
client := namespaces.NewClient(newFakeClient(), gocache.New(gocache.DefaultExpiration, gocache.DefaultExpiration))

list, err := client.List(context.Background(), map[string]string{"name": "default"})

assert.Nil(t, err)
assert.Equal(t, 1, len(list))
})

t.Run("read from cache", func(t *testing.T) {
fake := newFakeClient()
cache := gocache.New(gocache.NoExpiration, gocache.NoExpiration)

client := namespaces.NewClient(fake, cache)

list, err := client.List(context.Background(), map[string]string{"team": "team-a"})

assert.Nil(t, err)
assert.Equal(t, 2, len(list))

fake.Create(context.Background(), &corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "finance",
Labels: map[string]string{
"team": "team-a",
"name": "finance",
},
},
}, metav1.CreateOptions{})

list, err = client.List(context.Background(), map[string]string{"team": "team-a"})

assert.Nil(t, err)
assert.Equal(t, 2, len(list))

cache.Flush()

list, err = client.List(context.Background(), map[string]string{"team": "team-a"})

assert.Nil(t, err)
assert.Equal(t, 3, len(list))
})
t.Run("return error", func(t *testing.T) {
client := namespaces.NewClient(&nsErrorClient{NamespaceInterface: newFakeClient()}, gocache.New(gocache.DefaultExpiration, gocache.DefaultExpiration))

_, err := client.List(context.Background(), map[string]string{"team": "team-a"})

assert.NotNil(t, err)
assert.Equal(t, "error", err.Error())
})
}
151 changes: 151 additions & 0 deletions pkg/kubernetes/retry_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
package kubernetes_test

import (
"context"
"errors"
"testing"

"github.com/kyverno/policy-reporter/pkg/kubernetes"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
kerr "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
v1 "k8s.io/client-go/kubernetes/typed/core/v1"
)

func newFakeClient() v1.NamespaceInterface {
return fake.NewSimpleClientset(
&corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "default",
Labels: map[string]string{
"team": "team-a",
"name": "default",
},
},
},
&corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "user",
Labels: map[string]string{
"team": "team-a",
"name": "user",
},
},
},
).CoreV1().Namespaces()
}

type ns struct {
maxRetry int
try int
err bool
v1.NamespaceInterface
}

func (s *ns) List(ctx context.Context, opts metav1.ListOptions) (*corev1.NamespaceList, error) {
if !s.err {
if s.try >= s.maxRetry {
return s.NamespaceInterface.List(ctx, opts)
}

s.try++
}

return nil, errors.New("error")
}

func TestRetry(t *testing.T) {
t.Run("direct success", func(t *testing.T) {
client := &ns{NamespaceInterface: newFakeClient()}

list, err := kubernetes.Retry(func() (*corev1.NamespaceList, error) {
return client.List(context.Background(), metav1.ListOptions{})
})

assert.Nil(t, err)
assert.Equal(t, 2, len(list.Items))
})

t.Run("retry success", func(t *testing.T) {
client := &ns{maxRetry: 1, NamespaceInterface: newFakeClient()}

list, err := kubernetes.Retry(func() (*corev1.NamespaceList, error) {
return client.List(context.Background(), metav1.ListOptions{})
})

assert.Nil(t, err)
assert.Equal(t, 2, len(list.Items))
})

t.Run("retry error", func(t *testing.T) {
client := &ns{NamespaceInterface: newFakeClient(), err: true}

_, err := kubernetes.Retry(func() (*corev1.NamespaceList, error) {
return client.List(context.Background(), metav1.ListOptions{})
})

assert.NotNil(t, err)
})

t.Run("retry timeout", func(t *testing.T) {
try := 0

_, err := kubernetes.Retry(func() (any, error) {
try++

return nil, &kerr.StatusError{
ErrStatus: metav1.Status{Reason: metav1.StatusReasonTimeout},
}
})

assert.Equal(t, 5, try)
assert.NotNil(t, err)
})

t.Run("retry server timeout", func(t *testing.T) {
try := 0

_, err := kubernetes.Retry(func() (any, error) {
try++

return nil, &kerr.StatusError{
ErrStatus: metav1.Status{Reason: metav1.StatusReasonServerTimeout},
}
})

assert.Equal(t, 5, try)
assert.NotNil(t, err)
})

t.Run("retry service unavailable", func(t *testing.T) {
try := 0

_, err := kubernetes.Retry(func() (any, error) {
try++

return nil, &kerr.StatusError{
ErrStatus: metav1.Status{Reason: metav1.StatusReasonServiceUnavailable},
}
})

assert.Equal(t, 5, try)
assert.NotNil(t, err)
})

t.Run("retry ignore other status", func(t *testing.T) {
try := 0

_, err := kubernetes.Retry(func() (any, error) {
try++

return nil, &kerr.StatusError{
ErrStatus: metav1.Status{Reason: metav1.StatusReasonForbidden},
}
})

assert.Equal(t, 1, try)
assert.NotNil(t, err)
})
}

0 comments on commit 6410d00

Please sign in to comment.