Skip to content

Commit 1c4a7db

Browse files
authored
Merge pull request kubernetes#78245 from k-toyoda-pi/add_test_cronjob_failedJobsHistoryLimit
add e2e test for cronjob failedJobsHistoryLimit
2 parents 0d579bf + 6ce0d54 commit 1c4a7db

File tree

1 file changed

+74
-47
lines changed

1 file changed

+74
-47
lines changed

test/e2e/apps/cronjob.go

Lines changed: 74 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ var _ = SIGDescribe("CronJob", func() {
5151

5252
// Pod will complete instantly
5353
successCommand := []string{"/bin/true"}
54+
failureCommand := []string{"/bin/false"}
5455

5556
ginkgo.BeforeEach(func() {
5657
framework.SkipIfMissingResource(f.DynamicClient, CronJobGroupVersionResourceBeta, f.Namespace.Name)
@@ -60,7 +61,7 @@ var _ = SIGDescribe("CronJob", func() {
6061
ginkgo.It("should schedule multiple jobs concurrently", func() {
6162
ginkgo.By("Creating a cronjob")
6263
cronJob := newTestCronJob("concurrent", "*/1 * * * ?", batchv1beta1.AllowConcurrent,
63-
sleepCommand, nil)
64+
sleepCommand, nil, nil)
6465
cronJob, err := createCronJob(f.ClientSet, f.Namespace.Name, cronJob)
6566
framework.ExpectNoError(err, "Failed to create CronJob in namespace %s", f.Namespace.Name)
6667

@@ -83,7 +84,7 @@ var _ = SIGDescribe("CronJob", func() {
8384
ginkgo.It("should not schedule jobs when suspended [Slow]", func() {
8485
ginkgo.By("Creating a suspended cronjob")
8586
cronJob := newTestCronJob("suspended", "*/1 * * * ?", batchv1beta1.AllowConcurrent,
86-
sleepCommand, nil)
87+
sleepCommand, nil, nil)
8788
t := true
8889
cronJob.Spec.Suspend = &t
8990
cronJob, err := createCronJob(f.ClientSet, f.Namespace.Name, cronJob)
@@ -107,7 +108,7 @@ var _ = SIGDescribe("CronJob", func() {
107108
ginkgo.It("should not schedule new jobs when ForbidConcurrent [Slow]", func() {
108109
ginkgo.By("Creating a ForbidConcurrent cronjob")
109110
cronJob := newTestCronJob("forbid", "*/1 * * * ?", batchv1beta1.ForbidConcurrent,
110-
sleepCommand, nil)
111+
sleepCommand, nil, nil)
111112
cronJob, err := createCronJob(f.ClientSet, f.Namespace.Name, cronJob)
112113
framework.ExpectNoError(err, "Failed to create CronJob in namespace %s", f.Namespace.Name)
113114

@@ -139,7 +140,7 @@ var _ = SIGDescribe("CronJob", func() {
139140
ginkgo.It("should replace jobs when ReplaceConcurrent", func() {
140141
ginkgo.By("Creating a ReplaceConcurrent cronjob")
141142
cronJob := newTestCronJob("replace", "*/1 * * * ?", batchv1beta1.ReplaceConcurrent,
142-
sleepCommand, nil)
143+
sleepCommand, nil, nil)
143144
cronJob, err := createCronJob(f.ClientSet, f.Namespace.Name, cronJob)
144145
framework.ExpectNoError(err, "Failed to create CronJob in namespace %s", f.Namespace.Name)
145146

@@ -171,7 +172,7 @@ var _ = SIGDescribe("CronJob", func() {
171172
ginkgo.It("should not emit unexpected warnings", func() {
172173
ginkgo.By("Creating a cronjob")
173174
cronJob := newTestCronJob("concurrent", "*/1 * * * ?", batchv1beta1.AllowConcurrent,
174-
nil, nil)
175+
nil, nil, nil)
175176
cronJob, err := createCronJob(f.ClientSet, f.Namespace.Name, cronJob)
176177
framework.ExpectNoError(err, "Failed to create CronJob in namespace %s", f.Namespace.Name)
177178

@@ -194,7 +195,7 @@ var _ = SIGDescribe("CronJob", func() {
194195
ginkgo.It("should remove from active list jobs that have been deleted", func() {
195196
ginkgo.By("Creating a ForbidConcurrent cronjob")
196197
cronJob := newTestCronJob("forbid", "*/1 * * * ?", batchv1beta1.ForbidConcurrent,
197-
sleepCommand, nil)
198+
sleepCommand, nil, nil)
198199
cronJob, err := createCronJob(f.ClientSet, f.Namespace.Name, cronJob)
199200
framework.ExpectNoError(err, "Failed to create CronJob in namespace %s", f.Namespace.Name)
200201

@@ -229,52 +230,75 @@ var _ = SIGDescribe("CronJob", func() {
229230
framework.ExpectNoError(err, "Failed to remove %s cronjob in namespace %s", cronJob.Name, f.Namespace.Name)
230231
})
231232

232-
// cleanup of successful finished jobs, with limit of one successful job
233-
ginkgo.It("should delete successful finished jobs with limit of one successful job", func() {
234-
ginkgo.By("Creating a AllowConcurrent cronjob with custom history limits")
235-
successLimit := int32(1)
236-
cronJob := newTestCronJob("concurrent-limit", "*/1 * * * ?", batchv1beta1.AllowConcurrent,
237-
successCommand, &successLimit)
238-
cronJob, err := createCronJob(f.ClientSet, f.Namespace.Name, cronJob)
239-
framework.ExpectNoError(err, "Failed to create allowconcurrent cronjob with custom history limits in namespace %s", f.Namespace.Name)
240-
241-
// Job is going to complete instantly: do not check for an active job
242-
// as we are most likely to miss it
243-
244-
ginkgo.By("Ensuring a finished job exists")
245-
err = waitForAnyFinishedJob(f.ClientSet, f.Namespace.Name)
246-
framework.ExpectNoError(err, "Failed to ensure a finished cronjob exists in namespace %s", f.Namespace.Name)
247-
248-
ginkgo.By("Ensuring a finished job exists by listing jobs explicitly")
249-
jobs, err := f.ClientSet.BatchV1().Jobs(f.Namespace.Name).List(metav1.ListOptions{})
250-
framework.ExpectNoError(err, "Failed to ensure a finished cronjob exists by listing jobs explicitly in namespace %s", f.Namespace.Name)
251-
_, finishedJobs := filterActiveJobs(jobs)
252-
framework.ExpectEqual(len(finishedJobs), 1)
253-
254-
// Job should get deleted when the next job finishes the next minute
255-
ginkgo.By("Ensuring this job and its pods does not exist anymore")
256-
err = waitForJobToDisappear(f.ClientSet, f.Namespace.Name, finishedJobs[0])
257-
framework.ExpectNoError(err, "Failed to ensure that job does not exists anymore in namespace %s", f.Namespace.Name)
258-
err = waitForJobsPodToDisappear(f.ClientSet, f.Namespace.Name, finishedJobs[0])
259-
framework.ExpectNoError(err, "Failed to ensure that pods for job does not exists anymore in namespace %s", f.Namespace.Name)
260-
261-
ginkgo.By("Ensuring there is 1 finished job by listing jobs explicitly")
262-
jobs, err = f.ClientSet.BatchV1().Jobs(f.Namespace.Name).List(metav1.ListOptions{})
263-
framework.ExpectNoError(err, "Failed to ensure there is one finished job by listing job explicitly in namespace %s", f.Namespace.Name)
264-
_, finishedJobs = filterActiveJobs(jobs)
265-
framework.ExpectEqual(len(finishedJobs), 1)
233+
// cleanup of successful/failed finished jobs, with successfulJobsHistoryLimit and failedJobsHistoryLimit
234+
ginkgo.It("should delete successful/failed finished jobs with limit of one job", func() {
235+
236+
testCases := []struct {
237+
description string
238+
command []string
239+
successLimit int32
240+
failedLimit int32
241+
}{
242+
{
243+
description: "successful-jobs-history-limit",
244+
command: successCommand,
245+
successLimit: 1, // keep one successful job
246+
failedLimit: 0, // keep none failed job
247+
},
248+
{
249+
description: "failed-jobs-history-limit",
250+
command: failureCommand,
251+
successLimit: 0, // keep none succcessful job
252+
failedLimit: 1, // keep one failed job
253+
},
254+
}
266255

267-
ginkgo.By("Removing cronjob")
268-
err = deleteCronJob(f.ClientSet, f.Namespace.Name, cronJob.Name)
269-
framework.ExpectNoError(err, "Failed to remove the %s cronjob in namespace %s", cronJob.Name, f.Namespace.Name)
256+
for _, t := range testCases {
257+
ginkgo.By(fmt.Sprintf("Creating a AllowConcurrent cronjob with custom %s", t.description))
258+
cronJob := newTestCronJob(t.description, "*/1 * * * ?", batchv1beta1.AllowConcurrent,
259+
t.command, &t.successLimit, &t.failedLimit)
260+
cronJob, err := createCronJob(f.ClientSet, f.Namespace.Name, cronJob)
261+
framework.ExpectNoError(err, "Failed to create allowconcurrent cronjob with custom history limits in namespace %s", f.Namespace.Name)
262+
263+
// Job is going to complete instantly: do not check for an active job
264+
// as we are most likely to miss it
265+
266+
ginkgo.By("Ensuring a finished job exists")
267+
err = waitForAnyFinishedJob(f.ClientSet, f.Namespace.Name)
268+
framework.ExpectNoError(err, "Failed to ensure a finished cronjob exists in namespace %s", f.Namespace.Name)
269+
270+
ginkgo.By("Ensuring a finished job exists by listing jobs explicitly")
271+
jobs, err := f.ClientSet.BatchV1().Jobs(f.Namespace.Name).List(metav1.ListOptions{})
272+
framework.ExpectNoError(err, "Failed to ensure a finished cronjob exists by listing jobs explicitly in namespace %s", f.Namespace.Name)
273+
_, finishedJobs := filterActiveJobs(jobs)
274+
framework.ExpectEqual(len(finishedJobs), 1)
275+
276+
// Job should get deleted when the next job finishes the next minute
277+
ginkgo.By("Ensuring this job and its pods does not exist anymore")
278+
err = waitForJobToDisappear(f.ClientSet, f.Namespace.Name, finishedJobs[0])
279+
framework.ExpectNoError(err, "Failed to ensure that job does not exists anymore in namespace %s", f.Namespace.Name)
280+
err = waitForJobsPodToDisappear(f.ClientSet, f.Namespace.Name, finishedJobs[0])
281+
framework.ExpectNoError(err, "Failed to ensure that pods for job does not exists anymore in namespace %s", f.Namespace.Name)
282+
283+
ginkgo.By("Ensuring there is 1 finished job by listing jobs explicitly")
284+
jobs, err = f.ClientSet.BatchV1().Jobs(f.Namespace.Name).List(metav1.ListOptions{})
285+
framework.ExpectNoError(err, "Failed to ensure there is one finished job by listing job explicitly in namespace %s", f.Namespace.Name)
286+
_, finishedJobs = filterActiveJobs(jobs)
287+
framework.ExpectEqual(len(finishedJobs), 1)
288+
289+
ginkgo.By("Removing cronjob")
290+
err = deleteCronJob(f.ClientSet, f.Namespace.Name, cronJob.Name)
291+
framework.ExpectNoError(err, "Failed to remove the %s cronjob in namespace %s", cronJob.Name, f.Namespace.Name)
292+
}
270293
})
271294
})
272295

273296
// newTestCronJob returns a cronjob which does one of several testing behaviors.
274297
func newTestCronJob(name, schedule string, concurrencyPolicy batchv1beta1.ConcurrencyPolicy,
275-
command []string, successfulJobsHistoryLimit *int32) *batchv1beta1.CronJob {
298+
command []string, successfulJobsHistoryLimit *int32, failedJobsHistoryLimit *int32) *batchv1beta1.CronJob {
276299
parallelism := int32(1)
277300
completions := int32(1)
301+
backofflimit := int32(1)
278302
sj := &batchv1beta1.CronJob{
279303
ObjectMeta: metav1.ObjectMeta{
280304
Name: name,
@@ -287,8 +311,9 @@ func newTestCronJob(name, schedule string, concurrencyPolicy batchv1beta1.Concur
287311
ConcurrencyPolicy: concurrencyPolicy,
288312
JobTemplate: batchv1beta1.JobTemplateSpec{
289313
Spec: batchv1.JobSpec{
290-
Parallelism: &parallelism,
291-
Completions: &completions,
314+
Parallelism: &parallelism,
315+
Completions: &completions,
316+
BackoffLimit: &backofflimit,
292317
Template: v1.PodTemplateSpec{
293318
Spec: v1.PodSpec{
294319
RestartPolicy: v1.RestartPolicyOnFailure,
@@ -319,6 +344,7 @@ func newTestCronJob(name, schedule string, concurrencyPolicy batchv1beta1.Concur
319344
},
320345
}
321346
sj.Spec.SuccessfulJobsHistoryLimit = successfulJobsHistoryLimit
347+
sj.Spec.FailedJobsHistoryLimit = failedJobsHistoryLimit
322348
if command != nil {
323349
sj.Spec.JobTemplate.Spec.Template.Spec.Containers[0].Command = command
324350
}
@@ -334,7 +360,8 @@ func getCronJob(c clientset.Interface, ns, name string) (*batchv1beta1.CronJob,
334360
}
335361

336362
func deleteCronJob(c clientset.Interface, ns, name string) error {
337-
return c.BatchV1beta1().CronJobs(ns).Delete(name, nil)
363+
propagationPolicy := metav1.DeletePropagationBackground // Also delete jobs and pods related to cronjob
364+
return c.BatchV1beta1().CronJobs(ns).Delete(name, &metav1.DeleteOptions{PropagationPolicy: &propagationPolicy})
338365
}
339366

340367
// Wait for at least given amount of active jobs.

0 commit comments

Comments
 (0)