github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/db/job_factory_test.go (about) 1 package db_test 2 3 import ( 4 "github.com/pf-qiu/concourse/v6/atc" 5 "github.com/pf-qiu/concourse/v6/atc/db" 6 . "github.com/onsi/ginkgo" 7 . "github.com/onsi/gomega" 8 . "github.com/onsi/gomega/gstruct" 9 ) 10 11 var _ = Describe("JobFactory", func() { 12 var jobFactory db.JobFactory 13 14 BeforeEach(func() { 15 jobFactory = db.NewJobFactory(dbConn, lockFactory) 16 }) 17 18 Context("when there are public and private pipelines", func() { 19 var publicPipeline db.Pipeline 20 21 BeforeEach(func() { 22 otherTeam, err := teamFactory.CreateTeam(atc.Team{Name: "other-team"}) 23 Expect(err).NotTo(HaveOccurred()) 24 25 publicPipeline, _, err = otherTeam.SavePipeline(atc.PipelineRef{Name: "public-pipeline", InstanceVars: atc.InstanceVars{"branch": "master"}}, atc.Config{ 26 Jobs: atc.JobConfigs{ 27 { 28 Name: "public-pipeline-job-1", 29 PlanSequence: []atc.Step{ 30 { 31 Config: &atc.GetStep{ 32 Name: "some-resource", 33 }, 34 }, 35 { 36 Config: &atc.GetStep{ 37 Name: "some-other-resource", 38 }, 39 }, 40 { 41 Config: &atc.PutStep{ 42 Name: "some-resource", 43 }, 44 }, 45 }, 46 }, 47 { 48 Name: "public-pipeline-job-2", 49 PlanSequence: []atc.Step{ 50 { 51 Config: &atc.GetStep{ 52 Name: "some-resource", 53 Passed: []string{"public-pipeline-job-1"}, 54 }, 55 }, 56 { 57 Config: &atc.GetStep{ 58 Name: "some-other-resource", 59 Passed: []string{"public-pipeline-job-1"}, 60 }, 61 }, 62 { 63 Config: &atc.GetStep{ 64 Name: "resource", 65 Resource: "some-resource", 66 }, 67 }, 68 { 69 Config: &atc.PutStep{ 70 Name: "resource", 71 Resource: "some-resource", 72 }, 73 }, 74 { 75 Config: &atc.PutStep{ 76 Name: "some-resource", 77 }, 78 }, 79 }, 80 }, 81 { 82 Name: "public-pipeline-job-3", 83 PlanSequence: []atc.Step{ 84 { 85 Config: &atc.GetStep{ 86 Name: "some-resource", 87 Passed: []string{"public-pipeline-job-1", "public-pipeline-job-2"}, 88 }, 89 }, 90 }, 91 }, 92 }, 93 Resources: atc.ResourceConfigs{ 94 { 95 Name: "some-resource", 96 Type: "some-type", 97 }, 98 { 99 Name: "some-other-resource", 100 Type: "some-type", 101 }, 102 }, 103 }, db.ConfigVersion(0), false) 104 Expect(err).ToNot(HaveOccurred()) 105 Expect(publicPipeline.Expose()).To(Succeed()) 106 107 _, _, err = otherTeam.SavePipeline(atc.PipelineRef{Name: "private-pipeline"}, atc.Config{ 108 Jobs: atc.JobConfigs{ 109 { 110 Name: "private-pipeline-job", 111 PlanSequence: []atc.Step{ 112 { 113 Config: &atc.GetStep{ 114 Name: "some-resource", 115 }, 116 }, 117 { 118 Config: &atc.PutStep{ 119 Name: "some-resource", 120 }, 121 }, 122 }, 123 }, 124 }, 125 Resources: atc.ResourceConfigs{ 126 { 127 Name: "some-resource", 128 Type: "some-type", 129 }, 130 }, 131 }, db.ConfigVersion(0), false) 132 Expect(err).ToNot(HaveOccurred()) 133 }) 134 135 Describe("VisibleJobs", func() { 136 It("returns jobs in the provided teams and jobs in public pipelines", func() { 137 visibleJobs, err := jobFactory.VisibleJobs([]string{"default-team"}) 138 Expect(err).ToNot(HaveOccurred()) 139 140 Expect(len(visibleJobs)).To(Equal(4)) 141 Expect(visibleJobs[0].Name).To(Equal("some-job")) 142 Expect(visibleJobs[1].Name).To(Equal("public-pipeline-job-1")) 143 Expect(visibleJobs[2].Name).To(Equal("public-pipeline-job-2")) 144 Expect(visibleJobs[3].Name).To(Equal("public-pipeline-job-3")) 145 146 Expect(visibleJobs[0].Inputs).To(BeNil()) 147 Expect(visibleJobs[1].Inputs).To(Equal([]atc.JobInputSummary{ 148 { 149 Name: "some-other-resource", 150 Resource: "some-other-resource", 151 }, 152 { 153 Name: "some-resource", 154 Resource: "some-resource", 155 }, 156 })) 157 Expect(visibleJobs[2].Inputs).To(Equal([]atc.JobInputSummary{ 158 { 159 Name: "resource", 160 Resource: "some-resource", 161 }, 162 { 163 Name: "some-other-resource", 164 Resource: "some-other-resource", 165 Passed: []string{"public-pipeline-job-1"}, 166 }, 167 { 168 Name: "some-resource", 169 Resource: "some-resource", 170 Passed: []string{"public-pipeline-job-1"}, 171 }, 172 })) 173 Expect(visibleJobs[3].Inputs).To(Equal([]atc.JobInputSummary{ 174 { 175 Name: "some-resource", 176 Resource: "some-resource", 177 Passed: []string{"public-pipeline-job-1", "public-pipeline-job-2"}, 178 }, 179 })) 180 181 Expect(visibleJobs[0].Outputs).To(BeNil()) 182 Expect(visibleJobs[1].Outputs).To(Equal([]atc.JobOutputSummary{ 183 { 184 Name: "some-resource", 185 Resource: "some-resource", 186 }, 187 })) 188 Expect(visibleJobs[2].Outputs).To(Equal([]atc.JobOutputSummary{ 189 { 190 Name: "resource", 191 Resource: "some-resource", 192 }, 193 { 194 Name: "some-resource", 195 Resource: "some-resource", 196 }, 197 })) 198 Expect(visibleJobs[3].Outputs).To(BeNil()) 199 }) 200 201 It("returns next build, latest completed build, and transition build for each job", func() { 202 job, found, err := defaultPipeline.Job("some-job") 203 Expect(err).ToNot(HaveOccurred()) 204 Expect(found).To(BeTrue()) 205 206 transitionBuild, err := job.CreateBuild() 207 Expect(err).ToNot(HaveOccurred()) 208 209 err = transitionBuild.Finish(db.BuildStatusSucceeded) 210 Expect(err).ToNot(HaveOccurred()) 211 212 found, err = transitionBuild.Reload() 213 Expect(err).ToNot(HaveOccurred()) 214 Expect(found).To(BeTrue()) 215 216 finishedBuild, err := job.CreateBuild() 217 Expect(err).ToNot(HaveOccurred()) 218 219 err = finishedBuild.Finish(db.BuildStatusSucceeded) 220 Expect(err).ToNot(HaveOccurred()) 221 222 found, err = finishedBuild.Reload() 223 Expect(err).ToNot(HaveOccurred()) 224 Expect(found).To(BeTrue()) 225 226 nextBuild, err := job.CreateBuild() 227 Expect(err).ToNot(HaveOccurred()) 228 229 visibleJobs, err := jobFactory.VisibleJobs([]string{"default-team"}) 230 Expect(err).ToNot(HaveOccurred()) 231 232 Expect(visibleJobs[0].Name).To(Equal("some-job")) 233 Expect(visibleJobs[0].NextBuild.ID).To(Equal(nextBuild.ID())) 234 Expect(visibleJobs[0].NextBuild.Name).To(Equal(nextBuild.Name())) 235 Expect(visibleJobs[0].NextBuild.JobName).To(Equal(nextBuild.JobName())) 236 Expect(visibleJobs[0].NextBuild.PipelineID).To(Equal(nextBuild.PipelineID())) 237 Expect(visibleJobs[0].NextBuild.PipelineName).To(Equal(nextBuild.PipelineName())) 238 Expect(visibleJobs[0].NextBuild.PipelineInstanceVars).To(Equal(nextBuild.PipelineInstanceVars())) 239 Expect(visibleJobs[0].NextBuild.TeamName).To(Equal(nextBuild.TeamName())) 240 Expect(visibleJobs[0].NextBuild.Status).To(Equal(atc.BuildStatus(nextBuild.Status()))) 241 Expect(visibleJobs[0].NextBuild.StartTime).To(Equal(nextBuild.StartTime().Unix())) 242 Expect(visibleJobs[0].NextBuild.EndTime).To(Equal(nextBuild.EndTime().Unix())) 243 244 Expect(visibleJobs[0].FinishedBuild.ID).To(Equal(finishedBuild.ID())) 245 Expect(visibleJobs[0].FinishedBuild.Name).To(Equal(finishedBuild.Name())) 246 Expect(visibleJobs[0].FinishedBuild.JobName).To(Equal(finishedBuild.JobName())) 247 Expect(visibleJobs[0].FinishedBuild.PipelineID).To(Equal(finishedBuild.PipelineID())) 248 Expect(visibleJobs[0].FinishedBuild.PipelineName).To(Equal(finishedBuild.PipelineName())) 249 Expect(visibleJobs[0].FinishedBuild.PipelineInstanceVars).To(Equal(finishedBuild.PipelineInstanceVars())) 250 Expect(visibleJobs[0].FinishedBuild.TeamName).To(Equal(finishedBuild.TeamName())) 251 Expect(visibleJobs[0].FinishedBuild.Status).To(Equal(atc.BuildStatus(finishedBuild.Status()))) 252 Expect(visibleJobs[0].FinishedBuild.StartTime).To(Equal(finishedBuild.StartTime().Unix())) 253 Expect(visibleJobs[0].FinishedBuild.EndTime).To(Equal(finishedBuild.EndTime().Unix())) 254 255 Expect(visibleJobs[0].TransitionBuild.ID).To(Equal(transitionBuild.ID())) 256 Expect(visibleJobs[0].TransitionBuild.Name).To(Equal(transitionBuild.Name())) 257 Expect(visibleJobs[0].TransitionBuild.JobName).To(Equal(transitionBuild.JobName())) 258 Expect(visibleJobs[0].TransitionBuild.PipelineID).To(Equal(transitionBuild.PipelineID())) 259 Expect(visibleJobs[0].TransitionBuild.PipelineName).To(Equal(transitionBuild.PipelineName())) 260 Expect(visibleJobs[0].TransitionBuild.PipelineInstanceVars).To(Equal(transitionBuild.PipelineInstanceVars())) 261 Expect(visibleJobs[0].TransitionBuild.TeamName).To(Equal(transitionBuild.TeamName())) 262 Expect(visibleJobs[0].TransitionBuild.Status).To(Equal(atc.BuildStatus(transitionBuild.Status()))) 263 Expect(visibleJobs[0].TransitionBuild.StartTime).To(Equal(transitionBuild.StartTime().Unix())) 264 Expect(visibleJobs[0].TransitionBuild.EndTime).To(Equal(transitionBuild.EndTime().Unix())) 265 }) 266 }) 267 268 Describe("AllActiveJobs", func() { 269 It("return all private and public pipelines", func() { 270 allJobs, err := jobFactory.AllActiveJobs() 271 Expect(err).ToNot(HaveOccurred()) 272 273 Expect(len(allJobs)).To(Equal(5)) 274 Expect(allJobs[0].Name).To(Equal("some-job")) 275 Expect(allJobs[1].Name).To(Equal("public-pipeline-job-1")) 276 Expect(allJobs[2].Name).To(Equal("public-pipeline-job-2")) 277 Expect(allJobs[3].Name).To(Equal("public-pipeline-job-3")) 278 Expect(allJobs[4].Name).To(Equal("private-pipeline-job")) 279 280 Expect(allJobs[0].Inputs).To(BeNil()) 281 Expect(allJobs[1].Inputs).To(Equal([]atc.JobInputSummary{ 282 { 283 Name: "some-other-resource", 284 Resource: "some-other-resource", 285 }, 286 { 287 Name: "some-resource", 288 Resource: "some-resource", 289 }, 290 })) 291 Expect(allJobs[2].Inputs).To(Equal([]atc.JobInputSummary{ 292 { 293 Name: "resource", 294 Resource: "some-resource", 295 }, 296 { 297 Name: "some-other-resource", 298 Resource: "some-other-resource", 299 Passed: []string{"public-pipeline-job-1"}, 300 }, 301 { 302 Name: "some-resource", 303 Resource: "some-resource", 304 Passed: []string{"public-pipeline-job-1"}, 305 }, 306 })) 307 Expect(allJobs[3].Inputs).To(Equal([]atc.JobInputSummary{ 308 { 309 Name: "some-resource", 310 Resource: "some-resource", 311 Passed: []string{"public-pipeline-job-1", "public-pipeline-job-2"}, 312 }, 313 })) 314 Expect(allJobs[4].Inputs).To(Equal([]atc.JobInputSummary{ 315 { 316 Name: "some-resource", 317 Resource: "some-resource", 318 }, 319 })) 320 321 Expect(allJobs[0].Outputs).To(BeNil()) 322 Expect(allJobs[1].Outputs).To(Equal([]atc.JobOutputSummary{ 323 { 324 Name: "some-resource", 325 Resource: "some-resource", 326 }, 327 })) 328 Expect(allJobs[2].Outputs).To(Equal([]atc.JobOutputSummary{ 329 { 330 Name: "resource", 331 Resource: "some-resource", 332 }, 333 { 334 Name: "some-resource", 335 Resource: "some-resource", 336 }, 337 })) 338 Expect(allJobs[3].Outputs).To(BeNil()) 339 Expect(allJobs[4].Outputs).To(Equal([]atc.JobOutputSummary{ 340 { 341 Name: "some-resource", 342 Resource: "some-resource", 343 }, 344 })) 345 }) 346 }) 347 }) 348 349 Describe("JobsToSchedule", func() { 350 var ( 351 job1 db.Job 352 job2 db.Job 353 job3 db.Job 354 ) 355 356 BeforeEach(func() { 357 err := defaultPipeline.Destroy() 358 Expect(err).ToNot(HaveOccurred()) 359 }) 360 361 Context("when the job has a requested schedule time later than the last scheduled", func() { 362 BeforeEach(func() { 363 pipeline1, _, err := defaultTeam.SavePipeline(atc.PipelineRef{Name: "fake-pipeline"}, atc.Config{ 364 Jobs: atc.JobConfigs{ 365 {Name: "job-name"}, 366 }, 367 }, db.ConfigVersion(1), false) 368 Expect(err).ToNot(HaveOccurred()) 369 370 var found bool 371 job1, found, err = pipeline1.Job("job-name") 372 Expect(err).ToNot(HaveOccurred()) 373 Expect(found).To(BeTrue()) 374 375 err = job1.RequestSchedule() 376 Expect(err).ToNot(HaveOccurred()) 377 }) 378 379 It("fetches that job", func() { 380 jobs, err := jobFactory.JobsToSchedule() 381 Expect(err).ToNot(HaveOccurred()) 382 Expect(len(jobs)).To(Equal(1)) 383 Expect(jobs[0].Name()).To(Equal(job1.Name())) 384 }) 385 }) 386 387 Context("when the job has a requested schedule time earlier than the last scheduled", func() { 388 BeforeEach(func() { 389 pipeline1, _, err := defaultTeam.SavePipeline(atc.PipelineRef{Name: "fake-pipeline"}, atc.Config{ 390 Jobs: atc.JobConfigs{ 391 {Name: "job-name"}, 392 }, 393 }, db.ConfigVersion(1), false) 394 Expect(err).ToNot(HaveOccurred()) 395 396 var found bool 397 job1, found, err = pipeline1.Job("job-name") 398 Expect(err).ToNot(HaveOccurred()) 399 Expect(found).To(BeTrue()) 400 401 _, err = dbConn.Exec("UPDATE jobs SET last_scheduled = now() WHERE id = $1;", job1.ID()) 402 Expect(err).ToNot(HaveOccurred()) 403 }) 404 405 It("does not fetch that job", func() { 406 jobs, err := jobFactory.JobsToSchedule() 407 Expect(err).ToNot(HaveOccurred()) 408 Expect(len(jobs)).To(Equal(0)) 409 }) 410 }) 411 412 Context("when the job has a requested schedule time is the same as the last scheduled", func() { 413 BeforeEach(func() { 414 pipeline1, _, err := defaultTeam.SavePipeline(atc.PipelineRef{Name: "fake-pipeline"}, atc.Config{ 415 Jobs: atc.JobConfigs{ 416 {Name: "job-name"}, 417 }, 418 }, db.ConfigVersion(1), false) 419 Expect(err).ToNot(HaveOccurred()) 420 421 var found bool 422 job1, found, err = pipeline1.Job("job-name") 423 Expect(err).ToNot(HaveOccurred()) 424 Expect(found).To(BeTrue()) 425 426 err = job1.RequestSchedule() 427 Expect(err).ToNot(HaveOccurred()) 428 429 found, err = job1.Reload() 430 Expect(err).ToNot(HaveOccurred()) 431 Expect(found).To(BeTrue()) 432 433 err = job1.UpdateLastScheduled(job1.ScheduleRequestedTime()) 434 Expect(err).ToNot(HaveOccurred()) 435 }) 436 437 It("does not fetch that job", func() { 438 jobs, err := jobFactory.JobsToSchedule() 439 Expect(err).ToNot(HaveOccurred()) 440 Expect(len(jobs)).To(Equal(0)) 441 }) 442 }) 443 444 Context("when there are multiple jobs with different times", func() { 445 BeforeEach(func() { 446 pipeline1, _, err := defaultTeam.SavePipeline(atc.PipelineRef{Name: "fake-pipeline"}, atc.Config{ 447 Jobs: atc.JobConfigs{ 448 {Name: "job-name"}, 449 }, 450 }, db.ConfigVersion(1), false) 451 Expect(err).ToNot(HaveOccurred()) 452 453 var found bool 454 job1, found, err = pipeline1.Job("job-name") 455 Expect(err).ToNot(HaveOccurred()) 456 Expect(found).To(BeTrue()) 457 458 err = job1.RequestSchedule() 459 Expect(err).ToNot(HaveOccurred()) 460 461 team, err := teamFactory.CreateTeam(atc.Team{Name: "some-team"}) 462 Expect(err).ToNot(HaveOccurred()) 463 464 pipeline2, _, err := team.SavePipeline(atc.PipelineRef{Name: "fake-pipeline-two"}, atc.Config{ 465 Jobs: atc.JobConfigs{ 466 {Name: "job-fake"}, 467 }, 468 }, db.ConfigVersion(1), false) 469 Expect(err).ToNot(HaveOccurred()) 470 471 job2, found, err = pipeline2.Job("job-fake") 472 Expect(err).ToNot(HaveOccurred()) 473 Expect(found).To(BeTrue()) 474 475 pipeline3, _, err := team.SavePipeline(atc.PipelineRef{Name: "fake-pipeline-three"}, atc.Config{ 476 Jobs: atc.JobConfigs{ 477 {Name: "job-fake-two"}, 478 }, 479 }, db.ConfigVersion(1), false) 480 Expect(err).ToNot(HaveOccurred()) 481 482 job3, found, err = pipeline3.Job("job-fake-two") 483 Expect(err).ToNot(HaveOccurred()) 484 Expect(found).To(BeTrue()) 485 486 _, err = dbConn.Exec("UPDATE jobs SET last_scheduled = now() WHERE id = $1;", job2.ID()) 487 Expect(err).ToNot(HaveOccurred()) 488 489 err = job3.RequestSchedule() 490 Expect(err).ToNot(HaveOccurred()) 491 }) 492 493 It("fetches the jobs that have a requested schedule time later than it's last scheduled", func() { 494 jobs, err := jobFactory.JobsToSchedule() 495 Expect(err).ToNot(HaveOccurred()) 496 Expect(len(jobs)).To(Equal(2)) 497 jobNames := []string{jobs[0].Name(), jobs[1].Name()} 498 Expect(jobNames).To(ConsistOf(job1.Name(), job3.Name())) 499 }) 500 }) 501 502 Context("when the job is paused but has a later schedule requested time", func() { 503 BeforeEach(func() { 504 pipeline1, _, err := defaultTeam.SavePipeline(atc.PipelineRef{Name: "fake-pipeline"}, atc.Config{ 505 Jobs: atc.JobConfigs{ 506 {Name: "job-name"}, 507 }, 508 }, db.ConfigVersion(1), false) 509 Expect(err).ToNot(HaveOccurred()) 510 511 var found bool 512 job1, found, err = pipeline1.Job("job-name") 513 Expect(err).ToNot(HaveOccurred()) 514 Expect(found).To(BeTrue()) 515 516 err = job1.RequestSchedule() 517 Expect(err).ToNot(HaveOccurred()) 518 519 err = job1.Pause() 520 Expect(err).ToNot(HaveOccurred()) 521 }) 522 523 It("does not fetch that job", func() { 524 jobs, err := jobFactory.JobsToSchedule() 525 Expect(err).ToNot(HaveOccurred()) 526 Expect(len(jobs)).To(Equal(0)) 527 }) 528 }) 529 530 Context("when the job is inactive but has a later schedule requested time", func() { 531 BeforeEach(func() { 532 pipeline1, _, err := defaultTeam.SavePipeline(atc.PipelineRef{Name: "fake-pipeline"}, atc.Config{ 533 Jobs: atc.JobConfigs{ 534 {Name: "job-name"}, 535 }, 536 }, db.ConfigVersion(1), false) 537 Expect(err).ToNot(HaveOccurred()) 538 539 var found bool 540 job1, found, err = pipeline1.Job("job-name") 541 Expect(err).ToNot(HaveOccurred()) 542 Expect(found).To(BeTrue()) 543 544 err = job1.RequestSchedule() 545 Expect(err).ToNot(HaveOccurred()) 546 547 _, _, err = defaultTeam.SavePipeline(atc.PipelineRef{Name: "fake-pipeline"}, atc.Config{}, pipeline1.ConfigVersion(), false) 548 Expect(err).ToNot(HaveOccurred()) 549 }) 550 551 It("does not fetch that job", func() { 552 jobs, err := jobFactory.JobsToSchedule() 553 Expect(err).ToNot(HaveOccurred()) 554 Expect(len(jobs)).To(Equal(0)) 555 }) 556 }) 557 558 Context("when the pipeline is paused but it's job has a later schedule requested time", func() { 559 BeforeEach(func() { 560 pipeline1, _, err := defaultTeam.SavePipeline(atc.PipelineRef{Name: "fake-pipeline"}, atc.Config{ 561 Jobs: atc.JobConfigs{ 562 {Name: "job-name"}, 563 }, 564 }, db.ConfigVersion(1), false) 565 Expect(err).ToNot(HaveOccurred()) 566 567 var found bool 568 job1, found, err = pipeline1.Job("job-name") 569 Expect(err).ToNot(HaveOccurred()) 570 Expect(found).To(BeTrue()) 571 572 err = job1.RequestSchedule() 573 Expect(err).ToNot(HaveOccurred()) 574 575 err = pipeline1.Pause() 576 Expect(err).ToNot(HaveOccurred()) 577 }) 578 579 It("does not fetch that job", func() { 580 jobs, err := jobFactory.JobsToSchedule() 581 Expect(err).ToNot(HaveOccurred()) 582 Expect(len(jobs)).To(Equal(0)) 583 }) 584 }) 585 586 Describe("scheduler jobs resources", func() { 587 Context("when the job needed to be schedule has no resources", func() { 588 BeforeEach(func() { 589 pipeline1, _, err := defaultTeam.SavePipeline(atc.PipelineRef{Name: "fake-pipeline"}, atc.Config{ 590 Jobs: atc.JobConfigs{ 591 {Name: "job-name"}, 592 }, 593 }, db.ConfigVersion(1), false) 594 Expect(err).ToNot(HaveOccurred()) 595 596 var found bool 597 job1, found, err = pipeline1.Job("job-name") 598 Expect(err).ToNot(HaveOccurred()) 599 Expect(found).To(BeTrue()) 600 601 err = job1.RequestSchedule() 602 Expect(err).ToNot(HaveOccurred()) 603 }) 604 605 It("fetches that job and no resources", func() { 606 jobs, err := jobFactory.JobsToSchedule() 607 Expect(err).ToNot(HaveOccurred()) 608 Expect(len(jobs)).To(Equal(1)) 609 Expect(jobs[0].Name()).To(Equal(job1.Name())) 610 Expect(jobs[0].Resources).To(BeNil()) 611 }) 612 }) 613 614 Context("when the job needed to be schedule uses resources", func() { 615 BeforeEach(func() { 616 pipeline1, _, err := defaultTeam.SavePipeline(atc.PipelineRef{Name: "fake-pipeline"}, atc.Config{ 617 Jobs: atc.JobConfigs{ 618 { 619 Name: "job-name", 620 PlanSequence: []atc.Step{ 621 { 622 Config: &atc.GetStep{ 623 Name: "some-resource", 624 }, 625 }, 626 }, 627 }, 628 }, 629 630 Resources: atc.ResourceConfigs{ 631 { 632 Name: "some-resource", 633 Type: "some-type", 634 Source: atc.Source{ 635 "some": "source", 636 }, 637 }, 638 { 639 Name: "unused-resource", 640 }, 641 }, 642 }, db.ConfigVersion(1), false) 643 Expect(err).ToNot(HaveOccurred()) 644 645 var found bool 646 job1, found, err = pipeline1.Job("job-name") 647 Expect(err).ToNot(HaveOccurred()) 648 Expect(found).To(BeTrue()) 649 650 err = job1.RequestSchedule() 651 Expect(err).ToNot(HaveOccurred()) 652 }) 653 654 It("fetches that job and the used resource", func() { 655 jobs, err := jobFactory.JobsToSchedule() 656 Expect(err).ToNot(HaveOccurred()) 657 Expect(len(jobs)).To(Equal(1)) 658 Expect(jobs[0].Name()).To(Equal(job1.Name())) 659 Expect(jobs[0].Resources).To(HaveLen(1)) 660 Expect(jobs[0].Resources).To(ConsistOf( 661 db.SchedulerResource{ 662 Name: "some-resource", 663 Type: "some-type", 664 Source: atc.Source{"some": "source"}, 665 }, 666 )) 667 }) 668 }) 669 670 Context("when multiple jobs needed to be schedule uses resources", func() { 671 BeforeEach(func() { 672 pipeline1, _, err := defaultTeam.SavePipeline(atc.PipelineRef{Name: "fake-pipeline"}, atc.Config{ 673 Jobs: atc.JobConfigs{ 674 { 675 Name: "job-1", 676 PlanSequence: []atc.Step{ 677 { 678 Config: &atc.GetStep{ 679 Name: "some-resource", 680 }, 681 }, 682 }, 683 }, 684 { 685 Name: "job-2", 686 PlanSequence: []atc.Step{ 687 { 688 Config: &atc.GetStep{ 689 Name: "some-resource", 690 }, 691 }, 692 { 693 Config: &atc.GetStep{ 694 Name: "other-resource", 695 }, 696 }, 697 }, 698 }, 699 }, 700 701 Resources: atc.ResourceConfigs{ 702 { 703 Name: "some-resource", 704 Type: "some-type", 705 }, 706 { 707 Name: "other-resource", 708 Type: "some-type", 709 }, 710 { 711 Name: "unused-resource", 712 Type: "some-type", 713 }, 714 }, 715 }, db.ConfigVersion(1), false) 716 Expect(err).ToNot(HaveOccurred()) 717 718 pipeline2, _, err := defaultTeam.SavePipeline(atc.PipelineRef{Name: "fake-pipeline-2"}, atc.Config{ 719 Jobs: atc.JobConfigs{ 720 { 721 Name: "job-3", 722 PlanSequence: []atc.Step{ 723 { 724 Config: &atc.GetStep{ 725 Name: "some-resource", 726 }, 727 }, 728 { 729 Config: &atc.GetStep{ 730 Name: "some-resource-2", 731 }, 732 }, 733 }, 734 }, 735 }, 736 737 Resources: atc.ResourceConfigs{ 738 { 739 Name: "some-resource", 740 Type: "other-type", 741 }, 742 { 743 Name: "some-resource-2", 744 Type: "other-type", 745 }, 746 }, 747 }, db.ConfigVersion(1), false) 748 Expect(err).ToNot(HaveOccurred()) 749 750 var found bool 751 job1, found, err = pipeline1.Job("job-1") 752 Expect(err).ToNot(HaveOccurred()) 753 Expect(found).To(BeTrue()) 754 755 job2, found, err = pipeline1.Job("job-2") 756 Expect(err).ToNot(HaveOccurred()) 757 Expect(found).To(BeTrue()) 758 759 job3, found, err = pipeline2.Job("job-3") 760 Expect(err).ToNot(HaveOccurred()) 761 Expect(found).To(BeTrue()) 762 763 err = job1.RequestSchedule() 764 Expect(err).ToNot(HaveOccurred()) 765 766 err = job2.RequestSchedule() 767 Expect(err).ToNot(HaveOccurred()) 768 769 err = job3.RequestSchedule() 770 Expect(err).ToNot(HaveOccurred()) 771 }) 772 773 It("fetches that job and the used resource", func() { 774 jobs, err := jobFactory.JobsToSchedule() 775 Expect(err).ToNot(HaveOccurred()) 776 777 jobResources := make(map[string]db.SchedulerResources) 778 for _, job := range jobs { 779 jobResources[job.Name()] = job.Resources 780 } 781 782 Expect(jobResources).To(MatchAllKeys(Keys{ 783 job1.Name(): ConsistOf( 784 db.SchedulerResource{ 785 Name: "some-resource", 786 Type: "some-type", 787 }, 788 ), 789 job2.Name(): ConsistOf( 790 db.SchedulerResource{ 791 Name: "some-resource", 792 Type: "some-type", 793 }, 794 db.SchedulerResource{ 795 Name: "other-resource", 796 Type: "some-type", 797 }), 798 job3.Name(): ConsistOf( 799 db.SchedulerResource{ 800 Name: "some-resource", 801 Type: "other-type", 802 }, 803 db.SchedulerResource{ 804 Name: "some-resource-2", 805 Type: "other-type", 806 }), 807 })) 808 }) 809 }) 810 811 Context("when the job needed to be schedule uses resources as puts", func() { 812 BeforeEach(func() { 813 pipeline1, _, err := defaultTeam.SavePipeline(atc.PipelineRef{Name: "fake-pipeline"}, atc.Config{ 814 Jobs: atc.JobConfigs{ 815 { 816 Name: "job-name", 817 PlanSequence: []atc.Step{ 818 { 819 Config: &atc.PutStep{ 820 Name: "some-resource", 821 }, 822 }, 823 }, 824 }, 825 }, 826 827 Resources: atc.ResourceConfigs{ 828 { 829 Name: "some-resource", 830 Type: "some-type", 831 Source: atc.Source{ 832 "some": "source", 833 }, 834 }, 835 { 836 Name: "unused-resource", 837 }, 838 }, 839 }, db.ConfigVersion(1), false) 840 Expect(err).ToNot(HaveOccurred()) 841 842 var found bool 843 job1, found, err = pipeline1.Job("job-name") 844 Expect(err).ToNot(HaveOccurred()) 845 Expect(found).To(BeTrue()) 846 847 err = job1.RequestSchedule() 848 Expect(err).ToNot(HaveOccurred()) 849 }) 850 851 It("fetches that job and the used resource", func() { 852 jobs, err := jobFactory.JobsToSchedule() 853 Expect(err).ToNot(HaveOccurred()) 854 Expect(len(jobs)).To(Equal(1)) 855 Expect(jobs[0].Name()).To(Equal(job1.Name())) 856 Expect(jobs[0].Resources).To(ConsistOf( 857 db.SchedulerResource{ 858 Name: "some-resource", 859 Type: "some-type", 860 Source: atc.Source{"some": "source"}, 861 }, 862 )) 863 }) 864 }) 865 866 Context("when the job needed to be schedule uses the resource as a put and a get", func() { 867 BeforeEach(func() { 868 pipeline1, _, err := defaultTeam.SavePipeline(atc.PipelineRef{Name: "fake-pipeline"}, atc.Config{ 869 Jobs: atc.JobConfigs{ 870 { 871 Name: "job-name", 872 PlanSequence: []atc.Step{ 873 { 874 Config: &atc.GetStep{ 875 Name: "some-resource", 876 }, 877 }, 878 { 879 Config: &atc.PutStep{ 880 Name: "some-resource", 881 }, 882 }, 883 }, 884 }, 885 }, 886 887 Resources: atc.ResourceConfigs{ 888 { 889 Name: "some-resource", 890 Type: "some-type", 891 Source: atc.Source{ 892 "some": "source", 893 }, 894 }, 895 { 896 Name: "unused-resource", 897 }, 898 }, 899 }, db.ConfigVersion(1), false) 900 Expect(err).ToNot(HaveOccurred()) 901 902 var found bool 903 job1, found, err = pipeline1.Job("job-name") 904 Expect(err).ToNot(HaveOccurred()) 905 Expect(found).To(BeTrue()) 906 907 err = job1.RequestSchedule() 908 Expect(err).ToNot(HaveOccurred()) 909 }) 910 911 It("fetches that job and the used resource", func() { 912 jobs, err := jobFactory.JobsToSchedule() 913 Expect(err).ToNot(HaveOccurred()) 914 Expect(len(jobs)).To(Equal(1)) 915 Expect(jobs[0].Name()).To(Equal(job1.Name())) 916 Expect(jobs[0].Resources).To(ConsistOf( 917 db.SchedulerResource{ 918 Name: "some-resource", 919 Type: "some-type", 920 Source: atc.Source{"some": "source"}, 921 }, 922 )) 923 }) 924 }) 925 }) 926 927 Describe("schedule jobs resource types", func() { 928 Context("when the pipeline for the job needed to be scheduled uses custom resource types", func() { 929 BeforeEach(func() { 930 pipeline1, _, err := defaultTeam.SavePipeline(atc.PipelineRef{Name: "fake-pipeline"}, atc.Config{ 931 Jobs: atc.JobConfigs{ 932 {Name: "job-name"}, 933 }, 934 ResourceTypes: atc.ResourceTypes{ 935 { 936 Name: "some-type", 937 Type: "other-type", 938 }, 939 }, 940 }, db.ConfigVersion(1), false) 941 Expect(err).ToNot(HaveOccurred()) 942 943 var found bool 944 job1, found, err = pipeline1.Job("job-name") 945 Expect(err).ToNot(HaveOccurred()) 946 Expect(found).To(BeTrue()) 947 948 err = job1.RequestSchedule() 949 Expect(err).ToNot(HaveOccurred()) 950 }) 951 952 It("fetches that job and resource type", func() { 953 jobs, err := jobFactory.JobsToSchedule() 954 Expect(err).ToNot(HaveOccurred()) 955 Expect(len(jobs)).To(Equal(1)) 956 Expect(jobs[0].Name()).To(Equal(job1.Name())) 957 Expect(jobs[0].ResourceTypes).To(ConsistOf( 958 atc.VersionedResourceType{ 959 ResourceType: atc.ResourceType{ 960 Name: "some-type", 961 Type: "other-type", 962 }, 963 }, 964 )) 965 }) 966 }) 967 968 Context("when multiple job from different pipelines uses custom resource types", func() { 969 BeforeEach(func() { 970 pipeline1, _, err := defaultTeam.SavePipeline(atc.PipelineRef{Name: "fake-pipeline"}, atc.Config{ 971 Jobs: atc.JobConfigs{ 972 {Name: "job-1"}, 973 {Name: "job-2"}, 974 }, 975 ResourceTypes: atc.ResourceTypes{ 976 { 977 Name: "some-type", 978 Type: "other-type", 979 }, 980 }, 981 }, db.ConfigVersion(1), false) 982 Expect(err).ToNot(HaveOccurred()) 983 984 pipeline2, _, err := defaultTeam.SavePipeline(atc.PipelineRef{Name: "fake-pipeline-2"}, atc.Config{ 985 Jobs: atc.JobConfigs{ 986 {Name: "job-3"}, 987 }, 988 ResourceTypes: atc.ResourceTypes{ 989 { 990 Name: "some-type-1", 991 Type: "other-type-1", 992 }, 993 { 994 Name: "some-type-2", 995 Type: "other-type-2", 996 }, 997 }, 998 }, db.ConfigVersion(1), false) 999 Expect(err).ToNot(HaveOccurred()) 1000 1001 var found bool 1002 job1, found, err = pipeline1.Job("job-1") 1003 Expect(err).ToNot(HaveOccurred()) 1004 Expect(found).To(BeTrue()) 1005 1006 err = job1.RequestSchedule() 1007 Expect(err).ToNot(HaveOccurred()) 1008 1009 job2, found, err = pipeline1.Job("job-2") 1010 Expect(err).ToNot(HaveOccurred()) 1011 Expect(found).To(BeTrue()) 1012 1013 err = job2.RequestSchedule() 1014 Expect(err).ToNot(HaveOccurred()) 1015 1016 job3, found, err = pipeline2.Job("job-3") 1017 Expect(err).ToNot(HaveOccurred()) 1018 Expect(found).To(BeTrue()) 1019 1020 err = job3.RequestSchedule() 1021 Expect(err).ToNot(HaveOccurred()) 1022 }) 1023 1024 It("fetches all jobs and resource types", func() { 1025 jobs, err := jobFactory.JobsToSchedule() 1026 Expect(err).ToNot(HaveOccurred()) 1027 1028 jobResourceTypes := make(map[string]atc.VersionedResourceTypes) 1029 for _, job := range jobs { 1030 jobResourceTypes[job.Name()] = job.ResourceTypes 1031 } 1032 1033 Expect(jobResourceTypes).To(MatchAllKeys(Keys{ 1034 job1.Name(): ConsistOf( 1035 atc.VersionedResourceType{ 1036 ResourceType: atc.ResourceType{ 1037 Name: "some-type", 1038 Type: "other-type", 1039 }, 1040 }, 1041 ), 1042 job2.Name(): ConsistOf( 1043 atc.VersionedResourceType{ 1044 ResourceType: atc.ResourceType{ 1045 Name: "some-type", 1046 Type: "other-type", 1047 }, 1048 }, 1049 ), 1050 job3.Name(): ConsistOf( 1051 atc.VersionedResourceType{ 1052 ResourceType: atc.ResourceType{ 1053 Name: "some-type-1", 1054 Type: "other-type-1", 1055 }, 1056 }, 1057 atc.VersionedResourceType{ 1058 ResourceType: atc.ResourceType{ 1059 Name: "some-type-2", 1060 Type: "other-type-2", 1061 }, 1062 }, 1063 ), 1064 })) 1065 }) 1066 }) 1067 }) 1068 }) 1069 }) 1070 1071 var _ = Context("SchedulerResource", func() { 1072 var resource db.SchedulerResource 1073 1074 BeforeEach(func() { 1075 resource = db.SchedulerResource{ 1076 Name: "some-name", 1077 Type: "some-type", 1078 Source: atc.Source{ 1079 "some-key": "some-value", 1080 }, 1081 } 1082 }) 1083 1084 Context("ApplySourceDefaults", func() { 1085 var resourceTypes atc.VersionedResourceTypes 1086 1087 BeforeEach(func() { 1088 resourceTypes = atc.VersionedResourceTypes{ 1089 { 1090 ResourceType: atc.ResourceType{ 1091 Name: "some-type", 1092 Defaults: atc.Source{"default-key": "default-value"}, 1093 }, 1094 }, 1095 } 1096 }) 1097 1098 JustBeforeEach(func() { 1099 resource.ApplySourceDefaults(resourceTypes) 1100 }) 1101 1102 It("should apply defaults", func() { 1103 Expect(resource).To(Equal(db.SchedulerResource{ 1104 Name: "some-name", 1105 Type: "some-type", 1106 Source: atc.Source{ 1107 "some-key": "some-value", 1108 "default-key": "default-value", 1109 }, 1110 })) 1111 }) 1112 1113 Context("when the parent resource is not found", func() { 1114 BeforeEach(func() { 1115 resourceTypes = atc.VersionedResourceTypes{} 1116 atc.LoadBaseResourceTypeDefaults(map[string]atc.Source{ 1117 "some-type": {"default-key": "default-value"}, 1118 }) 1119 }) 1120 1121 AfterEach(func() { 1122 atc.LoadBaseResourceTypeDefaults(map[string]atc.Source{}) 1123 }) 1124 1125 It("should apply defaults using the base resource type", func() { 1126 Expect(resource).To(Equal(db.SchedulerResource{ 1127 Name: "some-name", 1128 Type: "some-type", 1129 Source: atc.Source{ 1130 "some-key": "some-value", 1131 "default-key": "default-value", 1132 }, 1133 })) 1134 }) 1135 }) 1136 }) 1137 })