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:
Brian Goff
2019-05-20 11:20:28 -07:00
parent d183dbbe17
commit 2c5952587a

View File

@@ -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))
} }