e2e: enhance tests that check for pod staying pending

Using WaitTimeoutForPodRunningInNamespace followed by ExpectError was not very
precise (any error passed the check, not just the expected timeout) and
hard to read. Now the test's expectation is spelled out explicitly: the pod
must stay in pending.
This commit is contained in:
Patrick Ohly 2022-10-24 17:26:07 +02:00
parent 6b5f77b163
commit 6af5bf0585
6 changed files with 41 additions and 29 deletions

View File

@ -29,6 +29,7 @@ import (
admissionapi "k8s.io/pod-security-admission/api"
"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
)
// These tests exercise the Kubernetes expansion syntax $(VAR).
@ -267,8 +268,8 @@ var _ = SIGDescribe("Variable Expansion", func() {
podClient := e2epod.NewPodClient(f)
pod = podClient.Create(ctx, pod)
err := e2epod.WaitTimeoutForPodRunningInNamespace(ctx, f.ClientSet, pod.Name, pod.Namespace, framework.PodStartShortTimeout)
framework.ExpectError(err, "while waiting for pod to be running")
getPod := e2epod.Get(f.ClientSet, pod)
gomega.Consistently(ctx, getPod).WithTimeout(framework.PodStartShortTimeout).Should(e2epod.BeInPhase(v1.PodPending))
ginkgo.By("updating the pod")
podClient.Update(ctx, pod.ObjectMeta.Name, func(pod *v1.Pod) {
@ -279,7 +280,7 @@ var _ = SIGDescribe("Variable Expansion", func() {
})
ginkgo.By("waiting for pod running")
err = e2epod.WaitTimeoutForPodRunningInNamespace(ctx, f.ClientSet, pod.Name, pod.Namespace, framework.PodStartShortTimeout)
err := e2epod.WaitTimeoutForPodRunningInNamespace(ctx, f.ClientSet, pod.Name, pod.Namespace, framework.PodStartShortTimeout)
framework.ExpectNoError(err, "while waiting for pod to be running")
ginkgo.By("deleting the pod gracefully")

View File

@ -556,8 +556,9 @@ var _ = SIGDescribe("ConfigMap", func() {
// Slow (~5 mins)
ginkgo.It("Should fail non-optional pod creation due to configMap object does not exist [Slow]", func(ctx context.Context) {
volumeMountPath := "/etc/configmap-volumes"
pod, err := createNonOptionalConfigMapPod(ctx, f, volumeMountPath)
framework.ExpectError(err, "created pod %q with non-optional configMap in namespace %q", pod.Name, f.Namespace.Name)
pod := createNonOptionalConfigMapPod(ctx, f, volumeMountPath)
getPod := e2epod.Get(f.ClientSet, pod)
gomega.Consistently(ctx, getPod).WithTimeout(f.Timeouts.PodStart).Should(e2epod.BeInPhase(v1.PodPending))
})
// ConfigMap object defined for the pod, If a key is specified which is not present in the ConfigMap,
@ -565,8 +566,9 @@ var _ = SIGDescribe("ConfigMap", func() {
// Slow (~5 mins)
ginkgo.It("Should fail non-optional pod creation due to the key in the configMap object does not exist [Slow]", func(ctx context.Context) {
volumeMountPath := "/etc/configmap-volumes"
pod, err := createNonOptionalConfigMapPodWithConfig(ctx, f, volumeMountPath)
framework.ExpectError(err, "created pod %q with non-optional configMap in namespace %q", pod.Name, f.Namespace.Name)
pod := createNonOptionalConfigMapPodWithConfig(ctx, f, volumeMountPath)
getPod := e2epod.Get(f.ClientSet, pod)
gomega.Consistently(ctx, getPod).WithTimeout(f.Timeouts.PodStart).Should(e2epod.BeInPhase(v1.PodPending))
})
})
@ -677,7 +679,7 @@ func doConfigMapE2EWithMappings(ctx context.Context, f *framework.Framework, asU
e2epodoutput.TestContainerOutputRegexp(ctx, f, "consume configMaps", pod, 0, output)
}
func createNonOptionalConfigMapPod(ctx context.Context, f *framework.Framework, volumeMountPath string) (*v1.Pod, error) {
func createNonOptionalConfigMapPod(ctx context.Context, f *framework.Framework, volumeMountPath string) *v1.Pod {
podLogTimeout := e2epod.GetPodSecretUpdateTimeout(ctx, f.ClientSet)
containerTimeoutArg := fmt.Sprintf("--retry_time=%v", int(podLogTimeout.Seconds()))
falseValue := false
@ -692,10 +694,10 @@ func createNonOptionalConfigMapPod(ctx context.Context, f *framework.Framework,
ginkgo.By("Creating the pod")
pod = e2epod.NewPodClient(f).Create(ctx, pod)
return pod, e2epod.WaitForPodNameRunningInNamespace(ctx, f.ClientSet, pod.Name, f.Namespace.Name)
return pod
}
func createNonOptionalConfigMapPodWithConfig(ctx context.Context, f *framework.Framework, volumeMountPath string) (*v1.Pod, error) {
func createNonOptionalConfigMapPodWithConfig(ctx context.Context, f *framework.Framework, volumeMountPath string) *v1.Pod {
podLogTimeout := e2epod.GetPodSecretUpdateTimeout(ctx, f.ClientSet)
containerTimeoutArg := fmt.Sprintf("--retry_time=%v", int(podLogTimeout.Seconds()))
falseValue := false
@ -722,7 +724,7 @@ func createNonOptionalConfigMapPodWithConfig(ctx context.Context, f *framework.F
ginkgo.By("Creating the pod")
pod = e2epod.NewPodClient(f).Create(ctx, pod)
return pod, e2epod.WaitForPodNameRunningInNamespace(ctx, f.ClientSet, pod.Name, f.Namespace.Name)
return pod
}
func createConfigMapVolumeMounttestPod(namespace, volumeName, referenceName, mountPath string, mounttestArgs ...string) *v1.Pod {

View File

@ -462,8 +462,9 @@ var _ = SIGDescribe("Projected configMap", func() {
//Slow (~5 mins)
ginkgo.It("Should fail non-optional pod creation due to configMap object does not exist [Slow]", func(ctx context.Context) {
volumeMountPath := "/etc/projected-configmap-volumes"
pod, err := createNonOptionalConfigMapPod(ctx, f, volumeMountPath)
framework.ExpectError(err, "created pod %q with non-optional configMap in namespace %q", pod.Name, f.Namespace.Name)
pod := createNonOptionalConfigMapPod(ctx, f, volumeMountPath)
getPod := e2epod.Get(f.ClientSet, pod)
gomega.Consistently(ctx, getPod).WithTimeout(f.Timeouts.PodStart).Should(e2epod.BeInPhase(v1.PodPending))
})
//ConfigMap object defined for the pod, If a key is specified which is not present in the ConfigMap,
@ -471,8 +472,9 @@ var _ = SIGDescribe("Projected configMap", func() {
//Slow (~5 mins)
ginkgo.It("Should fail non-optional pod creation due to the key in the configMap object does not exist [Slow]", func(ctx context.Context) {
volumeMountPath := "/etc/configmap-volumes"
pod, err := createNonOptionalConfigMapPodWithConfig(ctx, f, volumeMountPath)
framework.ExpectError(err, "created pod %q with non-optional configMap in namespace %q", pod.Name, f.Namespace.Name)
pod := createNonOptionalConfigMapPodWithConfig(ctx, f, volumeMountPath)
getPod := e2epod.Get(f.ClientSet, pod)
gomega.Consistently(ctx, getPod).WithTimeout(f.Timeouts.PodStart).Should(e2epod.BeInPhase(v1.PodPending))
})
})

View File

@ -414,8 +414,9 @@ var _ = SIGDescribe("Projected secret", func() {
ginkgo.It("Should fail non-optional pod creation due to secret object does not exist [Slow]", func(ctx context.Context) {
volumeMountPath := "/etc/projected-secret-volumes"
podName := "pod-secrets-" + string(uuid.NewUUID())
err := createNonOptionalSecretPod(ctx, f, volumeMountPath, podName)
framework.ExpectError(err, "created pod %q with non-optional secret in namespace %q", podName, f.Namespace.Name)
pod := createNonOptionalSecretPod(ctx, f, volumeMountPath, podName)
getPod := e2epod.Get(f.ClientSet, pod)
gomega.Consistently(ctx, getPod).WithTimeout(f.Timeouts.PodStart).Should(e2epod.BeInPhase(v1.PodPending))
})
//Secret object defined for the pod, If a key is specified which is not present in the secret,
@ -424,8 +425,9 @@ var _ = SIGDescribe("Projected secret", func() {
ginkgo.It("Should fail non-optional pod creation due to the key in the secret object does not exist [Slow]", func(ctx context.Context) {
volumeMountPath := "/etc/secret-volumes"
podName := "pod-secrets-" + string(uuid.NewUUID())
err := createNonOptionalSecretPodWithSecret(ctx, f, volumeMountPath, podName)
framework.ExpectError(err, "created pod %q with non-optional secret in namespace %q", podName, f.Namespace.Name)
pod := createNonOptionalSecretPodWithSecret(ctx, f, volumeMountPath, podName)
getPod := e2epod.Get(f.ClientSet, pod)
gomega.Consistently(ctx, getPod).WithTimeout(f.Timeouts.PodStart).Should(e2epod.BeInPhase(v1.PodPending))
})
})

View File

@ -439,8 +439,9 @@ var _ = SIGDescribe("Secrets", func() {
ginkgo.It("Should fail non-optional pod creation due to secret object does not exist [Slow]", func(ctx context.Context) {
volumeMountPath := "/etc/secret-volumes"
podName := "pod-secrets-" + string(uuid.NewUUID())
err := createNonOptionalSecretPod(ctx, f, volumeMountPath, podName)
framework.ExpectError(err, "created pod %q with non-optional secret in namespace %q", podName, f.Namespace.Name)
pod := createNonOptionalSecretPod(ctx, f, volumeMountPath, podName)
getPod := e2epod.Get(f.ClientSet, pod)
gomega.Consistently(ctx, getPod).WithTimeout(f.Timeouts.PodStart).Should(e2epod.BeInPhase(v1.PodPending))
})
// Secret object defined for the pod, If a key is specified which is not present in the secret,
@ -449,8 +450,9 @@ var _ = SIGDescribe("Secrets", func() {
ginkgo.It("Should fail non-optional pod creation due to the key in the secret object does not exist [Slow]", func(ctx context.Context) {
volumeMountPath := "/etc/secret-volumes"
podName := "pod-secrets-" + string(uuid.NewUUID())
err := createNonOptionalSecretPodWithSecret(ctx, f, volumeMountPath, podName)
framework.ExpectError(err, "created pod %q with non-optional secret in namespace %q", podName, f.Namespace.Name)
pod := createNonOptionalSecretPodWithSecret(ctx, f, volumeMountPath, podName)
getPod := e2epod.Get(f.ClientSet, pod)
gomega.Consistently(ctx, getPod).WithTimeout(f.Timeouts.PodStart).Should(e2epod.BeInPhase(v1.PodPending))
})
})
@ -606,7 +608,7 @@ func doSecretE2EWithMapping(ctx context.Context, f *framework.Framework, mode *i
e2epodoutput.TestContainerOutputRegexp(ctx, f, "consume secrets", pod, 0, expectedOutput)
}
func createNonOptionalSecretPod(ctx context.Context, f *framework.Framework, volumeMountPath, podName string) error {
func createNonOptionalSecretPod(ctx context.Context, f *framework.Framework, volumeMountPath, podName string) *v1.Pod {
podLogTimeout := e2epod.GetPodSecretUpdateTimeout(ctx, f.ClientSet)
containerTimeoutArg := fmt.Sprintf("--retry_time=%v", int(podLogTimeout.Seconds()))
falseValue := false
@ -651,10 +653,10 @@ func createNonOptionalSecretPod(ctx context.Context, f *framework.Framework, vol
}
ginkgo.By("Creating the pod")
pod = e2epod.NewPodClient(f).Create(ctx, pod)
return e2epod.WaitForPodNameRunningInNamespace(ctx, f.ClientSet, pod.Name, f.Namespace.Name)
return pod
}
func createNonOptionalSecretPodWithSecret(ctx context.Context, f *framework.Framework, volumeMountPath, podName string) error {
func createNonOptionalSecretPodWithSecret(ctx context.Context, f *framework.Framework, volumeMountPath, podName string) *v1.Pod {
podLogTimeout := e2epod.GetPodSecretUpdateTimeout(ctx, f.ClientSet)
containerTimeoutArg := fmt.Sprintf("--retry_time=%v", int(podLogTimeout.Seconds()))
falseValue := false
@ -712,5 +714,5 @@ func createNonOptionalSecretPodWithSecret(ctx context.Context, f *framework.Fram
}
ginkgo.By("Creating the pod")
pod = e2epod.NewPodClient(f).Create(ctx, pod)
return e2epod.WaitForPodNameRunningInNamespace(ctx, f.ClientSet, pod.Name, f.Namespace.Name)
return pod
}

View File

@ -22,6 +22,8 @@ import (
"time"
"github.com/onsi/ginkgo/v2"
"github.com/onsi/gomega"
v1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
@ -128,8 +130,9 @@ var _ = utils.SIGDescribe("CSI Mock volume attach", func() {
err = e2eevents.WaitTimeoutForEvent(ctx, m.cs, pod.Namespace, eventSelector, msg, f.Timeouts.PodStart)
if err != nil {
podErr := e2epod.WaitTimeoutForPodRunningInNamespace(ctx, m.cs, pod.Name, pod.Namespace, 10*time.Second)
framework.ExpectError(podErr, "Pod should not be in running status because attaching should failed")
getPod := e2epod.Get(m.cs, pod)
gomega.Consistently(ctx, getPod).WithTimeout(10*time.Second).Should(e2epod.BeInPhase(v1.PodPending),
"Pod should not be in running status because attaching should failed")
// Events are unreliable, don't depend on the event. It's used only to speed up the test.
framework.Logf("Attach should fail and the corresponding event should show up, error: %v", err)
}