Use custom mock in vkubelet tests
Don't use actual "mock" provider in vkubelet to reduce awkward import cycles. Really the "mock" provider is for e2e tests. Instead create our own mock in the vkubelet package specifically for unit tests which can also be more easily customized to test edge cases.
This commit is contained in:
@@ -2,9 +2,11 @@ package vkubelet
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"path"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/virtual-kubelet/virtual-kubelet/providers/mock"
|
"github.com/cpuguy83/strongerrors"
|
||||||
|
pkgerrors "github.com/pkg/errors"
|
||||||
testutil "github.com/virtual-kubelet/virtual-kubelet/test/util"
|
testutil "github.com/virtual-kubelet/virtual-kubelet/test/util"
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
is "gotest.tools/assert/cmp"
|
is "gotest.tools/assert/cmp"
|
||||||
@@ -12,60 +14,81 @@ import (
|
|||||||
"k8s.io/client-go/kubernetes/fake"
|
"k8s.io/client-go/kubernetes/fake"
|
||||||
)
|
)
|
||||||
|
|
||||||
type FakeProvider struct {
|
type mockProvider struct {
|
||||||
*mock.MockProvider
|
pods map[string]*corev1.Pod
|
||||||
createFn func()
|
|
||||||
updateFn func()
|
creates int
|
||||||
|
updates int
|
||||||
|
deletes int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FakeProvider) CreatePod(ctx context.Context, pod *corev1.Pod) error {
|
func (m *mockProvider) CreatePod(ctx context.Context, pod *corev1.Pod) error {
|
||||||
f.createFn()
|
m.pods[path.Join(pod.GetNamespace(), pod.GetName())] = pod
|
||||||
return f.MockProvider.CreatePod(ctx, pod)
|
m.creates++
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FakeProvider) UpdatePod(ctx context.Context, pod *corev1.Pod) error {
|
func (m *mockProvider) UpdatePod(ctx context.Context, pod *corev1.Pod) error {
|
||||||
f.updateFn()
|
m.pods[path.Join(pod.GetNamespace(), pod.GetName())] = pod
|
||||||
return f.MockProvider.CreatePod(ctx, pod)
|
m.updates++
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockProvider) GetPod(ctx context.Context, namespace, name string) (*corev1.Pod, error) {
|
||||||
|
p := m.pods[path.Join(namespace, name)]
|
||||||
|
if p == nil {
|
||||||
|
return nil, strongerrors.NotFound(pkgerrors.New("not found"))
|
||||||
|
}
|
||||||
|
return p, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockProvider) GetPodStatus(ctx context.Context, namespace, name string) (*corev1.PodStatus, error) {
|
||||||
|
p := m.pods[path.Join(namespace, name)]
|
||||||
|
if p == nil {
|
||||||
|
return nil, strongerrors.NotFound(pkgerrors.New("not found"))
|
||||||
|
}
|
||||||
|
return &p.Status, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockProvider) DeletePod(ctx context.Context, p *corev1.Pod) error {
|
||||||
|
delete(m.pods, path.Join(p.GetNamespace(), p.GetName()))
|
||||||
|
m.deletes++
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *mockProvider) GetPods(_ context.Context) ([]*corev1.Pod, error) {
|
||||||
|
ls := make([]*corev1.Pod, 0, len(m.pods))
|
||||||
|
for _, p := range ls {
|
||||||
|
ls = append(ls, p)
|
||||||
|
}
|
||||||
|
return ls, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type TestServer struct {
|
type TestServer struct {
|
||||||
*Server
|
*Server
|
||||||
mock *FakeProvider
|
mock *mockProvider
|
||||||
client *fake.Clientset
|
client *fake.Clientset
|
||||||
}
|
}
|
||||||
|
|
||||||
func newMockProvider(t *testing.T) (*mock.MockProvider, error) {
|
func newMockProvider() *mockProvider {
|
||||||
return mock.NewMockProviderMockConfig(
|
return &mockProvider{pods: make(map[string]*corev1.Pod)}
|
||||||
mock.MockConfig{},
|
|
||||||
"vk123",
|
|
||||||
"linux",
|
|
||||||
"127.0.0.1",
|
|
||||||
443,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestServer(t *testing.T) *TestServer {
|
func newTestServer() *TestServer {
|
||||||
|
|
||||||
mockProvider, err := newMockProvider(t)
|
|
||||||
assert.Check(t, is.Nil(err))
|
|
||||||
|
|
||||||
fk8s := fake.NewSimpleClientset()
|
fk8s := fake.NewSimpleClientset()
|
||||||
|
|
||||||
fakeProvider := &FakeProvider{
|
|
||||||
MockProvider: mockProvider,
|
|
||||||
}
|
|
||||||
|
|
||||||
rm := testutil.FakeResourceManager()
|
rm := testutil.FakeResourceManager()
|
||||||
|
p := newMockProvider()
|
||||||
|
|
||||||
tsvr := &TestServer{
|
tsvr := &TestServer{
|
||||||
Server: &Server{
|
Server: &Server{
|
||||||
namespace: "default",
|
namespace: "default",
|
||||||
nodeName: "vk123",
|
nodeName: "vk123",
|
||||||
provider: fakeProvider,
|
provider: p,
|
||||||
resourceManager: rm,
|
resourceManager: rm,
|
||||||
k8sClient: fk8s,
|
k8sClient: fk8s,
|
||||||
},
|
},
|
||||||
mock: fakeProvider,
|
mock: p,
|
||||||
client: fk8s,
|
client: fk8s,
|
||||||
}
|
}
|
||||||
return tsvr
|
return tsvr
|
||||||
@@ -146,7 +169,7 @@ func TestPodHashingDifferent(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPodCreateNewPod(t *testing.T) {
|
func TestPodCreateNewPod(t *testing.T) {
|
||||||
svr := newTestServer(t)
|
svr := newTestServer()
|
||||||
|
|
||||||
pod := &corev1.Pod{}
|
pod := &corev1.Pod{}
|
||||||
pod.ObjectMeta.Namespace = "default"
|
pod.ObjectMeta.Namespace = "default"
|
||||||
@@ -166,25 +189,16 @@ func TestPodCreateNewPod(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
created := false
|
|
||||||
updated := false
|
|
||||||
// The pod doesn't exist, we should invoke the CreatePod() method of the provider
|
|
||||||
svr.mock.createFn = func() {
|
|
||||||
created = true
|
|
||||||
}
|
|
||||||
svr.mock.updateFn = func() {
|
|
||||||
updated = true
|
|
||||||
}
|
|
||||||
er := testutil.FakeEventRecorder(5)
|
er := testutil.FakeEventRecorder(5)
|
||||||
err := svr.createOrUpdatePod(context.Background(), pod, er)
|
err := svr.createOrUpdatePod(context.Background(), pod, er)
|
||||||
assert.Check(t, is.Nil(err))
|
assert.Check(t, is.Nil(err))
|
||||||
// createOrUpdate called CreatePod but did not call UpdatePod because the pod did not exist
|
// createOrUpdate called CreatePod but did not call UpdatePod because the pod did not exist
|
||||||
assert.Check(t, created)
|
assert.Check(t, is.Equal(svr.mock.creates, 1))
|
||||||
assert.Check(t, !updated)
|
assert.Check(t, is.Equal(svr.mock.updates, 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPodUpdateExisting(t *testing.T) {
|
func TestPodUpdateExisting(t *testing.T) {
|
||||||
svr := newTestServer(t)
|
svr := newTestServer()
|
||||||
|
|
||||||
pod := &corev1.Pod{}
|
pod := &corev1.Pod{}
|
||||||
pod.ObjectMeta.Namespace = "default"
|
pod.ObjectMeta.Namespace = "default"
|
||||||
@@ -204,17 +218,10 @@ func TestPodUpdateExisting(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err := svr.mock.MockProvider.CreatePod(context.Background(), pod)
|
err := svr.provider.CreatePod(context.Background(), pod)
|
||||||
assert.Check(t, is.Nil(err))
|
assert.Check(t, is.Nil(err))
|
||||||
created := false
|
assert.Check(t, is.Equal(svr.mock.creates, 1))
|
||||||
updated := false
|
assert.Check(t, is.Equal(svr.mock.updates, 0))
|
||||||
// The pod doesn't exist, we should invoke the CreatePod() method of the provider
|
|
||||||
svr.mock.createFn = func() {
|
|
||||||
created = true
|
|
||||||
}
|
|
||||||
svr.mock.updateFn = func() {
|
|
||||||
updated = true
|
|
||||||
}
|
|
||||||
|
|
||||||
pod2 := &corev1.Pod{}
|
pod2 := &corev1.Pod{}
|
||||||
pod2.ObjectMeta.Namespace = "default"
|
pod2.ObjectMeta.Namespace = "default"
|
||||||
@@ -239,12 +246,12 @@ func TestPodUpdateExisting(t *testing.T) {
|
|||||||
assert.Check(t, is.Nil(err))
|
assert.Check(t, is.Nil(err))
|
||||||
|
|
||||||
// createOrUpdate didn't call CreatePod but did call UpdatePod because the spec changed
|
// createOrUpdate didn't call CreatePod but did call UpdatePod because the spec changed
|
||||||
assert.Check(t, !created)
|
assert.Check(t, is.Equal(svr.mock.creates, 1))
|
||||||
assert.Check(t, updated)
|
assert.Check(t, is.Equal(svr.mock.updates, 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPodNoSpecChange(t *testing.T) {
|
func TestPodNoSpecChange(t *testing.T) {
|
||||||
svr := newTestServer(t)
|
svr := newTestServer()
|
||||||
|
|
||||||
pod := &corev1.Pod{}
|
pod := &corev1.Pod{}
|
||||||
pod.ObjectMeta.Namespace = "default"
|
pod.ObjectMeta.Namespace = "default"
|
||||||
@@ -264,23 +271,16 @@ func TestPodNoSpecChange(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err := svr.mock.MockProvider.CreatePod(context.Background(), pod)
|
err := svr.mock.CreatePod(context.Background(), pod)
|
||||||
assert.Check(t, is.Nil(err))
|
assert.Check(t, is.Nil(err))
|
||||||
created := false
|
assert.Check(t, is.Equal(svr.mock.creates, 1))
|
||||||
updated := false
|
assert.Check(t, is.Equal(svr.mock.updates, 0))
|
||||||
// The pod doesn't exist, we should invoke the CreatePod() method of the provider
|
|
||||||
svr.mock.createFn = func() {
|
|
||||||
created = true
|
|
||||||
}
|
|
||||||
svr.mock.updateFn = func() {
|
|
||||||
updated = true
|
|
||||||
}
|
|
||||||
|
|
||||||
er := testutil.FakeEventRecorder(5)
|
er := testutil.FakeEventRecorder(5)
|
||||||
err = svr.createOrUpdatePod(context.Background(), pod, er)
|
err = svr.createOrUpdatePod(context.Background(), pod, er)
|
||||||
assert.Check(t, is.Nil(err))
|
assert.Check(t, is.Nil(err))
|
||||||
|
|
||||||
// createOrUpdate didn't call CreatePod or UpdatePod, spec didn't change
|
// createOrUpdate didn't call CreatePod or UpdatePod, spec didn't change
|
||||||
assert.Check(t, !created)
|
assert.Check(t, is.Equal(svr.mock.creates, 1))
|
||||||
assert.Check(t, !updated)
|
assert.Check(t, is.Equal(svr.mock.updates, 0))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user