@@ -465,6 +465,80 @@ done`}
465
465
gomega .Expect (job .Status .Succeeded ).Should (gomega .Equal (int32 (2 )))
466
466
})
467
467
468
+ /*
469
+ Testcase: Terminate job execution when the maxFailedIndexes is exceeded
470
+ Description: Create an indexed job with backoffLimitPerIndex and maxFailedIndexes.
471
+ Verify the job execution is terminated as soon as the number of failed
472
+ indexes exceeds maxFailedIndexes.
473
+ */
474
+ ginkgo .It ("should terminate job execution when the number of failed indexes exceeds maxFailedIndexes" , func (ctx context.Context ) {
475
+ // we use parallelism=1 to make sure in the asserts only one pod was created
476
+ parallelism := int32 (1 )
477
+ ginkgo .By ("Creating an indexed job with backoffLimit per index and maxFailedIndexes" )
478
+ job := e2ejob .NewTestJob ("fail" , "with-max-failed-indexes" , v1 .RestartPolicyNever , parallelism , completions , nil , backoffLimit )
479
+ job .Spec .BackoffLimit = nil
480
+ job .Spec .BackoffLimitPerIndex = ptr.To [int32 ](0 )
481
+ job .Spec .MaxFailedIndexes = ptr.To [int32 ](0 )
482
+
483
+ mode := batchv1 .IndexedCompletion
484
+ job .Spec .CompletionMode = & mode
485
+ job , err := e2ejob .CreateJob (ctx , f .ClientSet , f .Namespace .Name , job )
486
+ framework .ExpectNoError (err , "failed to create job in namespace: %s" , f .Namespace .Name )
487
+
488
+ ginkgo .By ("Awaiting for the job to fail as the number of max failed indexes is exceeded" )
489
+ err = e2ejob .WaitForJobFailed (f .ClientSet , f .Namespace .Name , job .Name )
490
+ framework .ExpectNoError (err , "failed to ensure job completion in namespace: %s" , f .Namespace .Name )
491
+
492
+ ginkgo .By ("Verifying the Job status fields to ensure early termination of the job" )
493
+ job , err = e2ejob .GetJob (ctx , f .ClientSet , f .Namespace .Name , job .Name )
494
+ framework .ExpectNoError (err , "failed to retrieve latest job object" )
495
+ gomega .Expect (job .Status .FailedIndexes ).Should (gomega .HaveValue (gomega .Equal ("0" )))
496
+ gomega .Expect (job .Status .Failed ).Should (gomega .Equal (int32 (1 )))
497
+ })
498
+
499
+ /*
500
+ Testcase: Mark indexes as failed when the FailIndex action is matched in podFailurePolicy
501
+ Description: Create an indexed job with backoffLimitPerIndex, and podFailurePolicy
502
+ with the FailIndex action. Verify the failed pods matching the pod failure policy
503
+ result in marking the corresponding indexes as failed without restarts, despite
504
+ backoffLimitPerIndex > 0.
505
+ */
506
+ ginkgo .It ("should mark indexes as failed when the FailIndex action is matched in podFailurePolicy" , func (ctx context.Context ) {
507
+ completions := int32 (2 )
508
+
509
+ ginkgo .By ("Creating an indexed job with failing pods matching the FailIndex action" )
510
+ job := e2ejob .NewTestJob ("failOddSucceedEven" , "matching-fail-index-action" , v1 .RestartPolicyNever , parallelism , completions , nil , backoffLimit )
511
+ job .Spec .BackoffLimit = nil
512
+ job .Spec .BackoffLimitPerIndex = ptr.To [int32 ](1 )
513
+ job .Spec .PodFailurePolicy = & batchv1.PodFailurePolicy {
514
+ Rules : []batchv1.PodFailurePolicyRule {
515
+ {
516
+ Action : batchv1 .PodFailurePolicyActionFailIndex ,
517
+ OnExitCodes : & batchv1.PodFailurePolicyOnExitCodesRequirement {
518
+ Operator : batchv1 .PodFailurePolicyOnExitCodesOpIn ,
519
+ Values : []int32 {1 },
520
+ },
521
+ },
522
+ },
523
+ }
524
+ mode := batchv1 .IndexedCompletion
525
+ job .Spec .CompletionMode = & mode
526
+ job , err := e2ejob .CreateJob (ctx , f .ClientSet , f .Namespace .Name , job )
527
+ framework .ExpectNoError (err , "failed to create job in namespace: %s" , f .Namespace .Name )
528
+
529
+ ginkgo .By ("Awaiting for the job to fail as all indexes are failed" )
530
+ err = e2ejob .WaitForJobFailed (f .ClientSet , f .Namespace .Name , job .Name )
531
+ framework .ExpectNoError (err , "failed to ensure job completion in namespace: %s" , f .Namespace .Name )
532
+
533
+ ginkgo .By ("Verifying the Job status fields to ensure the upper indexes didn't execute" )
534
+ job , err = e2ejob .GetJob (ctx , f .ClientSet , f .Namespace .Name , job .Name )
535
+ framework .ExpectNoError (err , "failed to retrieve latest job object" )
536
+ gomega .Expect (job .Status .FailedIndexes ).Should (gomega .HaveValue (gomega .Equal ("1" )))
537
+ gomega .Expect (job .Status .CompletedIndexes ).Should (gomega .Equal ("0" ))
538
+ gomega .Expect (job .Status .Failed ).Should (gomega .Equal (int32 (1 )))
539
+ gomega .Expect (job .Status .Succeeded ).Should (gomega .Equal (int32 (1 )))
540
+ })
541
+
468
542
/*
469
543
Testcase: Ensure that the pods associated with the job are removed once the job is deleted
470
544
Description: Create a job and ensure the associated pod count is equal to parallelism count. Delete the
0 commit comments