1
16
17 package job
18
19 import (
20 batchv1 "k8s.io/api/batch/v1"
21 v1 "k8s.io/api/core/v1"
22 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23 "k8s.io/apimachinery/pkg/util/rand"
24 "k8s.io/kubernetes/test/e2e/framework"
25 imageutils "k8s.io/kubernetes/test/utils/image"
26 "k8s.io/utils/ptr"
27 )
28
29
30
31
32
33
34
35 func NewTestJob(behavior, name string, rPol v1.RestartPolicy, parallelism, completions int32, activeDeadlineSeconds *int64, backoffLimit int32) *batchv1.Job {
36 anyNode := ""
37 return NewTestJobOnNode(behavior, name, rPol, parallelism, completions, activeDeadlineSeconds, backoffLimit, anyNode)
38 }
39
40
41
42 func NewTestJobOnNode(behavior, name string, rPol v1.RestartPolicy, parallelism, completions int32, activeDeadlineSeconds *int64, backoffLimit int32, nodeName string) *batchv1.Job {
43 manualSelector := false
44 job := &batchv1.Job{
45 ObjectMeta: metav1.ObjectMeta{
46 Name: name,
47 },
48 TypeMeta: metav1.TypeMeta{
49 Kind: "Job",
50 },
51 Spec: batchv1.JobSpec{
52 ActiveDeadlineSeconds: activeDeadlineSeconds,
53 Parallelism: ¶llelism,
54 Completions: &completions,
55 BackoffLimit: &backoffLimit,
56 ManualSelector: &manualSelector,
57 Template: v1.PodTemplateSpec{
58 ObjectMeta: metav1.ObjectMeta{
59 Labels: map[string]string{JobSelectorKey: name},
60 },
61 Spec: v1.PodSpec{
62 RestartPolicy: rPol,
63 Volumes: []v1.Volume{
64 {
65 Name: "data",
66 VolumeSource: v1.VolumeSource{
67 EmptyDir: &v1.EmptyDirVolumeSource{},
68 },
69 },
70 },
71 Containers: []v1.Container{
72 {
73 Name: "c",
74 Image: framework.BusyBoxImage,
75 Command: []string{},
76 VolumeMounts: []v1.VolumeMount{
77 {
78 MountPath: "/data",
79 Name: "data",
80 },
81 },
82 SecurityContext: &v1.SecurityContext{},
83 },
84 },
85 },
86 },
87 },
88 }
89 if len(nodeName) > 0 {
90 job.Spec.Template.Spec.NodeSelector = map[string]string{
91 "kubernetes.io/hostname": nodeName,
92 }
93 }
94 switch behavior {
95 case "neverTerminate":
96
97
98
99 job.Spec.Template.Spec.Containers[0].Command = []string{"sleep", "1000000"}
100 job.Spec.Template.Spec.TerminationGracePeriodSeconds = ptr.To(int64(1))
101 case "notTerminate":
102 job.Spec.Template.Spec.Containers[0].Image = imageutils.GetPauseImageName()
103 case "fail":
104 job.Spec.Template.Spec.Containers[0].Command = []string{"/bin/sh", "-c", "exit 1"}
105 case "failOddSucceedEven":
106 job.Spec.Template.Spec.Containers[0].Command = []string{"sh", "-c"}
107 job.Spec.Template.Spec.Containers[0].Args = []string{`
108 if [ $(expr ${JOB_COMPLETION_INDEX} % 2) -ne 0 ]; then
109 exit 1
110 else
111 exit 0
112 fi
113 `,
114 }
115 case "succeed":
116 job.Spec.Template.Spec.Containers[0].Command = []string{"/bin/sh", "-c", "exit 0"}
117 case "randomlySucceedOrFail":
118
119
120 job.Spec.Template.Spec.Containers[0].Command = []string{"/bin/sh", "-c", "exit $(( $RANDOM / 16384 ))"}
121 case "failOnce":
122
123
124
125
126
127
128 setupHostPathDirectory(job)
129 job.Spec.Template.Spec.Containers[0].Command = []string{"/bin/sh", "-c", "if [[ -r /data/foo ]] ; then exit 0 ; else touch /data/foo ; exit 1 ; fi"}
130 case "notTerminateOnce":
131
132
133
134
135
136 setupHostPathDirectory(job)
137 job.Spec.Template.Spec.TerminationGracePeriodSeconds = ptr.To(int64(1))
138 job.Spec.Template.Spec.Containers[0].Command = []string{"/bin/sh", "-c", "if [[ -r /data/foo ]] ; then exit 0 ; elif [[ $JOB_COMPLETION_INDEX -eq 0 ]] ; then touch /data/foo ; sleep 1000000 ; else exit 1 ; fi"}
139 }
140 return job
141 }
142
143
144 func setupHostPathDirectory(job *batchv1.Job) {
145 if _, nodeNameSpecified := job.Spec.Template.Spec.NodeSelector["kubernetes.io/hostname"]; nodeNameSpecified {
146 randomDir := "/tmp/job-e2e/" + rand.String(10)
147 hostPathType := v1.HostPathDirectoryOrCreate
148 job.Spec.Template.Spec.Volumes[0].VolumeSource = v1.VolumeSource{HostPath: &v1.HostPathVolumeSource{Path: randomDir, Type: &hostPathType}}
149
150
151
152 privileged := !framework.NodeOSDistroIs("windows")
153 job.Spec.Template.Spec.Containers[0].SecurityContext.Privileged = &privileged
154 }
155 }
156
View as plain text