containerized-data-importer/tests/operator_test.go
Michael Henriksen 99c95f2ddf
skip CDI CR delete tests when expected name does not exist (#1131)
Signed-off-by: Michael Henriksen <mhenriks@redhat.com>
2020-03-07 01:49:11 +01:00

210 lines
7.1 KiB
Go

package tests_test
import (
"fmt"
"time"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
routev1 "github.com/openshift/api/route/v1"
routeclient "github.com/openshift/client-go/route/clientset/versioned"
secclient "github.com/openshift/client-go/security/clientset/versioned"
conditions "github.com/openshift/custom-resource-status/conditions/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
cdiv1alpha1 "kubevirt.io/containerized-data-importer/pkg/apis/core/v1alpha1"
"kubevirt.io/containerized-data-importer/pkg/controller"
"kubevirt.io/containerized-data-importer/pkg/operator"
operatorcontroller "kubevirt.io/containerized-data-importer/pkg/operator/controller"
"kubevirt.io/containerized-data-importer/tests/framework"
"kubevirt.io/containerized-data-importer/tests/utils"
)
var _ = Describe("Operator tests", func() {
f := framework.NewFrameworkOrDie("operator-test")
It("should create a route in OpenShift", func() {
if !controller.IsOpenshift(f.K8sClient) {
Skip("This test is OpenShift specific")
}
routeClient, err := routeclient.NewForConfig(f.RestConfig)
Expect(err).ToNot(HaveOccurred())
r, err := routeClient.RouteV1().Routes(f.CdiInstallNs).Get("cdi-uploadproxy", metav1.GetOptions{})
Expect(err).ToNot(HaveOccurred())
Expect(r.Spec.TLS.Termination).To(Equal(routev1.TLSTerminationReencrypt))
})
It("add cdi-sa to anyuid scc", func() {
if !controller.IsOpenshift(f.K8sClient) {
Skip("This test is OpenShift specific")
}
secClient, err := secclient.NewForConfig(f.RestConfig)
Expect(err).ToNot(HaveOccurred())
scc, err := secClient.SecurityV1().SecurityContextConstraints().Get("anyuid", metav1.GetOptions{})
Expect(err).ToNot(HaveOccurred())
cdiSA := fmt.Sprintf("system:serviceaccount:%s:cdi-sa", f.CdiInstallNs)
Expect(scc.Users).Should(ContainElement(cdiSA))
})
// Condition flags can be found here with their meaning https://github.com/kubevirt/hyperconverged-cluster-operator/blob/master/docs/conditions.md
It("Condition flags on CR should be healthy and operating", func() {
cdiObjects, err := f.CdiClient.CdiV1alpha1().CDIs().List(metav1.ListOptions{})
Expect(err).ToNot(HaveOccurred())
Expect(len(cdiObjects.Items)).To(Equal(1))
cdiObject := cdiObjects.Items[0]
conditionMap := operatorcontroller.GetConditionValues(cdiObject.Status.Conditions)
// Application should be fully operational and healthy.
Expect(conditionMap[conditions.ConditionAvailable]).To(Equal(corev1.ConditionTrue))
Expect(conditionMap[conditions.ConditionProgressing]).To(Equal(corev1.ConditionFalse))
Expect(conditionMap[conditions.ConditionDegraded]).To(Equal(corev1.ConditionFalse))
})
})
var _ = Describe("Operator delete CDI tests", func() {
var cr *cdiv1alpha1.CDI
f := framework.NewFrameworkOrDie("operator-delete-cdi-test")
BeforeEach(func() {
var err error
cr, err = f.CdiClient.CdiV1alpha1().CDIs().Get("cdi", metav1.GetOptions{})
if errors.IsNotFound(err) {
Skip("CDI CR 'cdi' does not exist. Probably managed by another operator so skipping.")
}
Expect(err).ToNot(HaveOccurred())
})
AfterEach(func() {
if cr == nil {
return
}
cdi, err := f.CdiClient.CdiV1alpha1().CDIs().Get(cr.Name, metav1.GetOptions{})
if err == nil {
if cdi.DeletionTimestamp == nil {
cdi.Spec = cr.Spec
_, err = f.CdiClient.CdiV1alpha1().CDIs().Update(cdi)
Expect(err).ToNot(HaveOccurred())
return
}
Eventually(func() bool {
_, err = f.CdiClient.CdiV1alpha1().CDIs().Get(cr.Name, metav1.GetOptions{})
if errors.IsNotFound(err) {
return true
}
Expect(err).ToNot(HaveOccurred())
return false
}, 5*time.Minute, 2*time.Second).Should(BeTrue())
} else {
Expect(errors.IsNotFound(err)).To(BeTrue())
}
Eventually(func() bool {
_, err = f.K8sClient.CoreV1().ConfigMaps(f.CdiInstallNs).Get(operator.ConfigMapName, metav1.GetOptions{})
if errors.IsNotFound(err) {
return true
}
Expect(err).ToNot(HaveOccurred())
return false
}, 5*time.Minute, 2*time.Second).Should(BeTrue())
cdi = &cdiv1alpha1.CDI{
ObjectMeta: metav1.ObjectMeta{
Name: "cdi",
},
Spec: cr.Spec,
}
cdi, err = f.CdiClient.CdiV1alpha1().CDIs().Create(cdi)
Expect(err).ToNot(HaveOccurred())
Eventually(func() bool {
cdi, err = f.CdiClient.CdiV1alpha1().CDIs().Get(cr.Name, metav1.GetOptions{})
Expect(err).ToNot(HaveOccurred())
for _, c := range cdi.Status.Conditions {
if c.Type == conditions.ConditionAvailable && c.Status == corev1.ConditionTrue {
return true
}
}
return false
}, 10*time.Minute, 2*time.Second).Should(BeTrue())
})
It("should delete an upload pod", func() {
dv := utils.NewDataVolumeForUpload("delete-me", "1Gi")
By("Creating datavolume")
dv, err := utils.CreateDataVolumeFromDefinition(f.CdiClient, f.Namespace.Name, dv)
Expect(err).ToNot(HaveOccurred())
By("Waiting for pod to be running")
Eventually(func() bool {
pod, err := f.K8sClient.CoreV1().Pods(dv.Namespace).Get("cdi-upload-"+dv.Name, metav1.GetOptions{})
if errors.IsNotFound(err) {
return false
}
Expect(err).ToNot(HaveOccurred())
return pod.Status.Phase == corev1.PodRunning
}, 2*time.Minute, 1*time.Second).Should(BeTrue())
By("Deleting CDI")
err = f.CdiClient.CdiV1alpha1().CDIs().Delete(cr.Name, &metav1.DeleteOptions{})
Expect(err).ToNot(HaveOccurred())
By("Waiting for pod to be deleted")
Eventually(func() bool {
_, err = f.K8sClient.CoreV1().Pods(dv.Namespace).Get("cdi-upload-"+dv.Name, metav1.GetOptions{})
if errors.IsNotFound(err) {
return true
}
Expect(err).ToNot(HaveOccurred())
return false
}, 2*time.Minute, 1*time.Second).Should(BeTrue())
})
It("should block CDI delete", func() {
uninstallStrategy := cdiv1alpha1.CDIUninstallStrategyBlockUninstallIfWorkloadsExist
By("Getting CDI resource")
cdi, err := f.CdiClient.CdiV1alpha1().CDIs().Get(cr.Name, metav1.GetOptions{})
Expect(err).ToNot(HaveOccurred())
cdi.Spec.UninstallStrategy = &uninstallStrategy
_, err = f.CdiClient.CdiV1alpha1().CDIs().Update(cdi)
Expect(err).ToNot(HaveOccurred())
By("Waiting for update")
Eventually(func() bool {
cdi, err = f.CdiClient.CdiV1alpha1().CDIs().Get(cr.Name, metav1.GetOptions{})
Expect(err).ToNot(HaveOccurred())
return cdi.Spec.UninstallStrategy != nil && *cdi.Spec.UninstallStrategy == uninstallStrategy
}, 2*time.Minute, 1*time.Second).Should(BeTrue())
By("Creating datavolume")
dv := utils.NewDataVolumeForUpload("delete-me", "1Gi")
dv, err = utils.CreateDataVolumeFromDefinition(f.CdiClient, f.Namespace.Name, dv)
Expect(err).ToNot(HaveOccurred())
By("Cannot delete CDI")
err = f.CdiClient.CdiV1alpha1().CDIs().Delete(cr.Name, &metav1.DeleteOptions{DryRun: []string{"All"}})
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("there are still DataVolumes present"))
err = f.CdiClient.CdiV1alpha1().DataVolumes(f.Namespace.Name).Delete(dv.Name, &metav1.DeleteOptions{})
Expect(err).ToNot(HaveOccurred())
By("Can delete CDI")
err = f.CdiClient.CdiV1alpha1().CDIs().Delete(cr.Name, &metav1.DeleteOptions{DryRun: []string{"All"}})
Expect(err).ToNot(HaveOccurred())
})
})