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  )