github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/scheduler/algorithm/algorithm_test.go (about) 1 package algorithm_test 2 3 import ( 4 . "github.com/onsi/ginkgo/extensions/table" 5 ) 6 7 var _ = DescribeTable("Input resolving", 8 (Example).Run, 9 10 Entry("can fan-in", Example{ 11 DB: DB{ 12 BuildOutputs: []DBRow{ 13 // pass a and b 14 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 15 {Job: "simple-b", BuildID: 2, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 16 17 // pass a but not b 18 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 19 }, 20 }, 21 22 Inputs: Inputs{ 23 { 24 Name: "resource-x", 25 Resource: "resource-x", 26 Passed: []string{"simple-a", "simple-b"}, 27 }, 28 }, 29 30 // no v2 as it hasn't passed b 31 Result: Result{ 32 OK: true, 33 Values: map[string]string{ 34 "resource-x": "rxv1", 35 }, 36 }, 37 }), 38 39 Entry("propagates resources together", Example{ 40 DB: DB{ 41 BuildOutputs: []DBRow{ 42 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 43 {Job: "simple-a", BuildID: 1, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 44 }, 45 }, 46 47 Inputs: Inputs{ 48 {Name: "resource-x", Resource: "resource-x", Passed: []string{"simple-a"}}, 49 {Name: "resource-y", Resource: "resource-y", Passed: []string{"simple-a"}}, 50 }, 51 52 Result: Result{ 53 OK: true, 54 Values: map[string]string{ 55 "resource-x": "rxv1", 56 "resource-y": "ryv1", 57 }, 58 }, 59 }), 60 61 Entry("correlates inputs by build, allowing resources to skip jobs", Example{ 62 DB: DB{ 63 BuildOutputs: []DBRow{ 64 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 65 {Job: "simple-a", BuildID: 1, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 66 67 {Job: "fan-in", BuildID: 3, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 68 69 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 70 {Job: "simple-a", BuildID: 4, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 71 }, 72 }, 73 74 Inputs: Inputs{ 75 {Name: "resource-x", Resource: "resource-x", Passed: []string{"simple-a", "fan-in"}}, 76 {Name: "resource-y", Resource: "resource-y", Passed: []string{"simple-a"}}, 77 }, 78 79 Result: Result{ 80 OK: true, 81 Values: map[string]string{ 82 "resource-x": "rxv1", 83 84 // not ryv2, as it didn't make it through build relating simple-a to fan-in 85 "resource-y": "ryv1", 86 }, 87 }, 88 }), 89 90 Entry("resolve a resource when it has versions", Example{ 91 DB: DB{ 92 Resources: []DBRow{ 93 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 94 }, 95 }, 96 97 Inputs: Inputs{ 98 { 99 Name: "resource-x", 100 Resource: "resource-x", 101 Version: Version{Latest: true}, 102 }, 103 }, 104 105 Result: Result{ 106 OK: true, 107 Values: map[string]string{ 108 "resource-x": "rxv1", 109 }, 110 }, 111 }), 112 113 Entry("does not resolve a resource when it does not have any versions", Example{ 114 Inputs: Inputs{ 115 { 116 Name: "resource-x", 117 Resource: "resource-x", 118 Version: Version{Pinned: "rxv2"}, 119 }, 120 }, 121 122 Result: Result{ 123 OK: false, 124 Errors: map[string]string{"resource-x": "pinned version ver:rxv2 not found"}, 125 }, 126 }), 127 128 Entry("finds only versions that passed through together", Example{ 129 DB: DB{ 130 BuildOutputs: []DBRow{ 131 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 132 {Job: "simple-a", BuildID: 1, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 133 {Job: "simple-b", BuildID: 2, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 134 {Job: "simple-b", BuildID: 2, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 135 136 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 2}, 137 {Job: "simple-a", BuildID: 3, Resource: "resource-y", Version: "ryv3", CheckOrder: 2}, 138 {Job: "simple-b", BuildID: 4, Resource: "resource-x", Version: "rxv3", CheckOrder: 2}, 139 {Job: "simple-b", BuildID: 4, Resource: "resource-y", Version: "ryv3", CheckOrder: 2}, 140 141 {Job: "simple-a", BuildID: 5, Resource: "resource-x", Version: "rxv2", CheckOrder: 1}, 142 {Job: "simple-a", BuildID: 5, Resource: "resource-y", Version: "ryv4", CheckOrder: 1}, 143 144 {Job: "simple-b", BuildID: 6, Resource: "resource-x", Version: "rxv4", CheckOrder: 1}, 145 {Job: "simple-b", BuildID: 6, Resource: "resource-y", Version: "rxv4", CheckOrder: 1}, 146 147 {Job: "simple-b", BuildID: 7, Resource: "resource-x", Version: "rxv4", CheckOrder: 1}, 148 {Job: "simple-b", BuildID: 7, Resource: "resource-y", Version: "rxv2", CheckOrder: 1}, 149 }, 150 }, 151 152 Inputs: Inputs{ 153 {Name: "resource-x", Resource: "resource-x", Passed: []string{"simple-a", "simple-b"}}, 154 {Name: "resource-y", Resource: "resource-y", Passed: []string{"simple-a", "simple-b"}}, 155 }, 156 157 Result: Result{ 158 OK: true, 159 Values: map[string]string{ 160 "resource-x": "rxv3", 161 "resource-y": "ryv3", 162 }, 163 PassedBuildIDs: map[string][]int{ 164 "resource-x": []int{3, 4}, 165 "resource-y": []int{3, 4}, 166 }, 167 }, 168 }), 169 170 Entry("can collect distinct versions of resources without correlating by job", Example{ 171 DB: DB{ 172 BuildOutputs: []DBRow{ 173 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 174 {Job: "simple-b", BuildID: 2, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 175 {Job: "simple-b", BuildID: 3, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 176 }, 177 }, 178 179 Inputs: Inputs{ 180 {Name: "simple-a-resource-x", Resource: "resource-x", Passed: []string{"simple-a"}}, 181 {Name: "simple-b-resource-x", Resource: "resource-x", Passed: []string{"simple-b"}}, 182 }, 183 184 Result: Result{ 185 OK: true, 186 Values: map[string]string{ 187 "simple-a-resource-x": "rxv1", 188 "simple-b-resource-x": "rxv2", 189 }, 190 }, 191 }), 192 193 Entry("resolves passed constraints with common jobs", Example{ 194 DB: DB{ 195 BuildOutputs: []DBRow{ 196 {Job: "shared-job", BuildID: 1, Resource: "resource-1", Version: "r1-common-to-shared-and-j1", CheckOrder: 1}, 197 {Job: "shared-job", BuildID: 1, Resource: "resource-2", Version: "r2-common-to-shared-and-j2", CheckOrder: 1}, 198 {Job: "job-1", BuildID: 2, Resource: "resource-1", Version: "r1-common-to-shared-and-j1", CheckOrder: 1}, 199 {Job: "job-2", BuildID: 3, Resource: "resource-2", Version: "r2-common-to-shared-and-j2", CheckOrder: 1}, 200 }, 201 }, 202 203 Inputs: Inputs{ 204 { 205 Name: "input-1", 206 Resource: "resource-1", 207 Passed: []string{"shared-job", "job-1"}, 208 }, 209 { 210 Name: "input-2", 211 Resource: "resource-2", 212 Passed: []string{"shared-job", "job-2"}, 213 }, 214 }, 215 216 Result: Result{ 217 OK: true, 218 Values: map[string]string{ 219 "input-1": "r1-common-to-shared-and-j1", 220 "input-2": "r2-common-to-shared-and-j2", 221 }, 222 }, 223 }), 224 225 Entry("resolves passed constraints with common jobs, skipping versions that are not common to builds of all jobs", Example{ 226 DB: DB{ 227 BuildOutputs: []DBRow{ 228 {Job: "shared-job", BuildID: 1, Resource: "resource-1", Version: "r1-common-to-shared-and-j1", CheckOrder: 1}, 229 {Job: "shared-job", BuildID: 1, Resource: "resource-2", Version: "r2-common-to-shared-and-j2", CheckOrder: 1}, 230 {Job: "job-1", BuildID: 2, Resource: "resource-1", Version: "r1-common-to-shared-and-j1", CheckOrder: 1}, 231 {Job: "job-2", BuildID: 3, Resource: "resource-2", Version: "r2-common-to-shared-and-j2", CheckOrder: 1}, 232 233 {Job: "shared-job", BuildID: 4, Resource: "resource-1", Version: "new-r1-common-to-shared-and-j1", CheckOrder: 2}, 234 {Job: "shared-job", BuildID: 4, Resource: "resource-2", Version: "new-r2-common-to-shared-and-j2", CheckOrder: 2}, 235 {Job: "job-1", BuildID: 5, Resource: "resource-1", Version: "new-r1-common-to-shared-and-j1", CheckOrder: 2}, 236 }, 237 }, 238 239 Inputs: Inputs{ 240 { 241 Name: "input-1", 242 Resource: "resource-1", 243 Passed: []string{"shared-job", "job-1"}, 244 }, 245 { 246 Name: "input-2", 247 Resource: "resource-2", 248 Passed: []string{"shared-job", "job-2"}, 249 }, 250 }, 251 252 Result: Result{ 253 OK: true, 254 Values: map[string]string{ 255 "input-1": "r1-common-to-shared-and-j1", 256 "input-2": "r2-common-to-shared-and-j2", 257 }, 258 }, 259 }), 260 261 Entry("finds the latest version for inputs with no passed constraints", Example{ 262 DB: DB{ 263 BuildOutputs: []DBRow{ 264 // build outputs 265 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 266 {Job: "simple-a", BuildID: 1, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 267 }, 268 269 Resources: []DBRow{ 270 // the versions themselves 271 // note: normally there's one of these for each version, including ones 272 // that appear as outputs 273 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 274 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 275 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 276 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 277 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 278 {Resource: "resource-y", Version: "ryv4", CheckOrder: 4}, 279 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 280 {Resource: "resource-y", Version: "ryv5", CheckOrder: 5}, 281 {Resource: "resource-x", Version: "rxv5", CheckOrder: 5}, 282 }, 283 }, 284 285 Inputs: Inputs{ 286 { 287 Name: "resource-x", 288 Resource: "resource-x", 289 Passed: []string{"simple-a"}, 290 }, 291 { 292 Name: "resource-x-unconstrained", 293 Resource: "resource-x", 294 }, 295 { 296 Name: "resource-y-unconstrained", 297 Resource: "resource-y", 298 }, 299 }, 300 301 Result: Result{ 302 OK: true, 303 Values: map[string]string{ 304 "resource-x": "rxv1", 305 "resource-x-unconstrained": "rxv5", 306 "resource-y-unconstrained": "ryv5", 307 }, 308 // IC: map[string]bool{}, 309 }, 310 }), 311 312 Entry("finds the non-disabled latest version for inputs with no passed constraints", Example{ 313 DB: DB{ 314 Resources: []DBRow{ 315 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 316 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 317 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 318 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 319 {Resource: "resource-x", Version: "rxv5", CheckOrder: 5, Disabled: true}, 320 }, 321 }, 322 323 Inputs: Inputs{ 324 { 325 Name: "resource-x", 326 Resource: "resource-x", 327 }, 328 }, 329 330 Result: Result{ 331 OK: true, 332 Values: map[string]string{ 333 "resource-x": "rxv4", 334 }, 335 }, 336 }), 337 338 Entry("returns a missing input reason when no input version satisfies the passed constraint", Example{ 339 DB: DB{ 340 BuildInputs: []DBRow{ 341 {Job: CurrentJobName, BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 342 {Job: CurrentJobName, BuildID: 1, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 343 }, 344 345 BuildOutputs: []DBRow{ 346 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 347 {Job: "simple-a", BuildID: 2, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 348 }, 349 350 Resources: []DBRow{ 351 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 352 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 353 }, 354 }, 355 356 Inputs: Inputs{ 357 { 358 Name: "resource-x", 359 Resource: "resource-x", 360 Passed: []string{"simple-a", "simple-b"}, 361 }, 362 { 363 Name: "resource-y", 364 Resource: "resource-y", 365 Passed: []string{"simple-a", "simple-b"}, 366 }, 367 }, 368 369 // only one reason since skipping algorithm if resource does not satisfy passed constraints by itself 370 Result: Result{ 371 OK: false, 372 Errors: map[string]string{ 373 "resource-x": "no satisfiable builds from passed jobs found for set of inputs", 374 "resource-y": "no satisfiable builds from passed jobs found for set of inputs", 375 }, 376 }, 377 }), 378 379 Entry("finds next version for inputs that use every version when there is a build for that resource", Example{ 380 DB: DB{ 381 BuildInputs: []DBRow{ 382 {Job: CurrentJobName, BuildID: 4, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 383 }, 384 385 Resources: []DBRow{ 386 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 387 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 388 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 389 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 390 }, 391 }, 392 393 Inputs: Inputs{ 394 { 395 Name: "resource-x", 396 Resource: "resource-x", 397 Version: Version{Every: true}, 398 }, 399 }, 400 401 Result: Result{ 402 OK: true, 403 Values: map[string]string{ 404 "resource-x": "rxv2", 405 }, 406 }, 407 }), 408 409 Entry("finds next non-disabled version for inputs that use every version when there is a build for that resource", Example{ 410 DB: DB{ 411 BuildInputs: []DBRow{ 412 {Job: CurrentJobName, BuildID: 4, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 413 }, 414 415 Resources: []DBRow{ 416 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 417 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2, Disabled: true}, 418 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 419 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 420 }, 421 }, 422 423 Inputs: Inputs{ 424 { 425 Name: "resource-x", 426 Resource: "resource-x", 427 Version: Version{Every: true}, 428 }, 429 }, 430 431 Result: Result{ 432 OK: true, 433 Values: map[string]string{ 434 "resource-x": "rxv3", 435 }, 436 }, 437 }), 438 439 Entry("finds current non-disabled version if all later versions are disabled for inputs that use every version when there is a build for that resource", Example{ 440 DB: DB{ 441 BuildInputs: []DBRow{ 442 {Job: CurrentJobName, BuildID: 4, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 443 }, 444 445 Resources: []DBRow{ 446 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 447 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 448 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 449 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4, Disabled: true}, 450 }, 451 }, 452 453 Inputs: Inputs{ 454 { 455 Name: "resource-x", 456 Resource: "resource-x", 457 Version: Version{Every: true}, 458 }, 459 }, 460 461 Result: Result{ 462 OK: true, 463 Values: map[string]string{ 464 "resource-x": "rxv3", 465 }, 466 }, 467 }), 468 469 Entry("finds last non-disabled version if all later and current versions are disabled for inputs that use every version when there is a build for that resource", Example{ 470 DB: DB{ 471 BuildInputs: []DBRow{ 472 {Job: CurrentJobName, BuildID: 4, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 473 }, 474 475 Resources: []DBRow{ 476 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 477 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 478 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3, Disabled: true}, 479 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4, Disabled: true}, 480 }, 481 }, 482 483 Inputs: Inputs{ 484 { 485 Name: "resource-x", 486 Resource: "resource-x", 487 Version: Version{Every: true}, 488 }, 489 }, 490 491 Result: Result{ 492 OK: true, 493 Values: map[string]string{ 494 "resource-x": "rxv2", 495 }, 496 }, 497 }), 498 499 Entry("finds last enabled version for inputs that use every version when there is no builds for that resource", Example{ 500 DB: DB{ 501 Resources: []DBRow{ 502 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 503 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 504 505 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 506 507 {Resource: "resource-z", Version: "rzv1", CheckOrder: 1}, 508 {Resource: "resource-z", Version: "rzv2", CheckOrder: 2, Disabled: true}, 509 }, 510 }, 511 512 Inputs: Inputs{ 513 { 514 Name: "resource-x", 515 Resource: "resource-x", 516 Version: Version{Every: true}, 517 }, 518 { 519 Name: "resource-y", 520 Resource: "resource-y", 521 Version: Version{Every: true}, 522 }, 523 { 524 Name: "resource-z", 525 Resource: "resource-z", 526 Version: Version{Every: true}, 527 }, 528 }, 529 530 Result: Result{ 531 OK: true, 532 Values: map[string]string{ 533 "resource-x": "rxv2", 534 "resource-y": "ryv1", 535 "resource-z": "rzv1", 536 }, 537 }, 538 }), 539 540 Entry("finds last version for inputs that use every version when there is no builds for that resource", Example{ 541 DB: DB{ 542 BuildInputs: []DBRow{ 543 {Job: CurrentJobName, BuildID: 4, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 544 }, 545 546 Resources: []DBRow{ 547 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 548 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 549 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 550 551 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 552 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 553 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 554 }, 555 }, 556 557 Inputs: Inputs{ 558 { 559 Name: "resource-x", 560 Resource: "resource-x", 561 Version: Version{Every: true}, 562 }, 563 { 564 Name: "resource-y", 565 Resource: "resource-y", 566 Version: Version{Every: true}, 567 }, 568 }, 569 570 Result: Result{ 571 OK: true, 572 Values: map[string]string{ 573 "resource-x": "rxv2", 574 "resource-y": "ryv3", 575 }, 576 }, 577 }), 578 579 Entry("finds next version that passed constraints for inputs that use every version", Example{ 580 DB: DB{ 581 BuildOutputs: []DBRow{ 582 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 583 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 584 }, 585 586 Resources: []DBRow{ 587 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 588 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 589 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 590 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 591 }, 592 }, 593 594 Inputs: Inputs{ 595 { 596 Name: "resource-x", 597 Resource: "resource-x", 598 Version: Version{Every: true}, 599 Passed: []string{"simple-a"}, 600 }, 601 }, 602 603 Result: Result{ 604 OK: true, 605 Values: map[string]string{ 606 "resource-x": "rxv3", 607 }, 608 }, 609 }), 610 611 Entry("returns the first common version when the current job has no builds and there are multiple passed constraints with version every", Example{ 612 DB: DB{ 613 BuildOutputs: []DBRow{ 614 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 615 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 616 617 {Job: "simple-b", BuildID: 3, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 618 }, 619 620 Resources: []DBRow{ 621 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 622 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 623 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 624 }, 625 }, 626 627 Inputs: Inputs{ 628 { 629 Name: "resource-x", 630 Resource: "resource-x", 631 Version: Version{Every: true}, 632 Passed: []string{"simple-a", "simple-b"}, 633 }, 634 }, 635 636 Result: Result{ 637 OK: true, 638 Values: map[string]string{ 639 "resource-x": "rxv1", 640 }, 641 }, 642 }), 643 644 Entry("does not find candidates when the current job has no builds, there are multiple passed constraints with version every, and a passed job has no builds", Example{ 645 DB: DB{ 646 BuildOutputs: []DBRow{ 647 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 648 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 649 }, 650 651 Resources: []DBRow{ 652 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 653 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 654 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 655 }, 656 }, 657 658 Inputs: Inputs{ 659 { 660 Name: "resource-x", 661 Resource: "resource-x", 662 Version: Version{Every: true}, 663 Passed: []string{"simple-a", "simple-b"}, 664 }, 665 }, 666 667 Result: Result{ 668 OK: false, 669 Errors: map[string]string{ 670 "resource-x": "no satisfiable builds from passed jobs found for set of inputs", 671 }, 672 }, 673 }), 674 675 Entry("returns the next version when there is a passed constraint with version every", Example{ 676 DB: DB{ 677 BuildInputs: []DBRow{ 678 {Job: CurrentJobName, BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 679 }, 680 681 BuildPipes: []DBRow{ 682 {FromBuildID: 2, ToBuildID: 1}, 683 }, 684 685 BuildOutputs: []DBRow{ 686 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 687 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 688 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 689 }, 690 691 Resources: []DBRow{ 692 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 693 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 694 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 695 }, 696 }, 697 698 Inputs: Inputs{ 699 { 700 Name: "resource-x", 701 Resource: "resource-x", 702 Version: Version{Every: true}, 703 Passed: []string{"simple-a"}, 704 }, 705 }, 706 707 Result: Result{ 708 OK: true, 709 Values: map[string]string{ 710 "resource-x": "rxv2", 711 }, 712 }, 713 }), 714 715 Entry("returns current version if there is no version after it that satisifies constraints", Example{ 716 DB: DB{ 717 BuildInputs: []DBRow{ 718 {Job: CurrentJobName, BuildID: 1, Resource: "resource-x", Version: "rxv2", CheckOrder: 1}, 719 }, 720 721 BuildPipes: []DBRow{ 722 {FromBuildID: 3, ToBuildID: 1}, 723 }, 724 725 BuildOutputs: []DBRow{ 726 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 727 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 728 }, 729 730 Resources: []DBRow{ 731 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 732 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 733 }, 734 }, 735 736 Inputs: Inputs{ 737 { 738 Name: "resource-x", 739 Resource: "resource-x", 740 Version: Version{Every: true}, 741 Passed: []string{"simple-a"}, 742 }, 743 }, 744 745 Result: Result{ 746 OK: true, 747 Values: map[string]string{ 748 "resource-x": "rxv2", 749 }, 750 }, 751 }), 752 753 Entry("returns the common version when there are multiple passed constraints with version every", Example{ 754 DB: DB{ 755 BuildInputs: []DBRow{ 756 {Job: CurrentJobName, BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 757 }, 758 759 BuildPipes: []DBRow{ 760 {FromBuildID: 2, ToBuildID: 1}, 761 {FromBuildID: 5, ToBuildID: 1}, 762 }, 763 764 BuildOutputs: []DBRow{ 765 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 766 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 767 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 768 769 {Job: "simple-b", BuildID: 5, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 770 }, 771 772 Resources: []DBRow{ 773 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 774 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 775 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 776 }, 777 }, 778 779 Inputs: Inputs{ 780 { 781 Name: "resource-x", 782 Resource: "resource-x", 783 Version: Version{Every: true}, 784 Passed: []string{"simple-a", "simple-b"}, 785 }, 786 }, 787 788 Result: Result{ 789 OK: true, 790 Values: map[string]string{ 791 "resource-x": "rxv1", 792 }, 793 }, 794 }), 795 796 Entry("returns the first version that satisfies constraints when using every version", Example{ 797 DB: DB{ 798 BuildInputs: []DBRow{ 799 {Job: CurrentJobName, BuildID: 1, Resource: "resource-x", Version: "rxv2", CheckOrder: 3}, 800 }, 801 802 BuildPipes: []DBRow{ 803 {FromBuildID: 3, ToBuildID: 1}, 804 {FromBuildID: 5, ToBuildID: 1}, 805 }, 806 807 BuildOutputs: []DBRow{ 808 // only ran for resource-x, not any version of resource-y 809 {Job: "shared-job", BuildID: 2, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 810 811 // ran for resource-x and resource-y 812 {Job: "shared-job", BuildID: 3, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 813 {Job: "shared-job", BuildID: 3, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 814 815 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 816 {Job: "simple-a", BuildID: 5, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 817 }, 818 819 Resources: []DBRow{ 820 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 821 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 822 823 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 824 }, 825 }, 826 827 Inputs: Inputs{ 828 { 829 Name: "resource-x", 830 Resource: "resource-x", 831 Version: Version{Every: true}, 832 Passed: []string{"shared-job", "simple-a"}, 833 }, 834 { 835 Name: "resource-y", 836 Resource: "resource-y", 837 Version: Version{Every: true}, 838 Passed: []string{"shared-job"}, 839 }, 840 }, 841 842 Result: Result{ 843 OK: true, 844 Values: map[string]string{ 845 "resource-x": "rxv2", 846 "resource-y": "ryv1", 847 }, 848 }, 849 }), 850 851 Entry("does not find candidates when there are multiple passed constraints with version every, and one passed job has no builds", Example{ 852 DB: DB{ 853 BuildInputs: []DBRow{ 854 {Job: CurrentJobName, BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 855 }, 856 857 BuildPipes: []DBRow{ 858 {FromBuildID: 2, ToBuildID: 1}, 859 }, 860 861 BuildOutputs: []DBRow{ 862 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 863 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 864 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 865 }, 866 867 Resources: []DBRow{ 868 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 869 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 870 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 871 }, 872 }, 873 874 Inputs: Inputs{ 875 { 876 Name: "resource-x", 877 Resource: "resource-x", 878 Version: Version{Every: true}, 879 Passed: []string{"simple-a", "simple-b"}, 880 }, 881 }, 882 883 Result: Result{ 884 OK: false, 885 Errors: map[string]string{ 886 "resource-x": "no satisfiable builds from passed jobs found for set of inputs", 887 }, 888 }, 889 }), 890 891 Entry("returns the latest enabled version when the current job has no builds, and there is a passed constraint with version every", Example{ 892 DB: DB{ 893 BuildOutputs: []DBRow{ 894 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 895 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 896 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 897 }, 898 899 Resources: []DBRow{ 900 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 901 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 902 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3, Disabled: true}, 903 }, 904 }, 905 906 Inputs: Inputs{ 907 { 908 Name: "resource-x", 909 Resource: "resource-x", 910 Version: Version{Every: true}, 911 Passed: []string{"simple-a"}, 912 }, 913 }, 914 915 Result: Result{ 916 OK: true, 917 Values: map[string]string{ 918 "resource-x": "rxv2", 919 }, 920 }, 921 }), 922 923 Entry("returns the current enabled version when there is a passed constraint with version every, and all later verisons are disabled", Example{ 924 DB: DB{ 925 BuildInputs: []DBRow{ 926 {Job: CurrentJobName, BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 927 }, 928 929 BuildPipes: []DBRow{ 930 {FromBuildID: 2, ToBuildID: 1}, 931 }, 932 933 BuildOutputs: []DBRow{ 934 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 935 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 936 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 937 }, 938 939 Resources: []DBRow{ 940 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 941 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2, Disabled: true}, 942 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3, Disabled: true}, 943 }, 944 }, 945 946 Inputs: Inputs{ 947 { 948 Name: "resource-x", 949 Resource: "resource-x", 950 Version: Version{Every: true}, 951 Passed: []string{"simple-a"}, 952 }, 953 }, 954 955 Result: Result{ 956 OK: true, 957 Values: map[string]string{ 958 "resource-x": "rxv1", 959 }, 960 }, 961 }), 962 963 Entry("returns the latest set of versions that satisfy all passed constraint with version every, and the current job has no builds", Example{ 964 DB: DB{ 965 BuildOutputs: []DBRow{ 966 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 967 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 968 969 {Job: "simple-b", BuildID: 3, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 970 {Job: "simple-b", BuildID: 4, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 971 972 {Job: "shared-job", BuildID: 5, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 973 {Job: "shared-job", BuildID: 5, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 974 {Job: "shared-job", BuildID: 6, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 975 {Job: "shared-job", BuildID: 6, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 976 {Job: "shared-job", BuildID: 7, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 977 {Job: "shared-job", BuildID: 7, Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 978 }, 979 980 Resources: []DBRow{ 981 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 982 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 983 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 984 985 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 986 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 987 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 988 }, 989 }, 990 991 Inputs: Inputs{ 992 { 993 Name: "resource-x", 994 Resource: "resource-x", 995 Version: Version{Every: true}, 996 Passed: []string{"simple-a", "shared-job"}, 997 }, 998 { 999 Name: "resource-y", 1000 Resource: "resource-y", 1001 Version: Version{Every: true}, 1002 Passed: []string{"simple-b", "shared-job"}, 1003 }, 1004 }, 1005 1006 Result: Result{ 1007 OK: true, 1008 Values: map[string]string{ 1009 "resource-x": "rxv1", 1010 "resource-y": "ryv2", 1011 }, 1012 }, 1013 }), 1014 1015 Entry("returns the latest enabled set of versions that satisfy all passed constraint with version every, and the current job has no builds", Example{ 1016 DB: DB{ 1017 BuildOutputs: []DBRow{ 1018 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1019 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1020 1021 {Job: "simple-b", BuildID: 3, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1022 {Job: "simple-b", BuildID: 4, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1023 1024 {Job: "shared-job", BuildID: 5, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1025 {Job: "shared-job", BuildID: 5, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1026 {Job: "shared-job", BuildID: 6, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1027 {Job: "shared-job", BuildID: 6, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1028 }, 1029 1030 Resources: []DBRow{ 1031 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1032 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2, Disabled: true}, 1033 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1034 1035 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1036 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1037 }, 1038 }, 1039 1040 Inputs: Inputs{ 1041 { 1042 Name: "resource-x", 1043 Resource: "resource-x", 1044 Version: Version{Every: true}, 1045 Passed: []string{"simple-a", "shared-job"}, 1046 }, 1047 { 1048 Name: "resource-y", 1049 Resource: "resource-y", 1050 Version: Version{Every: true}, 1051 Passed: []string{"simple-b", "shared-job"}, 1052 }, 1053 }, 1054 1055 Result: Result{ 1056 OK: true, 1057 Values: map[string]string{ 1058 "resource-x": "rxv1", 1059 "resource-y": "ryv1", 1060 }, 1061 }, 1062 }), 1063 1064 Entry("returns latest build outputs for the passed job that has not run with the current job when using every version", Example{ 1065 DB: DB{ 1066 BuildInputs: []DBRow{ 1067 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, // resource-y does not have build already 1068 }, 1069 1070 BuildPipes: []DBRow{ 1071 {FromBuildID: 1, ToBuildID: 100}, 1072 }, 1073 1074 BuildOutputs: []DBRow{ 1075 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1076 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1077 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1078 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 1079 1080 {Job: "simple-b", BuildID: 5, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1081 {Job: "simple-b", BuildID: 6, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1082 {Job: "simple-b", BuildID: 7, Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1083 {Job: "simple-b", BuildID: 8, Resource: "resource-y", Version: "ryv4", CheckOrder: 4}, 1084 1085 {Job: "shared-job", BuildID: 9, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1086 {Job: "shared-job", BuildID: 9, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1087 1088 {Job: "shared-job", BuildID: 10, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1089 {Job: "shared-job", BuildID: 10, Resource: "resource-y", Version: "ryv2", CheckOrder: 1}, 1090 1091 {Job: "shared-job", BuildID: 11, Resource: "resource-x", Version: "rxv2", CheckOrder: 1}, 1092 {Job: "shared-job", BuildID: 11, Resource: "resource-y", Version: "ryv3", CheckOrder: 1}, 1093 1094 {Job: "shared-job", BuildID: 12, Resource: "resource-x", Version: "rxv2", CheckOrder: 1}, 1095 {Job: "shared-job", BuildID: 12, Resource: "resource-y", Version: "ryv4", CheckOrder: 1}, 1096 1097 {Job: "shared-job", BuildID: 13, Resource: "resource-x", Version: "rxv3", CheckOrder: 1}, 1098 {Job: "shared-job", BuildID: 13, Resource: "resource-y", Version: "ryv4", CheckOrder: 1}, 1099 }, 1100 1101 Resources: []DBRow{ 1102 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1103 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1104 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1105 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 1106 1107 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1108 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1109 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1110 {Resource: "resource-y", Version: "ryv4", CheckOrder: 4}, 1111 }, 1112 }, 1113 1114 Inputs: Inputs{ 1115 { 1116 Name: "resource-x", 1117 Resource: "resource-x", 1118 Version: Version{Every: true}, 1119 Passed: []string{"simple-a", "shared-job"}, 1120 }, 1121 { 1122 Name: "resource-y", 1123 Resource: "resource-y", 1124 Version: Version{Every: true}, 1125 Passed: []string{"shared-job", "simple-b"}, 1126 }, 1127 }, 1128 1129 Result: Result{ 1130 OK: true, 1131 Values: map[string]string{ 1132 "resource-x": "rxv2", 1133 "resource-y": "ryv4", 1134 }, 1135 }, 1136 }), 1137 1138 Entry("finds next version that satisfies common constraints when using every version", Example{ 1139 DB: DB{ 1140 BuildInputs: []DBRow{ 1141 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1142 }, 1143 1144 BuildPipes: []DBRow{ 1145 {FromBuildID: 1, ToBuildID: 100}, 1146 {FromBuildID: 4, ToBuildID: 100}, 1147 }, 1148 1149 BuildOutputs: []DBRow{ 1150 {Job: "shared-job", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1151 1152 {Job: "shared-job", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1153 1154 {Job: "shared-job", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1155 {Job: "shared-job", BuildID: 3, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1156 1157 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1158 {Job: "simple-a", BuildID: 5, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1159 {Job: "simple-a", BuildID: 6, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1160 1161 {Job: "simple-b", BuildID: 7, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1162 {Job: "simple-b", BuildID: 8, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1163 {Job: "simple-b", BuildID: 9, Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1164 }, 1165 1166 Resources: []DBRow{ 1167 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1168 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1169 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1170 1171 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1172 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1173 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1174 }, 1175 }, 1176 1177 Inputs: Inputs{ 1178 { 1179 Name: "resource-x", 1180 Resource: "resource-x", 1181 Version: Version{Every: true}, 1182 Passed: []string{"shared-job", "simple-a"}, 1183 }, 1184 { 1185 Name: "resource-y", 1186 Resource: "resource-y", 1187 Version: Version{Every: true}, 1188 Passed: []string{"shared-job", "simple-b"}, 1189 }, 1190 }, 1191 1192 Result: Result{ 1193 OK: true, 1194 Values: map[string]string{ 1195 "resource-x": "rxv3", 1196 "resource-y": "ryv1", 1197 }, 1198 }, 1199 }), 1200 1201 Entry("returns the only set of versions that satisfy constraints when the set is one that has already run", Example{ 1202 DB: DB{ 1203 BuildInputs: []DBRow{ 1204 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1205 {Job: CurrentJobName, BuildID: 100, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1206 }, 1207 1208 BuildPipes: []DBRow{ 1209 {FromBuildID: 1, ToBuildID: 100}, 1210 {FromBuildID: 5, ToBuildID: 100}, 1211 {FromBuildID: 9, ToBuildID: 100}, 1212 }, 1213 1214 BuildOutputs: []DBRow{ 1215 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1216 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1217 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1218 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 1219 1220 {Job: "simple-b", BuildID: 5, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1221 1222 {Job: "shared-job", BuildID: 9, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1223 {Job: "shared-job", BuildID: 9, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1224 1225 {Job: "shared-job", BuildID: 10, Resource: "resource-x", Version: "rxv4", CheckOrder: 1}, 1226 {Job: "shared-job", BuildID: 10, Resource: "resource-y", Version: "ryv2", CheckOrder: 1}, 1227 1228 {Job: "shared-job", BuildID: 11, Resource: "resource-x", Version: "rxv4", CheckOrder: 1}, 1229 {Job: "shared-job", BuildID: 11, Resource: "resource-y", Version: "ryv3", CheckOrder: 1}, 1230 1231 {Job: "shared-job", BuildID: 12, Resource: "resource-x", Version: "rxv4", CheckOrder: 1}, 1232 {Job: "shared-job", BuildID: 12, Resource: "resource-y", Version: "ryv4", CheckOrder: 1}, 1233 }, 1234 1235 Resources: []DBRow{ 1236 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1237 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1238 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1239 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 1240 1241 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1242 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1243 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1244 {Resource: "resource-y", Version: "ryv4", CheckOrder: 4}, 1245 }, 1246 }, 1247 1248 Inputs: Inputs{ 1249 { 1250 Name: "resource-x", 1251 Resource: "resource-x", 1252 Passed: []string{"shared-job", "simple-a"}, 1253 }, 1254 { 1255 Name: "resource-y", 1256 Resource: "resource-y", 1257 Passed: []string{"shared-job", "simple-b"}, 1258 }, 1259 }, 1260 1261 Result: Result{ 1262 OK: true, 1263 Values: map[string]string{ 1264 "resource-x": "rxv1", 1265 "resource-y": "ryv1", 1266 }, 1267 PassedBuildIDs: map[string][]int{ 1268 "resource-x": []int{1, 9}, 1269 "resource-y": []int{5, 9}, 1270 }, 1271 }, 1272 }), 1273 1274 Entry("returns the next set of versions that satisfy constraints when using every version", Example{ 1275 DB: DB{ 1276 BuildInputs: []DBRow{ 1277 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1278 {Job: CurrentJobName, BuildID: 100, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1279 }, 1280 1281 BuildPipes: []DBRow{ 1282 {FromBuildID: 1, ToBuildID: 100}, 1283 {FromBuildID: 5, ToBuildID: 100}, 1284 {FromBuildID: 9, ToBuildID: 100}, 1285 }, 1286 1287 BuildOutputs: []DBRow{ 1288 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1289 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1290 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1291 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 1292 1293 {Job: "simple-b", BuildID: 5, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1294 {Job: "simple-b", BuildID: 6, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1295 {Job: "simple-b", BuildID: 7, Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1296 {Job: "simple-b", BuildID: 8, Resource: "resource-y", Version: "ryv4", CheckOrder: 4}, 1297 1298 {Job: "shared-job", BuildID: 9, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1299 {Job: "shared-job", BuildID: 9, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1300 1301 {Job: "shared-job", BuildID: 10, Resource: "resource-x", Version: "rxv4", CheckOrder: 1}, 1302 {Job: "shared-job", BuildID: 10, Resource: "resource-y", Version: "ryv2", CheckOrder: 1}, 1303 1304 {Job: "shared-job", BuildID: 11, Resource: "resource-x", Version: "rxv4", CheckOrder: 1}, 1305 {Job: "shared-job", BuildID: 11, Resource: "resource-y", Version: "ryv3", CheckOrder: 1}, 1306 1307 {Job: "shared-job", BuildID: 12, Resource: "resource-x", Version: "rxv4", CheckOrder: 1}, 1308 {Job: "shared-job", BuildID: 12, Resource: "resource-y", Version: "ryv4", CheckOrder: 1}, 1309 }, 1310 1311 Resources: []DBRow{ 1312 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1313 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1314 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1315 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 1316 1317 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1318 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1319 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1320 {Resource: "resource-y", Version: "ryv4", CheckOrder: 4}, 1321 }, 1322 }, 1323 1324 Inputs: Inputs{ 1325 { 1326 Name: "resource-x", 1327 Resource: "resource-x", 1328 Version: Version{Every: true}, 1329 Passed: []string{"shared-job", "simple-a"}, 1330 }, 1331 { 1332 Name: "resource-y", 1333 Resource: "resource-y", 1334 Version: Version{Every: true}, 1335 Passed: []string{"shared-job", "simple-b"}, 1336 }, 1337 }, 1338 1339 Result: Result{ 1340 OK: true, 1341 Values: map[string]string{ 1342 "resource-x": "rxv4", 1343 "resource-y": "ryv2", 1344 }, 1345 }, 1346 }), 1347 1348 Entry("returns earliest set of versions that satisfy the multiple passed constraints with version every when the current job latest build has un-ordered versions independent of the ordering (build ids ordered lowest to highest starting with shared-job)", Example{ 1349 DB: DB{ 1350 BuildInputs: []DBRow{ 1351 {Job: CurrentJobName, BuildID: 10, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1352 {Job: CurrentJobName, BuildID: 10, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1353 }, 1354 1355 BuildPipes: []DBRow{ 1356 {FromBuildID: 4, ToBuildID: 10}, 1357 {FromBuildID: 8, ToBuildID: 10}, 1358 }, 1359 1360 BuildOutputs: []DBRow{ 1361 {Job: "shared-job", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1362 {Job: "shared-job", BuildID: 1, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1363 {Job: "shared-job", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1364 {Job: "shared-job", BuildID: 2, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1365 {Job: "shared-job", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1366 {Job: "shared-job", BuildID: 3, Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1367 1368 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1369 {Job: "simple-a", BuildID: 5, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1370 {Job: "simple-a", BuildID: 6, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1371 1372 {Job: "simple-b", BuildID: 7, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1373 {Job: "simple-b", BuildID: 8, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1374 {Job: "simple-b", BuildID: 9, Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1375 }, 1376 1377 Resources: []DBRow{ 1378 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1379 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1380 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1381 1382 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1383 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1384 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1385 }, 1386 }, 1387 1388 Inputs: Inputs{ 1389 { 1390 Name: "resource-x", 1391 Resource: "resource-x", 1392 Version: Version{Every: true}, 1393 Passed: []string{"simple-a", "shared-job"}, 1394 }, 1395 { 1396 Name: "resource-y", 1397 Resource: "resource-y", 1398 Version: Version{Every: true}, 1399 Passed: []string{"simple-b", "shared-job"}, 1400 }, 1401 }, 1402 1403 Result: Result{ 1404 OK: true, 1405 Values: map[string]string{ 1406 "resource-x": "rxv2", 1407 "resource-y": "ryv2", 1408 }, 1409 }, 1410 }), 1411 1412 Entry("returns earliest set of versions that satisfy the multiple passed constraints with version every when the current job latest build has un-ordered versions independent of the ordering (build ids ordered lowest to highest starting with simple-a)", Example{ 1413 DB: DB{ 1414 BuildInputs: []DBRow{ 1415 {Job: CurrentJobName, BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1416 {Job: CurrentJobName, BuildID: 1, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1417 }, 1418 1419 BuildPipes: []DBRow{ 1420 {FromBuildID: 2, ToBuildID: 1}, 1421 {FromBuildID: 6, ToBuildID: 1}, 1422 }, 1423 1424 BuildOutputs: []DBRow{ 1425 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1426 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1427 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1428 1429 {Job: "simple-b", BuildID: 5, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1430 {Job: "simple-b", BuildID: 6, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1431 {Job: "simple-b", BuildID: 7, Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1432 1433 {Job: "shared-job", BuildID: 8, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1434 {Job: "shared-job", BuildID: 8, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1435 {Job: "shared-job", BuildID: 9, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1436 {Job: "shared-job", BuildID: 9, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1437 {Job: "shared-job", BuildID: 10, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1438 {Job: "shared-job", BuildID: 10, Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1439 }, 1440 1441 Resources: []DBRow{ 1442 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1443 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1444 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1445 1446 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1447 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1448 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1449 }, 1450 }, 1451 1452 Inputs: Inputs{ 1453 { 1454 Name: "resource-x", 1455 Resource: "resource-x", 1456 Version: Version{Every: true}, 1457 Passed: []string{"simple-a", "shared-job"}, 1458 }, 1459 { 1460 Name: "resource-y", 1461 Resource: "resource-y", 1462 Version: Version{Every: true}, 1463 Passed: []string{"simple-b", "shared-job"}, 1464 }, 1465 }, 1466 1467 Result: Result{ 1468 OK: true, 1469 Values: map[string]string{ 1470 "resource-x": "rxv2", 1471 "resource-y": "ryv2", 1472 }, 1473 }, 1474 }), 1475 1476 Entry("returns earliest set of versions that satisfy the multiple passed constraints with version every when one of the passed jobs skipped a version", Example{ 1477 DB: DB{ 1478 BuildInputs: []DBRow{ 1479 {Job: CurrentJobName, BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1480 {Job: CurrentJobName, BuildID: 1, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1481 }, 1482 1483 BuildPipes: []DBRow{ 1484 {FromBuildID: 2, ToBuildID: 1}, 1485 {FromBuildID: 5, ToBuildID: 1}, 1486 }, 1487 1488 BuildOutputs: []DBRow{ 1489 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1490 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1491 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1492 1493 {Job: "simple-b", BuildID: 5, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1494 {Job: "simple-b", BuildID: 7, Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1495 1496 {Job: "shared-job", BuildID: 8, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1497 {Job: "shared-job", BuildID: 8, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1498 {Job: "shared-job", BuildID: 9, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1499 {Job: "shared-job", BuildID: 9, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1500 {Job: "shared-job", BuildID: 10, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1501 {Job: "shared-job", BuildID: 10, Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1502 }, 1503 1504 Resources: []DBRow{ 1505 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1506 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1507 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1508 1509 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1510 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1511 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1512 }, 1513 }, 1514 1515 Inputs: Inputs{ 1516 { 1517 Name: "resource-x", 1518 Resource: "resource-x", 1519 Version: Version{Every: true}, 1520 Passed: []string{"simple-a", "shared-job"}, 1521 }, 1522 { 1523 Name: "resource-y", 1524 Resource: "resource-y", 1525 Version: Version{Every: true}, 1526 Passed: []string{"simple-b", "shared-job"}, 1527 }, 1528 }, 1529 1530 Result: Result{ 1531 OK: true, 1532 Values: map[string]string{ 1533 "resource-x": "rxv3", 1534 "resource-y": "ryv3", 1535 }, 1536 }, 1537 }), 1538 1539 Entry("returns the current set of versions that satisfy the multiple passed constraints with version every when one of the passed job has no newer versions", Example{ 1540 DB: DB{ 1541 BuildInputs: []DBRow{ 1542 {Job: CurrentJobName, BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1543 {Job: CurrentJobName, BuildID: 1, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1544 }, 1545 1546 BuildPipes: []DBRow{ 1547 {FromBuildID: 2, ToBuildID: 1}, 1548 {FromBuildID: 5, ToBuildID: 1}, 1549 }, 1550 1551 BuildOutputs: []DBRow{ 1552 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1553 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1554 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1555 1556 {Job: "simple-b", BuildID: 5, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1557 1558 {Job: "shared-job", BuildID: 8, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1559 {Job: "shared-job", BuildID: 8, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1560 {Job: "shared-job", BuildID: 9, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1561 {Job: "shared-job", BuildID: 9, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1562 {Job: "shared-job", BuildID: 10, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1563 {Job: "shared-job", BuildID: 10, Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1564 }, 1565 1566 Resources: []DBRow{ 1567 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1568 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1569 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1570 1571 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1572 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1573 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1574 }, 1575 }, 1576 1577 Inputs: Inputs{ 1578 { 1579 Name: "resource-x", 1580 Resource: "resource-x", 1581 Version: Version{Every: true}, 1582 Passed: []string{"simple-a", "shared-job"}, 1583 }, 1584 { 1585 Name: "resource-y", 1586 Resource: "resource-y", 1587 Version: Version{Every: true}, 1588 Passed: []string{"simple-b", "shared-job"}, 1589 }, 1590 }, 1591 1592 Result: Result{ 1593 OK: true, 1594 Values: map[string]string{ 1595 "resource-x": "rxv1", 1596 "resource-y": "ryv1", 1597 }, 1598 }, 1599 }), 1600 1601 Entry("returns an older set of versions that satisfy the multiple passed constraints with version every when the passed job versions are older than the current set", Example{ 1602 DB: DB{ 1603 BuildInputs: []DBRow{ 1604 {Job: CurrentJobName, BuildID: 1, Resource: "resource-x", Version: "rxv2", CheckOrder: 1}, 1605 {Job: CurrentJobName, BuildID: 1, Resource: "resource-y", Version: "ryv2", CheckOrder: 1}, 1606 }, 1607 1608 BuildPipes: []DBRow{ 1609 {FromBuildID: 2, ToBuildID: 1}, 1610 {FromBuildID: 5, ToBuildID: 1}, 1611 }, 1612 1613 BuildOutputs: []DBRow{ 1614 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1615 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1616 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1617 1618 {Job: "simple-b", BuildID: 5, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1619 {Job: "simple-b", BuildID: 6, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1620 {Job: "simple-b", BuildID: 7, Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1621 1622 {Job: "shared-job", BuildID: 8, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1623 {Job: "shared-job", BuildID: 8, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1624 }, 1625 1626 Resources: []DBRow{ 1627 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1628 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1629 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1630 1631 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1632 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1633 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1634 }, 1635 }, 1636 1637 Inputs: Inputs{ 1638 { 1639 Name: "resource-x", 1640 Resource: "resource-x", 1641 Version: Version{Every: true}, 1642 Passed: []string{"simple-a", "shared-job"}, 1643 }, 1644 { 1645 Name: "resource-y", 1646 Resource: "resource-y", 1647 Version: Version{Every: true}, 1648 Passed: []string{"simple-b", "shared-job"}, 1649 }, 1650 }, 1651 1652 Result: Result{ 1653 OK: true, 1654 Values: map[string]string{ 1655 "resource-x": "rxv1", 1656 "resource-y": "ryv1", 1657 }, 1658 }, 1659 }), 1660 1661 Entry("returns the earliest non-disabled version that satisfies constraints when several versions do not satisfy when using every version", Example{ 1662 DB: DB{ 1663 BuildInputs: []DBRow{ 1664 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1665 {Job: CurrentJobName, BuildID: 100, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1666 }, 1667 1668 BuildPipes: []DBRow{ 1669 {FromBuildID: 1, ToBuildID: 100}, 1670 {FromBuildID: 5, ToBuildID: 100}, 1671 {FromBuildID: 9, ToBuildID: 100}, 1672 }, 1673 1674 BuildOutputs: []DBRow{ 1675 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1676 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1677 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1678 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 1679 1680 {Job: "simple-b", BuildID: 5, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1681 {Job: "simple-b", BuildID: 6, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1682 {Job: "simple-b", BuildID: 7, Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1683 {Job: "simple-b", BuildID: 8, Resource: "resource-y", Version: "ryv4", CheckOrder: 4}, 1684 1685 {Job: "shared-job", BuildID: 9, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1686 {Job: "shared-job", BuildID: 9, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1687 1688 {Job: "shared-job", BuildID: 10, Resource: "resource-x", Version: "rxv4", CheckOrder: 1}, 1689 {Job: "shared-job", BuildID: 10, Resource: "resource-y", Version: "ryv2", CheckOrder: 1}, 1690 1691 {Job: "shared-job", BuildID: 11, Resource: "resource-x", Version: "rxv4", CheckOrder: 1}, 1692 {Job: "shared-job", BuildID: 11, Resource: "resource-y", Version: "ryv3", CheckOrder: 1}, 1693 1694 {Job: "shared-job", BuildID: 12, Resource: "resource-x", Version: "rxv4", CheckOrder: 1}, 1695 {Job: "shared-job", BuildID: 12, Resource: "resource-y", Version: "ryv4", CheckOrder: 1}, 1696 }, 1697 1698 Resources: []DBRow{ 1699 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1700 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1701 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1702 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 1703 1704 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1705 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2, Disabled: true}, 1706 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 1707 {Resource: "resource-y", Version: "ryv4", CheckOrder: 4}, 1708 }, 1709 }, 1710 1711 Inputs: Inputs{ 1712 { 1713 Name: "resource-x", 1714 Resource: "resource-x", 1715 Version: Version{Every: true}, 1716 Passed: []string{"shared-job", "simple-a"}, 1717 }, 1718 { 1719 Name: "resource-y", 1720 Resource: "resource-y", 1721 Version: Version{Every: true}, 1722 Passed: []string{"shared-job", "simple-b"}, 1723 }, 1724 }, 1725 1726 Result: Result{ 1727 OK: true, 1728 Values: map[string]string{ 1729 "resource-x": "rxv4", 1730 "resource-y": "ryv3", 1731 }, 1732 }, 1733 }), 1734 1735 Entry("when a passed constraint is added to a job that has already run before, it finds the latest", Example{ 1736 DB: DB{ 1737 BuildInputs: []DBRow{ 1738 {Job: CurrentJobName, BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1739 }, 1740 1741 BuildOutputs: []DBRow{ 1742 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1743 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1744 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1745 }, 1746 1747 Resources: []DBRow{ 1748 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1749 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1750 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1751 }, 1752 }, 1753 1754 Inputs: Inputs{ 1755 { 1756 Name: "resource-x", 1757 Resource: "resource-x", 1758 Version: Version{Every: true}, 1759 Passed: []string{"simple-a"}, 1760 }, 1761 }, 1762 1763 Result: Result{ 1764 OK: true, 1765 Values: map[string]string{ 1766 "resource-x": "rxv3", 1767 }, 1768 }, 1769 }), 1770 1771 Entry("returns a missing input reason when no input version satisfies the shared passed constraints", Example{ 1772 DB: DB{ 1773 BuildOutputs: []DBRow{ 1774 {Job: "shared-job", BuildID: 1, Resource: "resource-1", Version: "r1-common-to-shared-and-j1", CheckOrder: 1}, 1775 {Job: "shared-job", BuildID: 1, Resource: "resource-2", Version: "r2-common-to-shared-and-j2", CheckOrder: 1}, 1776 1777 // resource-1 did not pass job-2 with r1-common-to-shared-and-j1 1778 {Job: "job-2", BuildID: 3, Resource: "resource-2", Version: "r2-common-to-shared-and-j2", CheckOrder: 1}, 1779 1780 {Job: "shared-job", BuildID: 4, Resource: "resource-1", Version: "new-r1-common-to-shared-and-j1", CheckOrder: 2}, 1781 {Job: "shared-job", BuildID: 4, Resource: "resource-2", Version: "new-r2-common-to-shared-and-j2", CheckOrder: 2}, 1782 1783 // resource-2 did not pass job-1 with new-r2-common-to-shared-and-j2 1784 {Job: "job-1", BuildID: 5, Resource: "resource-1", Version: "new-r1-common-to-shared-and-j1", CheckOrder: 2}, 1785 }, 1786 }, 1787 1788 Inputs: Inputs{ 1789 { 1790 Name: "input-1", 1791 Resource: "resource-1", 1792 Passed: []string{"shared-job", "job-1"}, 1793 }, 1794 { 1795 Name: "input-2", 1796 Resource: "resource-2", 1797 Passed: []string{"shared-job", "job-2"}, 1798 }, 1799 }, 1800 1801 Result: Result{ 1802 OK: false, 1803 Errors: map[string]string{ 1804 "input-1": "no satisfiable builds from passed jobs found for set of inputs", 1805 "input-2": "no satisfiable builds from passed jobs found for set of inputs", 1806 }, 1807 }, 1808 }), 1809 1810 Entry("resolves to the pinned version when it exists", Example{ 1811 DB: DB{ 1812 Resources: []DBRow{ 1813 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1814 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1815 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1816 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 1817 }, 1818 }, 1819 1820 Inputs: Inputs{ 1821 { 1822 Name: "resource-x", 1823 Resource: "resource-x", 1824 Version: Version{Pinned: "rxv2"}, 1825 }, 1826 }, 1827 1828 Result: Result{ 1829 OK: true, 1830 Values: map[string]string{ 1831 "resource-x": "rxv2", 1832 }, 1833 }, 1834 }), 1835 1836 Entry("does not resolve a version when the pinned version is not in Versions DB (version is disabled or no builds succeeded)", Example{ 1837 DB: DB{ 1838 Resources: []DBRow{ 1839 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1840 // rxv2 was here 1841 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1842 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 1843 }, 1844 }, 1845 1846 Inputs: Inputs{ 1847 { 1848 Name: "resource-x", 1849 Resource: "resource-x", 1850 Version: Version{Pinned: "rxv2"}, 1851 }, 1852 }, 1853 1854 Result: Result{ 1855 OK: false, 1856 Errors: map[string]string{"resource-x": "pinned version ver:rxv2 not found"}, 1857 }, 1858 }), 1859 1860 Entry("resolves the version that is pinned with passed", Example{ 1861 DB: DB{ 1862 BuildOutputs: []DBRow{ 1863 {Job: "some-job", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1864 {Job: "some-job", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1865 {Job: "some-job", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1866 {Job: "some-job", BuildID: 4, Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 1867 }, 1868 1869 Resources: []DBRow{ 1870 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1871 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1872 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1873 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 1874 }, 1875 }, 1876 1877 Inputs: Inputs{ 1878 { 1879 Name: "resource-x", 1880 Resource: "resource-x", 1881 Version: Version{Pinned: "rxv2"}, 1882 Passed: []string{"some-job"}, 1883 }, 1884 }, 1885 1886 Result: Result{ 1887 OK: true, 1888 Values: map[string]string{ 1889 "resource-x": "rxv2", 1890 }, 1891 }, 1892 }), 1893 1894 Entry("does not resolve a version when the pinned version has not passed the constraint", Example{ 1895 DB: DB{ 1896 BuildOutputs: []DBRow{ 1897 {Job: "some-job", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1898 }, 1899 1900 Resources: []DBRow{ 1901 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1902 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1903 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1904 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 1905 }, 1906 }, 1907 1908 Inputs: Inputs{ 1909 { 1910 Name: "resource-x", 1911 Resource: "resource-x", 1912 Version: Version{Pinned: "rxv2"}, 1913 Passed: []string{"some-job"}, 1914 }, 1915 }, 1916 1917 Result: Result{ 1918 OK: false, 1919 Errors: map[string]string{ 1920 "resource-x": "no satisfiable builds from passed jobs found for set of inputs", 1921 }, 1922 }, 1923 }), 1924 1925 Entry("uses the build that includes the pinned with passed while there are multiple inputs", Example{ 1926 DB: DB{ 1927 BuildOutputs: []DBRow{ 1928 {Job: "shared-job", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1929 {Job: "shared-job", BuildID: 1, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1930 1931 {Job: "shared-job", BuildID: 2, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1932 {Job: "shared-job", BuildID: 2, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1933 1934 {Job: "shared-job", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1935 {Job: "shared-job", BuildID: 3, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 1936 1937 {Job: "shared-job", BuildID: 4, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1938 {Job: "shared-job", BuildID: 4, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 1939 }, 1940 1941 Resources: []DBRow{ 1942 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1943 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1944 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1945 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 1946 1947 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1948 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1949 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 1950 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 1951 }, 1952 }, 1953 1954 Inputs: Inputs{ 1955 { 1956 Name: "resource-x", 1957 Resource: "resource-x", 1958 Version: Version{Pinned: "rxv3"}, 1959 Passed: []string{"shared-job"}, 1960 }, 1961 { 1962 Name: "resource-y", 1963 Resource: "resource-y", 1964 Version: Version{Pinned: "ryv1"}, 1965 Passed: []string{"shared-job"}, 1966 }, 1967 }, 1968 1969 Result: Result{ 1970 OK: true, 1971 Values: map[string]string{ 1972 "resource-x": "rxv3", 1973 "resource-y": "ryv1", 1974 }, 1975 }, 1976 }), 1977 1978 Entry("check orders take precedence over version ID", Example{ 1979 DB: DB{ 1980 Resources: []DBRow{ 1981 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 1982 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 1983 }, 1984 }, 1985 1986 Inputs: Inputs{ 1987 {Name: "resource-x", Resource: "resource-x"}, 1988 }, 1989 1990 Result: Result{ 1991 OK: true, 1992 Values: map[string]string{ 1993 "resource-x": "rxv2", 1994 }, 1995 }, 1996 }), 1997 1998 Entry("waiting on upstream job for shared version (ryv3)", Example{ 1999 DB: DB{ 2000 BuildOutputs: []DBRow{ 2001 {Job: "shared-job", BuildID: 1, Resource: "resource-x", Version: "rxv3", CheckOrder: 1}, 2002 {Job: "shared-job", BuildID: 1, Resource: "resource-y", Version: "ryv3", CheckOrder: 1}, 2003 2004 {Job: "simple-a", BuildID: 2, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 2005 {Job: "simple-a", BuildID: 3, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 2006 }, 2007 2008 Resources: []DBRow{ 2009 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2010 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2011 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2012 2013 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 2014 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 2015 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 2016 }, 2017 }, 2018 2019 Inputs: Inputs{ 2020 { 2021 Name: "resource-x", 2022 Resource: "resource-x", 2023 Passed: []string{"shared-job"}, 2024 }, 2025 { 2026 Name: "resource-y", 2027 Resource: "resource-y", 2028 Passed: []string{"shared-job", "simple-a"}, 2029 }, 2030 }, 2031 2032 Result: Result{ 2033 OK: false, 2034 Errors: map[string]string{ 2035 "resource-x": "no satisfiable builds from passed jobs found for set of inputs", 2036 "resource-y": "no satisfiable builds from passed jobs found for set of inputs", 2037 }, 2038 }, 2039 }), 2040 2041 Entry("reconfigure passed constraints for job with missing upstream dependency (simple-c)", Example{ 2042 DB: DB{ 2043 BuildInputs: []DBRow{ 2044 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2045 {Job: CurrentJobName, BuildID: 100, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 2046 {Job: CurrentJobName, BuildID: 100, Resource: "resource-w", Version: "rwv1", CheckOrder: 1}, 2047 {Job: CurrentJobName, BuildID: 100, Resource: "resource-v", Version: "rvv1", CheckOrder: 1}, 2048 }, 2049 2050 BuildPipes: []DBRow{ 2051 {FromBuildID: 1, ToBuildID: 100}, 2052 {FromBuildID: 7, ToBuildID: 100}, 2053 {FromBuildID: 9, ToBuildID: 100}, 2054 }, 2055 2056 BuildOutputs: []DBRow{ 2057 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2058 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2059 2060 {Job: "simple-b", BuildID: 3, Resource: "resource-z", Version: "rzv1", CheckOrder: 1}, 2061 {Job: "simple-b", BuildID: 4, Resource: "resource-z", Version: "rzv2", CheckOrder: 2}, 2062 2063 {Job: "simple-c", BuildID: 5, Resource: "resource-w", Version: "rwv3", CheckOrder: 1}, 2064 {Job: "simple-c", BuildID: 6, Resource: "resource-w", Version: "rwv4", CheckOrder: 2}, 2065 2066 {Job: "shared-job", BuildID: 7, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2067 {Job: "shared-job", BuildID: 7, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 2068 {Job: "shared-job", BuildID: 8, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2069 {Job: "shared-job", BuildID: 8, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 2070 2071 {Job: "shared-b", BuildID: 9, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 2072 {Job: "shared-b", BuildID: 9, Resource: "resource-w", Version: "rwv1", CheckOrder: 1}, 2073 {Job: "shared-b", BuildID: 10, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 2074 {Job: "shared-b", BuildID: 10, Resource: "resource-w", Version: "rwv2", CheckOrder: 2}, 2075 }, 2076 2077 Resources: []DBRow{ 2078 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2079 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2080 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2081 2082 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 2083 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 2084 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 2085 2086 {Resource: "resource-w", Version: "rwv1", CheckOrder: 1}, 2087 {Resource: "resource-w", Version: "rwv2", CheckOrder: 2}, 2088 {Resource: "resource-w", Version: "rwv3", CheckOrder: 3}, 2089 {Resource: "resource-w", Version: "rwv4", CheckOrder: 4}, 2090 2091 {Resource: "resource-z", Version: "rzv1", CheckOrder: 1}, 2092 {Resource: "resource-z", Version: "rzv2", CheckOrder: 2}, 2093 2094 {Resource: "resource-v", Version: "rvv1", CheckOrder: 1}, 2095 {Resource: "resource-v", Version: "rvv2", CheckOrder: 2}, 2096 {Resource: "resource-v", Version: "rvv3", CheckOrder: 3}, 2097 }, 2098 }, 2099 2100 Inputs: Inputs{ 2101 { 2102 Name: "resource-x", 2103 Resource: "resource-x", 2104 Passed: []string{"shared-job", "simple-a"}, 2105 }, 2106 { 2107 Name: "resource-y", 2108 Resource: "resource-y", 2109 Passed: []string{"shared-job", "shared-b"}, 2110 }, 2111 { 2112 Name: "resource-z", 2113 Resource: "resource-z", 2114 Passed: []string{"simple-b"}, 2115 }, 2116 { 2117 Name: "resource-w", 2118 Resource: "resource-w", 2119 Passed: []string{"shared-b", "simple-c"}, 2120 }, 2121 { 2122 Name: "resource-v", 2123 Resource: "resource-v", 2124 Version: Version{Latest: true}, 2125 }, 2126 }, 2127 2128 Result: Result{ 2129 OK: false, 2130 Errors: map[string]string{ 2131 "resource-x": "no satisfiable builds from passed jobs found for set of inputs", 2132 "resource-y": "no satisfiable builds from passed jobs found for set of inputs", 2133 "resource-w": "no satisfiable builds from passed jobs found for set of inputs", 2134 }, 2135 }, 2136 }), 2137 2138 Entry("finds a suitable candidate for any inputs resolved before an unresolveable candidates", Example{ 2139 DB: DB{ 2140 BuildInputs: []DBRow{ 2141 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2142 {Job: CurrentJobName, BuildID: 100, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 2143 {Job: CurrentJobName, BuildID: 100, Resource: "resource-c", Version: "rcv2", CheckOrder: 2}, 2144 }, 2145 2146 BuildPipes: []DBRow{ 2147 {FromBuildID: 1, ToBuildID: 100}, 2148 {FromBuildID: 9, ToBuildID: 100}, 2149 {FromBuildID: 14, ToBuildID: 100}, 2150 }, 2151 2152 BuildOutputs: []DBRow{ 2153 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2154 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2155 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2156 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 2157 2158 {Job: "simple-b", BuildID: 6, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 2159 {Job: "simple-b", BuildID: 6, Resource: "resource-d", Version: "rdv1", CheckOrder: 1}, 2160 2161 {Job: "simple-b", BuildID: 7, Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 2162 {Job: "simple-b", BuildID: 8, Resource: "resource-y", Version: "ryv4", CheckOrder: 4}, 2163 2164 {Job: "simple-b", BuildID: 7, Resource: "resource-d", Version: "rdv2", CheckOrder: 2}, 2165 {Job: "simple-b", BuildID: 8, Resource: "resource-d", Version: "rdv4", CheckOrder: 4}, 2166 2167 {Job: "shared-job", BuildID: 9, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2168 {Job: "shared-job", BuildID: 9, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 2169 {Job: "shared-job", BuildID: 9, Resource: "resource-d", Version: "rdv1", CheckOrder: 1}, 2170 2171 {Job: "shared-job", BuildID: 10, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2172 {Job: "shared-job", BuildID: 10, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 2173 2174 {Job: "shared-job", BuildID: 11, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2175 {Job: "shared-job", BuildID: 11, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 2176 2177 {Job: "shared-job", BuildID: 12, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2178 {Job: "shared-job", BuildID: 12, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 2179 2180 {Job: "simple-1", BuildID: 13, Resource: "resource-a", Version: "rav1", CheckOrder: 1}, 2181 {Job: "simple-1", BuildID: 13, Resource: "resource-c", Version: "rcv1", CheckOrder: 1}, 2182 {Job: "simple-1", BuildID: 14, Resource: "resource-a", Version: "rav2", CheckOrder: 2}, 2183 {Job: "simple-1", BuildID: 14, Resource: "resource-c", Version: "rcv2", CheckOrder: 2}, 2184 {Job: "simple-1", BuildID: 15, Resource: "resource-a", Version: "rav3", CheckOrder: 3}, 2185 {Job: "simple-1", BuildID: 15, Resource: "resource-c", Version: "rcv3", CheckOrder: 3}, 2186 2187 {Job: "simple-3", BuildID: 17, Resource: "resource-d", Version: "rdv1", CheckOrder: 1}, 2188 {Job: "simple-3", BuildID: 18, Resource: "resource-d", Version: "rdv2", CheckOrder: 2}, 2189 }, 2190 2191 Resources: []DBRow{ 2192 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2193 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2194 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2195 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 2196 2197 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 2198 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2, Disabled: true}, 2199 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 2200 {Resource: "resource-y", Version: "ryv4", CheckOrder: 4}, 2201 2202 {Resource: "resource-a", Version: "rav1", CheckOrder: 1}, 2203 {Resource: "resource-a", Version: "rav2", CheckOrder: 2}, 2204 {Resource: "resource-a", Version: "rav3", CheckOrder: 3}, 2205 2206 {Resource: "resource-b", Version: "rbv1", CheckOrder: 1}, 2207 {Resource: "resource-b", Version: "rbv2", CheckOrder: 2}, 2208 {Resource: "resource-b", Version: "rbv3", CheckOrder: 3, Disabled: true}, 2209 2210 {Resource: "resource-c", Version: "rcv1", CheckOrder: 1}, 2211 {Resource: "resource-c", Version: "rcv2", CheckOrder: 2}, 2212 {Resource: "resource-c", Version: "rcv3", CheckOrder: 3, Disabled: true}, 2213 {Resource: "resource-c", Version: "rcv4", CheckOrder: 4}, 2214 2215 {Resource: "resource-d", Version: "rdv1", CheckOrder: 1}, 2216 {Resource: "resource-d", Version: "rdv2", CheckOrder: 2}, 2217 {Resource: "resource-d", Version: "rdv3", CheckOrder: 3, Disabled: true}, 2218 {Resource: "resource-d", Version: "rdv4", CheckOrder: 4}, 2219 }, 2220 }, 2221 2222 Inputs: Inputs{ 2223 { 2224 Name: "resource-x", 2225 Resource: "resource-x", 2226 Passed: []string{"shared-job", "simple-a"}, 2227 }, 2228 { 2229 Name: "resource-y", 2230 Resource: "resource-y", 2231 Version: Version{Every: true}, 2232 Passed: []string{"shared-job", "simple-b"}, 2233 }, 2234 { 2235 Name: "resource-a", 2236 Resource: "resource-a", 2237 Version: Version{Every: true}, 2238 Passed: []string{"simple-1"}, 2239 }, 2240 { 2241 Name: "resource-b", 2242 Resource: "resource-b", 2243 Version: Version{Every: true}, 2244 Passed: []string{"simple-2"}, 2245 }, 2246 { 2247 Name: "resource-c", 2248 Resource: "resource-c", 2249 Version: Version{Every: true}, 2250 }, 2251 { 2252 Name: "resource-d", 2253 Resource: "resource-d", 2254 Passed: []string{"shared-job", "simple-b", "simple-3"}, 2255 }, 2256 }, 2257 2258 Result: Result{ 2259 OK: false, 2260 Errors: map[string]string{ 2261 "resource-x": "no satisfiable builds from passed jobs found for set of inputs", 2262 "resource-y": "no satisfiable builds from passed jobs found for set of inputs", 2263 "resource-d": "no satisfiable builds from passed jobs found for set of inputs", 2264 "resource-b": "no satisfiable builds from passed jobs found for set of inputs", 2265 }, 2266 }, 2267 }), 2268 2269 Entry("uses partially resolved candidates when there is an error with no passed", Example{ 2270 DB: DB{ 2271 Resources: []DBRow{ 2272 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2273 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2274 }, 2275 }, 2276 2277 Inputs: Inputs{ 2278 { 2279 Name: "resource-x", 2280 Resource: "resource-x", 2281 Version: Version{Every: true}, 2282 }, 2283 { 2284 Name: "resource-y", 2285 Resource: "resource-y", 2286 Version: Version{Every: true}, 2287 }, 2288 }, 2289 2290 Result: Result{ 2291 OK: false, 2292 Errors: map[string]string{ 2293 "resource-y": "version of resource not found", 2294 }, 2295 }, 2296 }), 2297 2298 Entry("finds the next every version scoped to a resource", Example{ 2299 DB: DB{ 2300 BuildInputs: []DBRow{ 2301 {Job: CurrentJobName, BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2302 }, 2303 2304 Resources: []DBRow{ 2305 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2306 2307 // higher check-order but different resource 2308 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 2309 }, 2310 }, 2311 2312 Inputs: Inputs{ 2313 { 2314 Name: "resource-x", 2315 Resource: "resource-x", 2316 Version: Version{Every: true}, 2317 }, 2318 }, 2319 2320 Result: Result{ 2321 OK: true, 2322 Values: map[string]string{ 2323 "resource-x": "rxv1", 2324 }, 2325 }, 2326 }), 2327 2328 Entry("finds successful candidates when there are multiple outputs from passed constraints that are identical", Example{ 2329 DB: DB{ 2330 BuildInputs: []DBRow{ 2331 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2332 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2333 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2334 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2335 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 2336 }, 2337 2338 BuildPipes: []DBRow{ 2339 {FromBuildID: 1, ToBuildID: 100}, 2340 }, 2341 2342 BuildOutputs: []DBRow{ 2343 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2344 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2345 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2346 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 2347 2348 {Job: "simple-b", BuildID: 5, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2349 }, 2350 2351 Resources: []DBRow{ 2352 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2353 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2354 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2355 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 2356 }, 2357 }, 2358 2359 Inputs: Inputs{ 2360 { 2361 Name: "resource-x", 2362 Resource: "resource-x", 2363 Passed: []string{"simple-a", "simple-b"}, 2364 }, 2365 }, 2366 2367 Result: Result{ 2368 OK: true, 2369 Values: map[string]string{ 2370 "resource-x": "rxv1", 2371 }, 2372 }, 2373 }), 2374 2375 Entry("only uses the first build output/input to set a version candidate and disregards the other (it should use the output version first)", Example{ 2376 DB: DB{ 2377 BuildInputs: []DBRow{ 2378 {Job: "simple-a", BuildID: 1, Resource: "version", Version: "5.5.6-rc.23", CheckOrder: 1}, 2379 {Job: "simple-a", BuildID: 1, Resource: "resource-1", Version: "r1v1", CheckOrder: 1}, 2380 {Job: "simple-a", BuildID: 1, Resource: "resource-2", Version: "r2v1", CheckOrder: 1}, 2381 {Job: "simple-a", BuildID: 1, Resource: "resource-3", Version: "r3v1", CheckOrder: 1}, 2382 {Job: "simple-a", BuildID: 1, Resource: "resource-4", Version: "r4v1", CheckOrder: 1}, 2383 {Job: "simple-a", BuildID: 1, Resource: "resource-5", Version: "r5v1", CheckOrder: 1}, 2384 {Job: "simple-a", BuildID: 1, Resource: "resource-6", Version: "r6v1", CheckOrder: 1}, 2385 {Job: "simple-a", BuildID: 1, Resource: "resource-7", Version: "r7v1", CheckOrder: 1}, 2386 {Job: "simple-a", BuildID: 1, Resource: "resource-8", Version: "r8v1", CheckOrder: 1}, 2387 2388 {Job: "simple-a", BuildID: 2, Resource: "version", Version: "5.5.7-rc.23", CheckOrder: 3}, 2389 {Job: "simple-a", BuildID: 2, Resource: "resource-1", Version: "r1v2", CheckOrder: 2}, 2390 {Job: "simple-a", BuildID: 2, Resource: "resource-2", Version: "r2v2", CheckOrder: 2}, 2391 {Job: "simple-a", BuildID: 2, Resource: "resource-3", Version: "r3v2", CheckOrder: 2}, 2392 {Job: "simple-a", BuildID: 2, Resource: "resource-4", Version: "r4v2", CheckOrder: 2}, 2393 {Job: "simple-a", BuildID: 2, Resource: "resource-5", Version: "r5v2", CheckOrder: 2}, 2394 {Job: "simple-a", BuildID: 2, Resource: "resource-6", Version: "r6v2", CheckOrder: 2}, 2395 {Job: "simple-a", BuildID: 2, Resource: "resource-7", Version: "r7v2", CheckOrder: 2}, 2396 {Job: "simple-a", BuildID: 2, Resource: "resource-8", Version: "r8v2", CheckOrder: 2}, 2397 }, 2398 2399 BuildOutputs: []DBRow{ 2400 {Job: "simple-a", BuildID: 1, Resource: "version", Version: "5.5.6", CheckOrder: 2}, 2401 {Job: "simple-a", BuildID: 2, Resource: "version", Version: "5.5.7", CheckOrder: 4}, 2402 }, 2403 2404 Resources: []DBRow{ 2405 {Resource: "resource-1", Version: "r1v1", CheckOrder: 1}, 2406 {Resource: "resource-1", Version: "r1v2", CheckOrder: 2}, 2407 2408 {Resource: "resource-2", Version: "r2v1", CheckOrder: 1}, 2409 {Resource: "resource-2", Version: "r2v2", CheckOrder: 2}, 2410 2411 {Resource: "resource-3", Version: "r3v1", CheckOrder: 1}, 2412 {Resource: "resource-3", Version: "r3v2", CheckOrder: 2}, 2413 2414 {Resource: "resource-4", Version: "r4v1", CheckOrder: 1}, 2415 {Resource: "resource-4", Version: "r4v2", CheckOrder: 2}, 2416 2417 {Resource: "resource-5", Version: "r5v1", CheckOrder: 1}, 2418 {Resource: "resource-5", Version: "r5v2", CheckOrder: 2}, 2419 2420 {Resource: "resource-6", Version: "r6v1", CheckOrder: 1}, 2421 {Resource: "resource-6", Version: "r6v2", CheckOrder: 2}, 2422 2423 {Resource: "resource-7", Version: "r7v1", CheckOrder: 1}, 2424 {Resource: "resource-7", Version: "r7v2", CheckOrder: 2}, 2425 2426 {Resource: "resource-8", Version: "r7v1", CheckOrder: 1}, 2427 {Resource: "resource-8", Version: "r7v2", CheckOrder: 2}, 2428 2429 {Resource: "version", Version: "5.5.6-rc.22", CheckOrder: 1}, 2430 {Resource: "version", Version: "5.5.6", CheckOrder: 2}, 2431 {Resource: "version", Version: "5.5.7-rc.23", CheckOrder: 3}, 2432 {Resource: "version", Version: "5.5.7", CheckOrder: 4}, 2433 }, 2434 }, 2435 2436 Inputs: Inputs{ 2437 { 2438 Name: "version", 2439 Resource: "version", 2440 Passed: []string{"simple-a"}, 2441 }, 2442 { 2443 Name: "resource-1", 2444 Resource: "resource-1", 2445 Passed: []string{"simple-a"}, 2446 }, 2447 { 2448 Name: "resource-2", 2449 Resource: "resource-2", 2450 Passed: []string{"simple-a"}, 2451 }, 2452 { 2453 Name: "resource-3", 2454 Resource: "resource-3", 2455 Passed: []string{"simple-a"}, 2456 }, 2457 { 2458 Name: "resource-4", 2459 Resource: "resource-4", 2460 Passed: []string{"simple-a"}, 2461 }, 2462 { 2463 Name: "resource-5", 2464 Resource: "resource-5", 2465 Passed: []string{"simple-a"}, 2466 }, 2467 { 2468 Name: "resource-6", 2469 Resource: "resource-6", 2470 Passed: []string{"simple-a"}, 2471 }, 2472 { 2473 Name: "resource-7", 2474 Resource: "resource-7", 2475 Passed: []string{"simple-a"}, 2476 }, 2477 { 2478 Name: "resource-8", 2479 Resource: "resource-8", 2480 Passed: []string{"simple-a"}, 2481 }, 2482 }, 2483 2484 Result: Result{ 2485 OK: true, 2486 Values: map[string]string{ 2487 "version": "5.5.7", 2488 "resource-1": "r1v2", 2489 "resource-2": "r2v2", 2490 "resource-3": "r3v2", 2491 "resource-4": "r4v2", 2492 "resource-5": "r5v2", 2493 "resource-6": "r6v2", 2494 "resource-7": "r7v2", 2495 "resource-8": "r8v2", 2496 }, 2497 }, 2498 2499 // run this test enough times to shake out any non-deterministic ordering issues 2500 Iterations: 100, 2501 }), 2502 2503 Entry("with very every and passed, it does not use retrigger builds as latest build", Example{ 2504 DB: DB{ 2505 BuildInputs: []DBRow{ 2506 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 2507 }, 2508 2509 BuildPipes: []DBRow{ 2510 {FromBuildID: 4, ToBuildID: 100}, 2511 }, 2512 2513 BuildOutputs: []DBRow{ 2514 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2515 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2516 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2517 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 2518 {Job: "simple-a", BuildID: 5, Resource: "resource-x", Version: "rxv2", CheckOrder: 2, RerunOfBuildID: 2}, 2519 }, 2520 2521 Resources: []DBRow{ 2522 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2523 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2524 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2525 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 2526 }, 2527 }, 2528 2529 Inputs: Inputs{ 2530 { 2531 Name: "resource-x", 2532 Resource: "resource-x", 2533 Version: Version{Every: true}, 2534 Passed: []string{"simple-a"}, 2535 }, 2536 }, 2537 2538 Result: Result{ 2539 OK: true, 2540 Values: map[string]string{ 2541 "resource-x": "rxv4", 2542 }, 2543 }, 2544 }), 2545 2546 Entry("with very every and passed, it does not use retrigger builds as latest build when there are multiple passed jobs", Example{ 2547 DB: DB{ 2548 BuildInputs: []DBRow{ 2549 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 2550 }, 2551 2552 BuildPipes: []DBRow{ 2553 {FromBuildID: 4, ToBuildID: 100}, 2554 {FromBuildID: 9, ToBuildID: 100}, 2555 }, 2556 2557 BuildOutputs: []DBRow{ 2558 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2559 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2560 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2561 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 2562 {Job: "simple-a", BuildID: 5, Resource: "resource-x", Version: "rxv2", CheckOrder: 2, RerunOfBuildID: 2}, 2563 2564 {Job: "simple-b", BuildID: 6, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2565 {Job: "simple-b", BuildID: 7, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2566 {Job: "simple-b", BuildID: 8, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2567 {Job: "simple-b", BuildID: 9, Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 2568 {Job: "simple-b", BuildID: 10, Resource: "resource-x", Version: "rxv2", CheckOrder: 2, RerunOfBuildID: 7}, 2569 }, 2570 2571 Resources: []DBRow{ 2572 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2573 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2574 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2575 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 2576 }, 2577 }, 2578 2579 Inputs: Inputs{ 2580 { 2581 Name: "resource-x", 2582 Resource: "resource-x", 2583 Version: Version{Every: true}, 2584 Passed: []string{"simple-a", "simple-b"}, 2585 }, 2586 }, 2587 2588 Result: Result{ 2589 OK: true, 2590 Values: map[string]string{ 2591 "resource-x": "rxv4", 2592 }, 2593 }, 2594 }), 2595 2596 Entry("with passed constraints, it does not use the retrigger build as latest build", Example{ 2597 DB: DB{ 2598 BuildInputs: []DBRow{ 2599 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2600 }, 2601 2602 BuildPipes: []DBRow{ 2603 {FromBuildID: 1, ToBuildID: 100}, 2604 }, 2605 2606 BuildOutputs: []DBRow{ 2607 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2608 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2609 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2610 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 2611 {Job: "simple-a", BuildID: 5, Resource: "resource-x", Version: "rxv2", CheckOrder: 2, RerunOfBuildID: 2}, 2612 }, 2613 2614 Resources: []DBRow{ 2615 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2616 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2617 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2618 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 2619 }, 2620 }, 2621 2622 Inputs: Inputs{ 2623 { 2624 Name: "resource-x", 2625 Resource: "resource-x", 2626 Passed: []string{"simple-a"}, 2627 }, 2628 }, 2629 2630 Result: Result{ 2631 OK: true, 2632 Values: map[string]string{ 2633 "resource-x": "rxv4", 2634 }, 2635 }, 2636 }), 2637 2638 Entry("with multiple passed constraints, it does not use retrigger builds as latest build when there are multiple passed jobs", Example{ 2639 DB: DB{ 2640 BuildInputs: []DBRow{ 2641 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2642 }, 2643 2644 BuildPipes: []DBRow{ 2645 {FromBuildID: 1, ToBuildID: 100}, 2646 {FromBuildID: 6, ToBuildID: 100}, 2647 }, 2648 2649 BuildOutputs: []DBRow{ 2650 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2651 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2652 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2653 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 2654 {Job: "simple-a", BuildID: 5, Resource: "resource-x", Version: "rxv2", CheckOrder: 2, RerunOfBuildID: 2}, 2655 2656 {Job: "simple-b", BuildID: 6, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2657 {Job: "simple-b", BuildID: 7, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2658 {Job: "simple-b", BuildID: 8, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2659 {Job: "simple-b", BuildID: 9, Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 2660 {Job: "simple-b", BuildID: 10, Resource: "resource-x", Version: "rxv2", CheckOrder: 2, RerunOfBuildID: 7}, 2661 }, 2662 2663 Resources: []DBRow{ 2664 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2665 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2666 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2667 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 2668 }, 2669 }, 2670 2671 Inputs: Inputs{ 2672 { 2673 Name: "resource-x", 2674 Resource: "resource-x", 2675 Passed: []string{"simple-a", "simple-b"}, 2676 }, 2677 }, 2678 2679 Result: Result{ 2680 OK: true, 2681 Values: map[string]string{ 2682 "resource-x": "rxv4", 2683 }, 2684 }, 2685 }), 2686 2687 Entry("with a build that has a disabled input of the same resource, still uses the other inputs to resolve", Example{ 2688 DB: DB{ 2689 BuildInputs: []DBRow{ 2690 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2691 }, 2692 2693 BuildPipes: []DBRow{ 2694 {FromBuildID: 1, ToBuildID: 100}, 2695 }, 2696 2697 BuildOutputs: []DBRow{ 2698 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2699 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2700 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2701 }, 2702 2703 Resources: []DBRow{ 2704 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1, Disabled: true}, 2705 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2706 }, 2707 }, 2708 2709 Inputs: Inputs{ 2710 { 2711 Name: "resource-x", 2712 Resource: "resource-x", 2713 Passed: []string{"simple-a"}, 2714 }, 2715 }, 2716 2717 Result: Result{ 2718 OK: true, 2719 Values: map[string]string{ 2720 "resource-x": "rxv2", 2721 }, 2722 }, 2723 }), 2724 2725 Entry("with version every and passed and unused builds, has next is true", Example{ 2726 DB: DB{ 2727 BuildInputs: []DBRow{ 2728 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2729 }, 2730 2731 BuildPipes: []DBRow{ 2732 {FromBuildID: 1, ToBuildID: 100}, 2733 }, 2734 2735 BuildOutputs: []DBRow{ 2736 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2737 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2738 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2739 }, 2740 2741 Resources: []DBRow{ 2742 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2743 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2744 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2745 }, 2746 }, 2747 2748 Inputs: Inputs{ 2749 { 2750 Name: "resource-x", 2751 Resource: "resource-x", 2752 Version: Version{Every: true}, 2753 Passed: []string{"simple-a"}, 2754 }, 2755 }, 2756 2757 Result: Result{ 2758 OK: true, 2759 HasNext: true, 2760 Values: map[string]string{ 2761 "resource-x": "rxv2", 2762 }, 2763 }, 2764 }), 2765 2766 Entry("with version every and passed and no unused builds, has next is false", Example{ 2767 DB: DB{ 2768 BuildInputs: []DBRow{ 2769 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2770 }, 2771 2772 BuildPipes: []DBRow{ 2773 {FromBuildID: 3, ToBuildID: 100}, 2774 }, 2775 2776 BuildOutputs: []DBRow{ 2777 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2778 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2779 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2780 }, 2781 2782 Resources: []DBRow{ 2783 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2784 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2785 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2786 }, 2787 }, 2788 2789 Inputs: Inputs{ 2790 { 2791 Name: "resource-x", 2792 Resource: "resource-x", 2793 Version: Version{Every: true}, 2794 Passed: []string{"simple-a"}, 2795 }, 2796 }, 2797 2798 Result: Result{ 2799 OK: true, 2800 NoNext: true, 2801 Values: map[string]string{ 2802 "resource-x": "rxv3", 2803 }, 2804 }, 2805 }), 2806 2807 Entry("with version every and passed and the unused builds is not satisfiable, has next is false", Example{ 2808 DB: DB{ 2809 BuildInputs: []DBRow{ 2810 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2811 }, 2812 2813 BuildPipes: []DBRow{ 2814 {FromBuildID: 2, ToBuildID: 100}, 2815 }, 2816 2817 BuildOutputs: []DBRow{ 2818 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2819 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2820 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2821 }, 2822 2823 Resources: []DBRow{ 2824 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2825 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2826 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3, Disabled: true}, 2827 }, 2828 }, 2829 2830 Inputs: Inputs{ 2831 { 2832 Name: "resource-x", 2833 Resource: "resource-x", 2834 Version: Version{Every: true}, 2835 Passed: []string{"simple-a"}, 2836 }, 2837 }, 2838 2839 Result: Result{ 2840 OK: true, 2841 NoNext: true, 2842 Values: map[string]string{ 2843 "resource-x": "rxv2", 2844 }, 2845 }, 2846 }), 2847 2848 Entry("with version every and passed and multiple jobs with one that has unused builds, has next is true", Example{ 2849 DB: DB{ 2850 BuildInputs: []DBRow{ 2851 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2852 {Job: CurrentJobName, BuildID: 100, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 2853 }, 2854 2855 BuildPipes: []DBRow{ 2856 {FromBuildID: 1, ToBuildID: 100}, 2857 {FromBuildID: 4, ToBuildID: 100}, 2858 {FromBuildID: 7, ToBuildID: 100}, 2859 }, 2860 2861 BuildOutputs: []DBRow{ 2862 {Job: "simple-a", BuildID: 1, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 2863 {Job: "simple-a", BuildID: 2, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 2864 2865 {Job: "simple-b", BuildID: 4, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 2866 {Job: "simple-b", BuildID: 5, Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 2867 {Job: "simple-b", BuildID: 6, Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 2868 2869 {Job: "simple-c", BuildID: 7, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2870 {Job: "simple-c", BuildID: 8, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2871 }, 2872 2873 Resources: []DBRow{ 2874 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2875 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2876 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2877 2878 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 2879 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 2880 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 2881 }, 2882 }, 2883 2884 Inputs: Inputs{ 2885 { 2886 Name: "resource-x", 2887 Resource: "resource-x", 2888 Version: Version{Every: true}, 2889 Passed: []string{"simple-c"}, 2890 }, 2891 { 2892 Name: "resource-y", 2893 Resource: "resource-y", 2894 Version: Version{Every: true}, 2895 Passed: []string{"simple-a", "simple-b"}, 2896 }, 2897 }, 2898 2899 Result: Result{ 2900 OK: true, 2901 HasNext: true, 2902 Values: map[string]string{ 2903 "resource-x": "rxv2", 2904 "resource-y": "ryv2", 2905 }, 2906 }, 2907 }), 2908 2909 Entry("with version every and unused versions, has next is true", Example{ 2910 DB: DB{ 2911 BuildInputs: []DBRow{ 2912 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2913 }, 2914 2915 Resources: []DBRow{ 2916 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2917 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2918 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 2919 }, 2920 }, 2921 2922 Inputs: Inputs{ 2923 { 2924 Name: "resource-x", 2925 Resource: "resource-x", 2926 Version: Version{Every: true}, 2927 }, 2928 }, 2929 2930 Result: Result{ 2931 OK: true, 2932 HasNext: true, 2933 Values: map[string]string{ 2934 "resource-x": "rxv2", 2935 }, 2936 }, 2937 }), 2938 2939 Entry("with version every and no unused versions, has next is false", Example{ 2940 DB: DB{ 2941 BuildInputs: []DBRow{ 2942 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2943 }, 2944 2945 Resources: []DBRow{ 2946 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2947 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2948 }, 2949 }, 2950 2951 Inputs: Inputs{ 2952 { 2953 Name: "resource-x", 2954 Resource: "resource-x", 2955 Version: Version{Every: true}, 2956 }, 2957 }, 2958 2959 Result: Result{ 2960 OK: true, 2961 NoNext: true, 2962 Values: map[string]string{ 2963 "resource-x": "rxv2", 2964 }, 2965 }, 2966 }), 2967 2968 Entry("with version every but has never used the version before, has next is false", Example{ 2969 DB: DB{ 2970 Resources: []DBRow{ 2971 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2972 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 2973 }, 2974 }, 2975 2976 Inputs: Inputs{ 2977 { 2978 Name: "resource-x", 2979 Resource: "resource-x", 2980 Version: Version{Every: true}, 2981 }, 2982 }, 2983 2984 Result: Result{ 2985 OK: true, 2986 NoNext: true, 2987 Values: map[string]string{ 2988 "resource-x": "rxv2", 2989 }, 2990 }, 2991 }), 2992 2993 Entry("with both version every and version every with passed inputs, the has next value is recognized", Example{ 2994 DB: DB{ 2995 BuildInputs: []DBRow{ 2996 {Job: CurrentJobName, BuildID: 100, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 2997 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 2998 }, 2999 3000 BuildPipes: []DBRow{ 3001 {FromBuildID: 1, ToBuildID: 100}, 3002 }, 3003 3004 BuildOutputs: []DBRow{ 3005 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 3006 }, 3007 3008 Resources: []DBRow{ 3009 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 3010 3011 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 3012 {Resource: "resource-y", Version: "ryv2", CheckOrder: 2}, 3013 {Resource: "resource-y", Version: "ryv3", CheckOrder: 3}, 3014 }, 3015 }, 3016 3017 Inputs: Inputs{ 3018 { 3019 Name: "resource-x", 3020 Resource: "resource-x", 3021 Version: Version{Every: true}, 3022 Passed: []string{"simple-a"}, 3023 }, 3024 { 3025 Name: "resource-y", 3026 Resource: "resource-y", 3027 Version: Version{Every: true}, 3028 }, 3029 }, 3030 3031 Result: Result{ 3032 OK: true, 3033 HasNext: true, 3034 Values: map[string]string{ 3035 "resource-x": "rxv1", 3036 "resource-y": "ryv2", 3037 }, 3038 }, 3039 }), 3040 3041 Entry("when the resource does not have it's resource config scope set, it should error", Example{ 3042 DB: DB{ 3043 Resources: []DBRow{ 3044 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1, NoResourceConfigScope: true}, 3045 }, 3046 }, 3047 3048 Inputs: Inputs{ 3049 { 3050 Name: "resource-x", 3051 Resource: "resource-x", 3052 NoResourceConfigScope: true, 3053 }, 3054 }, 3055 3056 Result: Result{ 3057 OK: false, 3058 HasNext: false, 3059 Errors: map[string]string{"resource-x": "latest version of resource not found"}, 3060 }, 3061 }), 3062 3063 Entry("with version every and passed using an old version, it finds latest version ran by job", Example{ 3064 DB: DB{ 3065 BuildInputs: []DBRow{ 3066 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 3067 {Job: CurrentJobName, BuildID: 101, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 3068 {Job: CurrentJobName, BuildID: 102, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 3069 }, 3070 3071 BuildPipes: []DBRow{ 3072 {FromBuildID: 1, ToBuildID: 100}, 3073 {FromBuildID: 2, ToBuildID: 101}, 3074 {FromBuildID: 1, ToBuildID: 102}, 3075 }, 3076 3077 BuildOutputs: []DBRow{ 3078 {Job: "simple-a", BuildID: 1, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 3079 {Job: "simple-a", BuildID: 2, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 3080 {Job: "simple-a", BuildID: 3, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 3081 {Job: "simple-a", BuildID: 4, Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 3082 }, 3083 3084 Resources: []DBRow{ 3085 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 3086 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 3087 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 3088 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 3089 }, 3090 }, 3091 3092 Inputs: Inputs{ 3093 { 3094 Name: "resource-x", 3095 Resource: "resource-x", 3096 Version: Version{Every: true}, 3097 Passed: []string{"simple-a"}, 3098 }, 3099 }, 3100 3101 Result: Result{ 3102 OK: true, 3103 HasNext: true, 3104 Values: map[string]string{ 3105 "resource-x": "rxv3", 3106 }, 3107 }, 3108 }), 3109 3110 Entry("with version every without passed using an old version, it finds latest version ran by job", Example{ 3111 DB: DB{ 3112 BuildInputs: []DBRow{ 3113 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 3114 {Job: CurrentJobName, BuildID: 101, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 3115 {Job: CurrentJobName, BuildID: 102, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 3116 }, 3117 3118 Resources: []DBRow{ 3119 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 3120 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 3121 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 3122 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 3123 }, 3124 }, 3125 3126 Inputs: Inputs{ 3127 { 3128 Name: "resource-x", 3129 Resource: "resource-x", 3130 Version: Version{Every: true}, 3131 }, 3132 }, 3133 3134 Result: Result{ 3135 OK: true, 3136 HasNext: true, 3137 Values: map[string]string{ 3138 "resource-x": "rxv3", 3139 }, 3140 }, 3141 }), 3142 3143 Entry("if another job uses the same resource, that does not affect the next version found for the current job", Example{ 3144 DB: DB{ 3145 BuildInputs: []DBRow{ 3146 {Job: CurrentJobName, BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 3147 {Job: CurrentJobName, BuildID: 101, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 3148 {Job: CurrentJobName, BuildID: 102, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 3149 3150 {Job: "another-job", BuildID: 103, Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 3151 }, 3152 3153 Resources: []DBRow{ 3154 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 3155 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 3156 {Resource: "resource-x", Version: "rxv3", CheckOrder: 3}, 3157 {Resource: "resource-x", Version: "rxv4", CheckOrder: 4}, 3158 {Resource: "resource-x", Version: "rxv5", CheckOrder: 5}, 3159 }, 3160 }, 3161 3162 Inputs: Inputs{ 3163 { 3164 Name: "resource-x", 3165 Resource: "resource-x", 3166 Version: Version{Every: true}, 3167 }, 3168 }, 3169 3170 Result: Result{ 3171 OK: true, 3172 HasNext: true, 3173 Values: map[string]string{ 3174 "resource-x": "rxv3", 3175 }, 3176 }, 3177 }), 3178 3179 Entry("if the chosen version for an input with passed constraints does not exist, it will not select that version", Example{ 3180 DB: DB{ 3181 BuildInputs: []DBRow{ 3182 {Job: "another-job", BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 3183 {Job: "another-job", BuildID: 101, Resource: "resource-x", Version: "rxv2", CheckOrder: 2, DoNotInsertVersion: true}, 3184 }, 3185 Resources: []DBRow{ 3186 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 3187 }, 3188 }, 3189 3190 Inputs: Inputs{ 3191 { 3192 Name: "resource-x", 3193 Resource: "resource-x", 3194 Passed: []string{"another-job"}, 3195 }, 3196 }, 3197 3198 Result: Result{ 3199 OK: true, 3200 Values: map[string]string{ 3201 "resource-x": "rxv1", 3202 }, 3203 }, 3204 }), 3205 3206 Entry("if there are multiple inputs with the same passed constraint job and the chosen version from a build does not exist, it will not use that build", Example{ 3207 DB: DB{ 3208 BuildInputs: []DBRow{ 3209 {Job: "another-job", BuildID: 100, Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 3210 {Job: "another-job", BuildID: 101, Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 3211 3212 {Job: "another-job", BuildID: 100, Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 3213 {Job: "another-job", BuildID: 101, Resource: "resource-y", Version: "ryv2", CheckOrder: 2, DoNotInsertVersion: true}, 3214 }, 3215 3216 Resources: []DBRow{ 3217 {Resource: "resource-x", Version: "rxv1", CheckOrder: 1}, 3218 {Resource: "resource-x", Version: "rxv2", CheckOrder: 2}, 3219 {Resource: "resource-y", Version: "ryv1", CheckOrder: 1}, 3220 }, 3221 }, 3222 3223 Inputs: Inputs{ 3224 { 3225 Name: "resource-x", 3226 Resource: "resource-x", 3227 Passed: []string{"another-job"}, 3228 }, 3229 { 3230 Name: "resource-y", 3231 Resource: "resource-y", 3232 Passed: []string{"another-job"}, 3233 }, 3234 }, 3235 3236 Result: Result{ 3237 OK: true, 3238 Values: map[string]string{ 3239 "resource-x": "rxv1", 3240 "resource-y": "ryv1", 3241 }, 3242 }, 3243 }), 3244 )