containerized-data-importer/pkg/controller/controller_test.go
2018-03-19 17:41:42 -05:00

144 lines
4.0 KiB
Go

package controller_test
import (
"fmt"
. "github.com/kubevirt/containerized-data-importer/pkg/controller"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes/fake"
"k8s.io/client-go/tools/cache"
k8stesting "k8s.io/client-go/tools/cache/testing"
"k8s.io/client-go/util/workqueue"
)
type operation int
const (
opAdd operation = iota
opUpdate
opDelete
)
var _ = Describe("Controller", func() {
var stop chan struct{}
var controller *Controller
var fakeClient *fake.Clientset
type testT struct {
descr string
pvcName string
annEndpoint string
op operation
expectPodName string
errMessage string
}
setUpInformer := func(obj *v1.PersistentVolumeClaim, op operation, pvcName string) {
stop = make(chan struct{})
fakeClient = fake.NewSimpleClientset()
importerTag := "test"
objSource := k8stesting.NewFakeControllerSource()
pvcInformer := cache.NewSharedIndexInformer(objSource, obj, 0, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc})
queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter())
pvcListWatcher := k8stesting.NewFakeControllerSource()
controller = NewController(fakeClient, queue, pvcInformer, pvcListWatcher, importerTag)
if op == opAdd {
pvcListWatcher.Add(obj)
objSource.Add(obj)
queue.Add(pvcName)
}
go pvcInformer.Run(stop)
Expect(cache.WaitForCacheSync(stop, pvcInformer.HasSynced)).To(BeTrue())
}
Context("Test Contoller create pods will success if", func() {
tests := []testT{
{
descr: "it has an annEndpoint",
pvcName: "test",
annEndpoint: "http://www.google.com",
op: opAdd,
expectPodName: "importer-test",
},
}
for _, test := range tests {
BeforeEach(func() {
pvcObj := &v1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: test.pvcName,
Annotations: map[string]string{AnnEndpoint: test.annEndpoint},
},
}
setUpInformer(pvcObj, test.op, test.pvcName)
})
AfterEach(func() {
close(stop)
})
It(test.descr, func() {
Expect(controller.ProcessNextItem()).To(BeTrue())
pod, err := getTestPod(fakeClient, test.expectPodName)
Expect(err).To(BeNil(), fmt.Sprintf("Expected nil err, got: %v", err))
Expect(pod).NotTo(BeNil(), fmt.Sprintf("Expected Pod %q was not found.", test.expectPodName))
Expect(pod.GenerateName).To(ContainSubstring(test.expectPodName))
})
}
})
Context("Test Contoller create pods will failed if", func() {
tests := []testT{
{
descr: "it does not have an annEndpoint",
pvcName: "test",
annEndpoint: "",
op: opAdd,
expectPodName: "",
errMessage: "pods \"\" not found",
},
}
for _, test := range tests {
BeforeEach(func() {
pvcObj := &v1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: test.pvcName,
Annotations: map[string]string{AnnEndpoint: test.annEndpoint},
},
}
setUpInformer(pvcObj, test.op, test.pvcName)
})
AfterEach(func() {
close(stop)
})
It(test.descr, func() {
Expect(controller.ProcessNextItem()).To(BeTrue())
_, err := fakeClient.CoreV1().Pods("").Get(test.expectPodName, metav1.GetOptions{})
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(Equal(test.errMessage))
})
}
})
})
// getTestPod is used to handle pods with generated name by comparing the passed in pod name to a list of pods
// If a match is found, the pod is returned.
// If no match is found, a nil pointer is returned. This should be checked by the caller.
func getTestPod(fc *fake.Clientset, podName string) (*v1.Pod, error) {
podList, err := fc.CoreV1().Pods("").List(metav1.ListOptions{})
if err != nil {
return nil, err
}
var pod *v1.Pod
for i, p := range podList.Items {
if p.GenerateName == podName {
pod = &podList.Items[i]
}
}
return pod, nil
}