From 8c142a83635538f37a5b58b9c324ed528d9ebb9c Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Thu, 29 Sep 2022 12:04:03 +0530 Subject: [PATCH 1/3] add e2e test for keystone containers Signed-off-by: Akhil Mohan --- test/e2e/common/node/keystone_containers.go | 84 +++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 test/e2e/common/node/keystone_containers.go diff --git a/test/e2e/common/node/keystone_containers.go b/test/e2e/common/node/keystone_containers.go new file mode 100644 index 0000000000000..a72a3ff74baea --- /dev/null +++ b/test/e2e/common/node/keystone_containers.go @@ -0,0 +1,84 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package node + +import ( + "context" + + batchv1 "k8s.io/api/batch/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/kubernetes/test/e2e/framework" + imageutils "k8s.io/kubernetes/test/utils/image" + + "github.com/onsi/ginkgo/v2" + "github.com/onsi/gomega" +) + +var _ = SIGDescribe("Keystone Containers [Feature:KeystoneContainers]", func() { + f := framework.NewDefaultFramework("keystone-container-test") + + ginkgo.Context("When creating a job with two containers", func() { + + ginkgo.It("should complete the job once the keystone container exits successfully", func() { + jobClient := f.ClientSet.BatchV1().Jobs(f.Namespace.Name) + job := &batchv1.Job{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-job", + }, + Spec: batchv1.JobSpec{ + Template: v1.PodTemplateSpec{ + Spec: v1.PodSpec{ + RestartPolicy: v1.RestartPolicyOnFailure, + Containers: []v1.Container{ + // the main container should exit before the sidecar with 0 exit code + { + Name: "main-container", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"sh", "-c", "sleep 1 && exit 0"}, + }, + { + Name: "sidecar-container", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"sh", "-c", "sleep infinity"}, + }, + }, + }, + }, + }, + } + + j, err := jobClient.Create(context.TODO(), job, metav1.CreateOptions{}) + framework.ExpectNoError(err, "error while creating the job") + + // it is expected that the pod succeeds and the job should have a completed + // status eventually even if the sidecar container has not terminated in the pod + gomega.Eventually(func() bool { + j, err = jobClient.Get(context.TODO(), j.Name, metav1.GetOptions{}) + framework.ExpectNoError(err, "error while getting job") + for _, c := range j.Status.Conditions { + if c.Type == batchv1.JobComplete && c.Status == v1.ConditionTrue { + return true + } + } + return false + }).Should(gomega.BeTrue()) + + }) + + }) +}) From 0ad4bf0b8e25d03cc94cb76410e8402ae93dbc06 Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Tue, 11 Oct 2022 12:04:23 +0530 Subject: [PATCH 2/3] use pods instead of job Signed-off-by: Akhil Mohan --- test/e2e/common/node/keystone_containers.go | 75 ++++++++++----------- 1 file changed, 34 insertions(+), 41 deletions(-) diff --git a/test/e2e/common/node/keystone_containers.go b/test/e2e/common/node/keystone_containers.go index a72a3ff74baea..36727c2eabd84 100644 --- a/test/e2e/common/node/keystone_containers.go +++ b/test/e2e/common/node/keystone_containers.go @@ -17,66 +17,59 @@ limitations under the License. package node import ( - "context" - - batchv1 "k8s.io/api/batch/v1" + "fmt" + "github.com/onsi/ginkgo/v2" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/uuid" "k8s.io/kubernetes/test/e2e/framework" imageutils "k8s.io/kubernetes/test/utils/image" - - "github.com/onsi/ginkgo/v2" - "github.com/onsi/gomega" + admissionapi "k8s.io/pod-security-admission/api" ) var _ = SIGDescribe("Keystone Containers [Feature:KeystoneContainers]", func() { f := framework.NewDefaultFramework("keystone-container-test") + f.NamespacePodSecurityEnforceLevel = admissionapi.LevelPrivileged + var podClient *framework.PodClient + ginkgo.BeforeEach(func() { + podClient = f.PodClient() + }) - ginkgo.Context("When creating a job with two containers", func() { + ginkgo.Context("When creating a pod with two containers", func() { - ginkgo.It("should complete the job once the keystone container exits successfully", func() { - jobClient := f.ClientSet.BatchV1().Jobs(f.Namespace.Name) - job := &batchv1.Job{ + ginkgo.It("should delete the pod once the keystone container exits successfully [Keystone]", func() { + keystone := "Keystone" + podName := fmt.Sprintf("keystone-test-pod-%s", uuid.NewUUID()) + pod := &v1.Pod{ ObjectMeta: metav1.ObjectMeta{ - Name: "test-job", + Name: podName, }, - Spec: batchv1.JobSpec{ - Template: v1.PodTemplateSpec{ - Spec: v1.PodSpec{ - RestartPolicy: v1.RestartPolicyOnFailure, - Containers: []v1.Container{ - // the main container should exit before the sidecar with 0 exit code - { - Name: "main-container", - Image: imageutils.GetE2EImage(imageutils.BusyBox), - Command: []string{"sh", "-c", "sleep 1 && exit 0"}, - }, - { - Name: "sidecar-container", - Image: imageutils.GetE2EImage(imageutils.BusyBox), - Command: []string{"sh", "-c", "sleep infinity"}, - }, + Spec: v1.PodSpec{ + RestartPolicy: v1.RestartPolicyOnFailure, + Containers: []v1.Container{ + // the main container should exit before the sidecar with 0 exit code + { + Name: "main-container", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"sh", "-c", "sleep 10 && exit 0"}, + Lifecycle: &v1.Lifecycle{ + Type: &keystone, }, }, + { + Name: "sidecar-container", + Image: imageutils.GetE2EImage(imageutils.BusyBox), + Command: []string{"sh", "-c", "sleep 3600"}, + }, }, }, } - j, err := jobClient.Create(context.TODO(), job, metav1.CreateOptions{}) - framework.ExpectNoError(err, "error while creating the job") + // create the pod and wait for it to be in running state + podClient.CreateSync(pod) - // it is expected that the pod succeeds and the job should have a completed - // status eventually even if the sidecar container has not terminated in the pod - gomega.Eventually(func() bool { - j, err = jobClient.Get(context.TODO(), j.Name, metav1.GetOptions{}) - framework.ExpectNoError(err, "error while getting job") - for _, c := range j.Status.Conditions { - if c.Type == batchv1.JobComplete && c.Status == v1.ConditionTrue { - return true - } - } - return false - }).Should(gomega.BeTrue()) + // the pod should succeed when the main container exits + podClient.WaitForSuccess(podName, framework.PodStartTimeout) }) From 35569d7687c266fcd308b207e641f11006da63d0 Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Thu, 13 Oct 2022 17:39:17 +0530 Subject: [PATCH 3/3] add feature flag to ginkgo.It Signed-off-by: Akhil Mohan --- test/e2e/common/node/keystone_containers.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/e2e/common/node/keystone_containers.go b/test/e2e/common/node/keystone_containers.go index 36727c2eabd84..5667aa4add84f 100644 --- a/test/e2e/common/node/keystone_containers.go +++ b/test/e2e/common/node/keystone_containers.go @@ -37,7 +37,7 @@ var _ = SIGDescribe("Keystone Containers [Feature:KeystoneContainers]", func() { ginkgo.Context("When creating a pod with two containers", func() { - ginkgo.It("should delete the pod once the keystone container exits successfully [Keystone]", func() { + ginkgo.It("should delete the pod once the keystone container exits successfully [Feature:KeystoneContainers]", func() { keystone := "Keystone" podName := fmt.Sprintf("keystone-test-pod-%s", uuid.NewUUID()) pod := &v1.Pod{