diff --git a/go.mod b/go.mod index 42a9fd74d..57b51dc76 100644 --- a/go.mod +++ b/go.mod @@ -82,3 +82,5 @@ require ( sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) + +replace k8s.io/api => k8s.io/api v0.0.0-20240718103906-7c71f3c0b7a7 // feature-branch diff --git a/go.sum b/go.sum index 78551be8b..92b26e18b 100644 --- a/go.sum +++ b/go.sum @@ -188,8 +188,8 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.29.4 h1:WEnF/XdxuCxdG3ayHNRR8yH3cI1B/llkWBma6bq4R3w= -k8s.io/api v0.29.4/go.mod h1:DetSv0t4FBTcEpfA84NJV3g9a7+rSzlUHk5ADAYHUv0= +k8s.io/api v0.0.0-20240718103906-7c71f3c0b7a7 h1:yum8NOR/ysIRWDiCZuVbLvHCmeuM2KHc/8voO+xoivw= +k8s.io/api v0.0.0-20240718103906-7c71f3c0b7a7/go.mod h1:AFqQkkEfmsUH52cPeKeWVm6eQZJUan7p62A0JEH+azM= k8s.io/apiextensions-apiserver v0.29.2 h1:UK3xB5lOWSnhaCk0RFZ0LUacPZz9RY4wi/yt2Iu+btg= k8s.io/apiextensions-apiserver v0.29.2/go.mod h1:aLfYjpA5p3OwtqNXQFkhJ56TB+spV8Gc4wfMhUA3/b8= k8s.io/apimachinery v0.29.4 h1:RaFdJiDmuKs/8cm1M6Dh1Kvyh59YQFDcFuFTSmXes6Q= diff --git a/pkg/util/testing/wrappers.go b/pkg/util/testing/wrappers.go index a08eef463..232e7841a 100644 --- a/pkg/util/testing/wrappers.go +++ b/pkg/util/testing/wrappers.go @@ -254,6 +254,12 @@ func (j *JobTemplateWrapper) PodSpec(podSpec corev1.PodSpec) *JobTemplateWrapper return j } +// PodFailurePolicy sets the Job pod failure policy +func (j *JobTemplateWrapper) PodFailurePolicy(podFailurePolicy batchv1.PodFailurePolicy) *JobTemplateWrapper { + j.Spec.PodFailurePolicy = &podFailurePolicy + return j +} + // SetAnnotations sets the annotations on the Job template. func (j *JobTemplateWrapper) SetAnnotations(annotations map[string]string) *JobTemplateWrapper { j.Annotations = annotations diff --git a/test/e2e/e2e_test.go b/test/e2e/e2e_test.go index 8c713a721..7e920e83e 100644 --- a/test/e2e/e2e_test.go +++ b/test/e2e/e2e_test.go @@ -21,6 +21,7 @@ import ( "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" + v1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" @@ -130,7 +131,54 @@ var _ = ginkgo.Describe("JobSet", func() { util.JobSetDeleted(ctx, k8sClient, js, timeout) }) }) + ginkgo.When("pod failure policy is used", func() { + ginkgo.It("should allow to fail the Job on exit code", func() { + ctx := context.Background() + + // This test verifies that the PodFailurePolicy terminated the Job + // Otherwise the pod restarts, with the default backoffLimit of 6 + // the Pod restarts would take cumulatively at least: + // 10+20+40+80+160+320=630s (exceeding the test timeout) + ginkgo.By("creating jobset with ttl seconds after finished") + jsWrapper := testing.MakeJobSet("job-pod-failure-policy", ns.Name). + TTLSecondsAfterFinished(5). + ReplicatedJob(testing.MakeReplicatedJob("rjob"). + Job(testing.MakeJobTemplate("job", ns.Name). + PodFailurePolicy(v1.PodFailurePolicy{ + Rules: []v1.PodFailurePolicyRule{ + { + Action: v1.PodFailurePolicyActionFailJob, + OnExitCodes: &v1.PodFailurePolicyOnExitCodesRequirement{ + Operator: v1.PodFailurePolicyOnExitCodesOpIn, + Values: []int32{42}, + }, + }, + }, + }). + PodSpec(corev1.PodSpec{ + RestartPolicy: "Never", + Containers: []corev1.Container{ + { + Name: "sleep-test-container", + Image: "bash:latest", + Command: []string{"bash", "-c"}, + Args: []string{"exit 42"}, + }, + }, + }).Obj()). + Replicas(int32(1)). + Obj()) + js := jsWrapper.Obj() + // Verify jobset created successfully. + ginkgo.By("checking that jobset creation succeeds") + gomega.Expect(k8sClient.Create(ctx, js)).Should(gomega.Succeed()) + + // Check jobset status if specified. + ginkgo.By("checking jobset condition") + util.JobSetFailed(ctx, k8sClient, js, timeout) + }) + }) }) // end of Describe // getPingCommand returns ping command for 4 hostnames