diff --git a/pkg/registry/batch/job/strategy.go b/pkg/registry/batch/job/strategy.go index 2db435d94fc..71cd60c0598 100644 --- a/pkg/registry/batch/job/strategy.go +++ b/pkg/registry/batch/job/strategy.go @@ -379,7 +379,7 @@ func getStatusValidationOptions(newJob, oldJob *batch.Job) batchvalidation.JobSt isUncountedTerminatedPodsChanged := !apiequality.Semantic.DeepEqual(oldJob.Status.UncountedTerminatedPods, newJob.Status.UncountedTerminatedPods) isReadyChanged := !ptr.Equal(oldJob.Status.Ready, newJob.Status.Ready) isTerminatingChanged := !ptr.Equal(oldJob.Status.Terminating, newJob.Status.Terminating) - isSuspendedWithZeroCompletions := newJob.Spec.Completions != nil && *newJob.Spec.Completions == 0 && newJob.Spec.Suspend != nil && *newJob.Spec.Suspend + isSuspendedWithZeroCompletions := ptr.Equal(newJob.Spec.Suspend, ptr.To(true)) && ptr.Equal(newJob.Spec.Completions, ptr.To[int32](0)) return batchvalidation.JobStatusValidationOptions{ // We allow to decrease the counter for succeeded pods for jobs which diff --git a/test/integration/job/job_test.go b/test/integration/job/job_test.go index d1f12bbc9ca..1c608c4c0ce 100644 --- a/test/integration/job/job_test.go +++ b/test/integration/job/job_test.go @@ -2801,29 +2801,6 @@ func TestParallelJobWithCompletions(t *testing.T) { }) } -// TestSuspendedJobWithZeroCompletions verifies the suspended Job with -// completions=0 is marked as Complete. -func TestSuspendedJobWithZeroCompletions(t *testing.T) { - closeFn, restConfig, clientSet, ns := setup(t, "suspended-with-zero-completions") - t.Cleanup(closeFn) - ctx, cancel := startJobControllerAndWaitForCaches(t, restConfig) - t.Cleanup(func() { - cancel() - }) - jobObj, err := createJobWithDefaults(ctx, clientSet, ns.Name, &batchv1.Job{ - Spec: batchv1.JobSpec{ - Completions: ptr.To[int32](0), - Suspend: ptr.To(true), - }, - }) - if err != nil { - t.Fatalf("Failed to create Job: %v", err) - } - for _, condition := range []batchv1.JobConditionType{batchv1.JobSuccessCriteriaMet, batchv1.JobComplete} { - validateJobCondition(ctx, t, clientSet, jobObj, condition) - } -} - func TestIndexedJob(t *testing.T) { t.Cleanup(setDurationDuringTest(&jobcontroller.DefaultJobPodFailureBackOff, fastPodFailureBackoff)) closeFn, restConfig, clientSet, ns := setup(t, "indexed") @@ -4007,6 +3984,29 @@ func TestSuspendJob(t *testing.T) { } } +// TestSuspendJobWithZeroCompletions verifies the suspended Job with +// completions=0 is marked as Complete. +func TestSuspendJobWithZeroCompletions(t *testing.T) { + closeFn, restConfig, clientSet, ns := setup(t, "suspended-with-zero-completions") + t.Cleanup(closeFn) + ctx, cancel := startJobControllerAndWaitForCaches(t, restConfig) + t.Cleanup(func() { + cancel() + }) + jobObj, err := createJobWithDefaults(ctx, clientSet, ns.Name, &batchv1.Job{ + Spec: batchv1.JobSpec{ + Completions: ptr.To[int32](0), + Suspend: ptr.To(true), + }, + }) + if err != nil { + t.Fatalf("Failed to create Job: %v", err) + } + for _, condition := range []batchv1.JobConditionType{batchv1.JobSuccessCriteriaMet, batchv1.JobComplete} { + validateJobCondition(ctx, t, clientSet, jobObj, condition) + } +} + func TestSuspendJobControllerRestart(t *testing.T) { closeFn, restConfig, clientSet, ns := setup(t, "suspend") t.Cleanup(closeFn)