volcano.sh/volcano@v1.9.0/test/e2e/schedulingaction/allocate.go (about) 1 /* 2 Copyright 2021 The Volcano Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package schedulingaction 18 19 import ( 20 "context" 21 22 "github.com/onsi/ginkgo/v2" 23 "github.com/onsi/gomega" 24 25 corev1 "k8s.io/api/core/v1" 26 "k8s.io/apimachinery/pkg/api/resource" 27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 28 29 schedulingv1beta1 "volcano.sh/apis/pkg/apis/scheduling/v1beta1" 30 31 e2eutil "volcano.sh/volcano/test/e2e/util" 32 ) 33 34 var _ = ginkgo.Describe("Job E2E Test", func() { 35 ginkgo.It("allocate work when resource is enough", func() { 36 ctx := e2eutil.InitTestContext(e2eutil.Options{ 37 NodesNumLimit: 2, 38 NodesResourceLimit: corev1.ResourceList{ 39 corev1.ResourceCPU: resource.MustParse("2000m"), 40 corev1.ResourceMemory: resource.MustParse("2048Mi")}, 41 }) 42 defer e2eutil.CleanupTestContext(ctx) 43 44 slot1 := corev1.ResourceList{ 45 corev1.ResourceCPU: resource.MustParse("500m"), 46 corev1.ResourceMemory: resource.MustParse("512Mi")} 47 slot2 := corev1.ResourceList{ 48 corev1.ResourceCPU: resource.MustParse("1000m"), 49 corev1.ResourceMemory: resource.MustParse("1024Mi")} 50 51 job := &e2eutil.JobSpec{ 52 Tasks: []e2eutil.TaskSpec{ 53 { 54 Img: e2eutil.DefaultNginxImage, 55 Req: slot1, 56 Min: 1, 57 Rep: 1, 58 }, 59 }, 60 } 61 62 job.Name = "low" 63 lowReqJob := e2eutil.CreateJob(ctx, job) 64 err := e2eutil.WaitJobReady(ctx, lowReqJob) 65 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 66 67 job.Name = "high" 68 job.Tasks[0].Req = slot2 69 highReqJob := e2eutil.CreateJob(ctx, job) 70 err = e2eutil.WaitJobReady(ctx, highReqJob) 71 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 72 }) 73 74 ginkgo.It("allocate don't work when resource is NOT enough", func() { 75 ctx := e2eutil.InitTestContext(e2eutil.Options{ 76 NodesNumLimit: 1, 77 NodesResourceLimit: corev1.ResourceList{ 78 corev1.ResourceCPU: resource.MustParse("2000m"), 79 corev1.ResourceMemory: resource.MustParse("2048Mi")}, 80 }) 81 defer e2eutil.CleanupTestContext(ctx) 82 83 slot1 := corev1.ResourceList{ 84 corev1.ResourceCPU: resource.MustParse("500m"), 85 corev1.ResourceMemory: resource.MustParse("512Mi")} 86 slot2 := corev1.ResourceList{ 87 corev1.ResourceCPU: resource.MustParse("1000m"), 88 corev1.ResourceMemory: resource.MustParse("1024Mi")} 89 slot3 := corev1.ResourceList{ 90 corev1.ResourceCPU: resource.MustParse("3000m"), 91 corev1.ResourceMemory: resource.MustParse("3072Mi")} 92 93 job := &e2eutil.JobSpec{ 94 Tasks: []e2eutil.TaskSpec{ 95 { 96 Img: e2eutil.DefaultNginxImage, 97 Req: slot2, 98 Min: 1, 99 Rep: 1, 100 }, 101 }, 102 } 103 104 job.Name = "middle" 105 midReqJob := e2eutil.CreateJob(ctx, job) 106 err := e2eutil.WaitJobReady(ctx, midReqJob) 107 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 108 109 job.Name = "low" 110 job.Tasks[0].Req = slot1 111 lowReqJob := e2eutil.CreateJob(ctx, job) 112 err = e2eutil.WaitJobReady(ctx, lowReqJob) 113 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 114 115 job.Name = "high" 116 job.Tasks[0].Req = slot3 117 highReqJob := e2eutil.CreateJob(ctx, job) 118 err = e2eutil.WaitJobPending(ctx, highReqJob) 119 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 120 }) 121 122 ginkgo.It("allocate don't work when podgroup is pending", func() { 123 ctx := e2eutil.InitTestContext(e2eutil.Options{ 124 NodesNumLimit: 2, 125 NodesResourceLimit: corev1.ResourceList{ 126 corev1.ResourceCPU: resource.MustParse("2000m"), 127 corev1.ResourceMemory: resource.MustParse("2048Mi")}, 128 }) 129 defer e2eutil.CleanupTestContext(ctx) 130 131 pgName := "pending-pg" 132 pg := &schedulingv1beta1.PodGroup{ 133 ObjectMeta: metav1.ObjectMeta{ 134 Namespace: ctx.Namespace, 135 Name: pgName, 136 }, 137 Spec: schedulingv1beta1.PodGroupSpec{ 138 MinMember: 1, 139 MinResources: &e2eutil.ThirtyCPU, 140 }, 141 } 142 143 _, err := ctx.Vcclient.SchedulingV1beta1().PodGroups(ctx.Namespace).Create(context.TODO(), pg, metav1.CreateOptions{}) 144 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 145 146 slot1 := corev1.ResourceList{ 147 corev1.ResourceCPU: resource.MustParse("500m"), 148 corev1.ResourceMemory: resource.MustParse("512Mi")} 149 150 job := &e2eutil.JobSpec{ 151 Tasks: []e2eutil.TaskSpec{ 152 { 153 Img: e2eutil.DefaultNginxImage, 154 Req: slot1, 155 Min: 1, 156 Rep: 1, 157 }, 158 }, 159 } 160 161 job.Name = "j1" 162 existJob := e2eutil.CreateJob(ctx, job) 163 err = e2eutil.WaitJobReady(ctx, existJob) 164 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 165 166 job.Name = "j2" 167 allocateJob := e2eutil.CreateJobWithPodGroup(ctx, job, pgName, map[string]string{}) 168 err = e2eutil.WaitJobPending(ctx, allocateJob) 169 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 170 }) 171 172 ginkgo.It("allocate don't work when job NOT satisify predicates", func() { 173 ctx := e2eutil.InitTestContext(e2eutil.Options{ 174 NodesNumLimit: 1, 175 NodesResourceLimit: corev1.ResourceList{ 176 corev1.ResourceCPU: resource.MustParse("2000m"), 177 corev1.ResourceMemory: resource.MustParse("2048Mi")}, 178 }) 179 defer e2eutil.CleanupTestContext(ctx) 180 181 slot1 := corev1.ResourceList{ 182 corev1.ResourceCPU: resource.MustParse("500m"), 183 corev1.ResourceMemory: resource.MustParse("512Mi")} 184 185 job := &e2eutil.JobSpec{ 186 Tasks: []e2eutil.TaskSpec{ 187 { 188 Img: e2eutil.DefaultNginxImage, 189 Req: slot1, 190 Min: 1, 191 Rep: 1, 192 Labels: map[string]string{ 193 "job": "for-test-predicate", 194 }, 195 }, 196 }, 197 } 198 199 job.Name = "j1" 200 existJob := e2eutil.CreateJob(ctx, job) 201 err := e2eutil.WaitJobReady(ctx, existJob) 202 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 203 204 job.Name = "j2" 205 job.Tasks[0].Affinity = &corev1.Affinity{ 206 PodAntiAffinity: &corev1.PodAntiAffinity{ 207 RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{ 208 { 209 LabelSelector: &metav1.LabelSelector{ 210 MatchExpressions: []metav1.LabelSelectorRequirement{ 211 { 212 Key: "job", 213 Operator: metav1.LabelSelectorOpIn, 214 Values: []string{ 215 "for-test-predicate", 216 }, 217 }, 218 }, 219 }, 220 TopologyKey: corev1.LabelHostname, 221 }, 222 }, 223 }, 224 } 225 allocateJob := e2eutil.CreateJob(ctx, job) 226 err = e2eutil.WaitJobPending(ctx, allocateJob) 227 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 228 }) 229 230 ginkgo.It("allocate don't work when queue is overused", func() { 231 q1 := "q1" 232 q2 := "q2" 233 ctx := e2eutil.InitTestContext(e2eutil.Options{ 234 Queues: []string{q1, q2}, 235 NodesNumLimit: 2, 236 NodesResourceLimit: corev1.ResourceList{ 237 corev1.ResourceCPU: resource.MustParse("2000m"), 238 corev1.ResourceMemory: resource.MustParse("2048Mi")}, 239 }) 240 241 defer e2eutil.CleanupTestContext(ctx) 242 243 slot1 := corev1.ResourceList{ 244 corev1.ResourceCPU: resource.MustParse("1000m"), 245 corev1.ResourceMemory: resource.MustParse("1024Mi")} 246 slot2 := corev1.ResourceList{ 247 corev1.ResourceCPU: resource.MustParse("1000m"), 248 corev1.ResourceMemory: resource.MustParse("1024Mi")} 249 slot3 := corev1.ResourceList{ 250 corev1.ResourceCPU: resource.MustParse("500m"), 251 corev1.ResourceMemory: resource.MustParse("512Mi")} 252 slot4 := corev1.ResourceList{ 253 corev1.ResourceCPU: resource.MustParse("500m"), 254 corev1.ResourceMemory: resource.MustParse("512Mi")} 255 256 job := &e2eutil.JobSpec{ 257 Tasks: []e2eutil.TaskSpec{ 258 { 259 Img: e2eutil.DefaultNginxImage, 260 Req: slot1, 261 Min: 1, 262 Rep: 1, 263 }, 264 }, 265 } 266 267 job.Name = "j1-q1" 268 job.Queue = q1 269 queue1Job1 := e2eutil.CreateJob(ctx, job) 270 err := e2eutil.WaitJobStateReady(ctx, queue1Job1) 271 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 272 273 job.Name = "j2-q1" 274 job.Queue = q1 275 job.Tasks[0].Req = slot2 276 queue1Job2 := e2eutil.CreateJob(ctx, job) 277 err = e2eutil.WaitJobStateReady(ctx, queue1Job2) 278 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 279 280 job.Name = "j3-q2" 281 job.Queue = q2 282 job.Tasks[0].Req = slot3 283 queue2Job3 := e2eutil.CreateJob(ctx, job) 284 err = e2eutil.WaitJobStateReady(ctx, queue2Job3) 285 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 286 287 job.Name = "j4-q1" 288 job.Queue = q1 289 job.Tasks[0].Req = slot4 290 queue1Job4 := e2eutil.CreateJob(ctx, job) 291 err = e2eutil.WaitJobPending(ctx, queue1Job4) 292 gomega.Expect(err).NotTo(gomega.HaveOccurred()) 293 }) 294 })