containerized-data-importer/tests/leaderelection_test.go

138 lines
3.9 KiB
Go

package tests_test
import (
"regexp"
"time"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"kubevirt.io/containerized-data-importer/tests"
"kubevirt.io/containerized-data-importer/tests/framework"
)
const (
cdiDeploymentName = "cdi-deployment"
newDeploymentName = "cdi-deployment-new"
pollingInterval = 2 * time.Second
timeout = 90 * time.Second
)
var (
logCheckLeaderRegEx = regexp.MustCompile("Attempting to acquire leader lease")
logIsLeaderRegex = regexp.MustCompile("Successfully acquired leadership lease")
)
func checkLogForRegEx(regEx *regexp.Regexp, log string) bool {
matches := regEx.FindAllStringIndex(log, -1)
return len(matches) == 1
}
var _ = Describe("[rfe_id:1250][crit:high][vendor:cnv-qe@redhat.com][level:component]Leader election tests", func() {
f := framework.NewFrameworkOrDie("leaderelection-test")
getDeployments := func() *appsv1.DeploymentList {
deployments, err := f.K8sClient.AppsV1().Deployments(f.CdiInstallNs).List(metav1.ListOptions{LabelSelector: "app=containerized-data-importer"})
Expect(err).ToNot(HaveOccurred())
return deployments
}
getPods := func() *v1.PodList {
pods, err := f.K8sClient.CoreV1().Pods(f.CdiInstallNs).List(metav1.ListOptions{LabelSelector: "app=containerized-data-importer"})
Expect(err).ToNot(HaveOccurred())
return pods
}
getLog := func(name string) string {
log, err := tests.RunKubectlCommand(f, "logs", name, "-n", f.CdiInstallNs)
Expect(err).ToNot(HaveOccurred())
return log
}
AfterEach(func() {
deployments := getDeployments()
if len(deployments.Items) > 1 {
d := &appsv1.Deployment{}
d.Name = newDeploymentName
err := f.K8sClient.AppsV1().Deployments(f.CdiInstallNs).Delete(newDeploymentName, &metav1.DeleteOptions{})
Expect(err).ToNot(HaveOccurred())
Eventually(func() []appsv1.Deployment {
return getDeployments().Items
}, timeout, pollingInterval).Should(HaveLen(1))
}
})
It("[test_id:1365]Should only ever be one controller as leader", func() {
By("Check only one CDI controller deployment/pod")
deployments := getDeployments()
Expect(deployments.Items).Should(HaveLen(1))
pods := getPods()
Expect(pods.Items).Should(HaveLen(1))
leaderPodName := pods.Items[0].Name
log := getLog(leaderPodName)
Expect(checkLogForRegEx(logIsLeaderRegex, log)).To(BeTrue())
newDeployment := deployments.Items[0].DeepCopy()
newDeployment.ObjectMeta = metav1.ObjectMeta{Name: newDeploymentName}
newDeployment.Status = appsv1.DeploymentStatus{}
By("Creating new controller deployment")
newDeployment, err := f.K8sClient.AppsV1().Deployments(f.CdiInstallNs).Create(newDeployment)
Expect(err).ToNot(HaveOccurred())
var newPodName string
Eventually(func() bool {
pods := getPods()
if len(pods.Items) != 2 {
return false
}
for _, pod := range pods.Items {
if pod.Status.Phase != "Running" {
return false
}
if pod.Name != leaderPodName {
newPodName = pod.Name
}
}
return true
}, timeout, pollingInterval).Should(BeTrue())
Expect(newPodName).ShouldNot(BeEmpty())
By("Check that new pod is attempting to become leader")
Eventually(func() bool {
log := getLog(newPodName)
return checkLogForRegEx(logCheckLeaderRegEx, log)
}, timeout, pollingInterval).Should(BeTrue())
// have to prove new pod won't become leader in period longer than lease duration
time.Sleep(20 * time.Second)
By("Confirm pod did not become leader")
log = getLog(newPodName)
Expect(checkLogForRegEx(logIsLeaderRegex, log)).To(BeFalse())
By("Delete new deployment")
err = f.K8sClient.AppsV1().Deployments(f.CdiInstallNs).Delete(newDeploymentName, &metav1.DeleteOptions{})
Expect(err).ToNot(HaveOccurred())
By("Confirm deployment deleted")
Eventually(func() bool {
deployments := getDeployments()
return len(deployments.Items) == 1
}, timeout, pollingInterval).Should(BeTrue())
})
})