github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/db/resource_config_scope_test.go (about)

     1  package db_test
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/pf-qiu/concourse/v6/atc"
     7  	"github.com/pf-qiu/concourse/v6/atc/db"
     8  	"github.com/pf-qiu/concourse/v6/atc/db/dbtest"
     9  	"github.com/pf-qiu/concourse/v6/atc/db/lock"
    10  	. "github.com/onsi/ginkgo"
    11  	. "github.com/onsi/gomega"
    12  )
    13  
    14  var _ = Describe("Resource Config Scope", func() {
    15  	var scenario *dbtest.Scenario
    16  	var resourceScope db.ResourceConfigScope
    17  
    18  	BeforeEach(func() {
    19  		scenario = dbtest.Setup(
    20  			builder.WithPipeline(atc.Config{
    21  				Resources: atc.ResourceConfigs{
    22  					{
    23  						Name: "some-resource",
    24  						Type: "some-base-resource-type",
    25  						Source: atc.Source{
    26  							"some": "source",
    27  						},
    28  					},
    29  				},
    30  				Jobs: atc.JobConfigs{
    31  					{
    32  						Name: "some-job",
    33  						PlanSequence: []atc.Step{
    34  							{
    35  								Config: &atc.GetStep{
    36  									Name: "some-resource",
    37  								},
    38  							},
    39  						},
    40  					},
    41  					{
    42  						Name: "downstream-job",
    43  						PlanSequence: []atc.Step{
    44  							{
    45  								Config: &atc.GetStep{
    46  									Name:   "some-resource",
    47  									Passed: []string{"some-job"},
    48  								},
    49  							},
    50  						},
    51  					},
    52  					{
    53  						Name: "some-other-job",
    54  					},
    55  				},
    56  			}),
    57  			builder.WithResourceVersions("some-resource"),
    58  		)
    59  
    60  		rc, found, err := resourceConfigFactory.FindResourceConfigByID(scenario.Resource("some-resource").ResourceConfigID())
    61  		Expect(err).ToNot(HaveOccurred())
    62  		Expect(found).To(BeTrue())
    63  
    64  		resourceScope, err = rc.FindOrCreateScope(scenario.Resource("some-resource"))
    65  		Expect(err).ToNot(HaveOccurred())
    66  	})
    67  
    68  	Describe("SaveVersions", func() {
    69  		var (
    70  			originalVersionSlice []atc.Version
    71  		)
    72  
    73  		BeforeEach(func() {
    74  			originalVersionSlice = []atc.Version{
    75  				{"ref": "v1"},
    76  				{"ref": "v3"},
    77  			}
    78  		})
    79  
    80  		// XXX: Can make test more resilient if there is a method that gives all versions by descending check order
    81  		It("ensures versioned resources have the correct check_order", func() {
    82  			err := resourceScope.SaveVersions(nil, originalVersionSlice)
    83  			Expect(err).ToNot(HaveOccurred())
    84  
    85  			latestVR, found, err := resourceScope.LatestVersion()
    86  			Expect(err).ToNot(HaveOccurred())
    87  			Expect(found).To(BeTrue())
    88  
    89  			Expect(latestVR.Version()).To(Equal(db.Version{"ref": "v3"}))
    90  			Expect(latestVR.CheckOrder()).To(Equal(2))
    91  
    92  			pretendCheckResults := []atc.Version{
    93  				{"ref": "v2"},
    94  				{"ref": "v3"},
    95  			}
    96  
    97  			err = resourceScope.SaveVersions(nil, pretendCheckResults)
    98  			Expect(err).ToNot(HaveOccurred())
    99  
   100  			latestVR, found, err = resourceScope.LatestVersion()
   101  			Expect(err).ToNot(HaveOccurred())
   102  			Expect(found).To(BeTrue())
   103  
   104  			Expect(latestVR.Version()).To(Equal(db.Version{"ref": "v3"}))
   105  			Expect(latestVR.CheckOrder()).To(Equal(4))
   106  		})
   107  
   108  		Context("when the versions already exists", func() {
   109  			var newVersionSlice []atc.Version
   110  
   111  			BeforeEach(func() {
   112  				newVersionSlice = []atc.Version{
   113  					{"ref": "v1"},
   114  					{"ref": "v3"},
   115  				}
   116  
   117  				err := resourceScope.SaveVersions(nil, originalVersionSlice)
   118  				Expect(err).ToNot(HaveOccurred())
   119  
   120  				latestVR, found, err := resourceScope.LatestVersion()
   121  				Expect(err).ToNot(HaveOccurred())
   122  				Expect(found).To(BeTrue())
   123  
   124  				Expect(latestVR.Version()).To(Equal(db.Version{"ref": "v3"}))
   125  				Expect(latestVR.CheckOrder()).To(Equal(2))
   126  			})
   127  
   128  			It("does not change the check order", func() {
   129  				err := resourceScope.SaveVersions(nil, newVersionSlice)
   130  				Expect(err).ToNot(HaveOccurred())
   131  
   132  				latestVR, found, err := resourceScope.LatestVersion()
   133  				Expect(err).ToNot(HaveOccurred())
   134  				Expect(found).To(BeTrue())
   135  
   136  				Expect(latestVR.Version()).To(Equal(db.Version{"ref": "v3"}))
   137  				Expect(latestVR.CheckOrder()).To(Equal(2))
   138  			})
   139  
   140  			Context("when a new version is added", func() {
   141  				It("requests schedule on the jobs that use the resource", func() {
   142  					err := resourceScope.SaveVersions(nil, originalVersionSlice)
   143  					Expect(err).ToNot(HaveOccurred())
   144  
   145  					requestedSchedule := scenario.Job("some-job").ScheduleRequestedTime()
   146  
   147  					newVersions := []atc.Version{
   148  						{"ref": "v0"},
   149  						{"ref": "v3"},
   150  					}
   151  					err = resourceScope.SaveVersions(nil, newVersions)
   152  					Expect(err).ToNot(HaveOccurred())
   153  
   154  					Expect(scenario.Job("some-job").ScheduleRequestedTime()).Should(BeTemporally(">", requestedSchedule))
   155  				})
   156  
   157  				It("does not request schedule on the jobs that use the resource but through passed constraints", func() {
   158  					err := resourceScope.SaveVersions(nil, originalVersionSlice)
   159  					Expect(err).ToNot(HaveOccurred())
   160  
   161  					requestedSchedule := scenario.Job("downstream-job").ScheduleRequestedTime()
   162  
   163  					newVersions := []atc.Version{
   164  						{"ref": "v0"},
   165  						{"ref": "v3"},
   166  					}
   167  					err = resourceScope.SaveVersions(nil, newVersions)
   168  					Expect(err).ToNot(HaveOccurred())
   169  
   170  					Expect(scenario.Job("downstream-job").ScheduleRequestedTime()).Should(BeTemporally("==", requestedSchedule))
   171  				})
   172  
   173  				It("does not request schedule on the jobs that do not use the resource", func() {
   174  					err := resourceScope.SaveVersions(nil, originalVersionSlice)
   175  					Expect(err).ToNot(HaveOccurred())
   176  
   177  					requestedSchedule := scenario.Job("some-other-job").ScheduleRequestedTime()
   178  
   179  					newVersions := []atc.Version{
   180  						{"ref": "v0"},
   181  						{"ref": "v3"},
   182  					}
   183  					err = resourceScope.SaveVersions(nil, newVersions)
   184  					Expect(err).ToNot(HaveOccurred())
   185  
   186  					Expect(scenario.Job("some-other-job").ScheduleRequestedTime()).Should(BeTemporally("==", requestedSchedule))
   187  				})
   188  			})
   189  		})
   190  	})
   191  
   192  	Describe("LatestVersion", func() {
   193  		Context("when the resource config exists", func() {
   194  			var latestCV db.ResourceConfigVersion
   195  
   196  			BeforeEach(func() {
   197  				originalVersionSlice := []atc.Version{
   198  					{"ref": "v1"},
   199  					{"ref": "v3"},
   200  				}
   201  
   202  				err := resourceScope.SaveVersions(nil, originalVersionSlice)
   203  				Expect(err).ToNot(HaveOccurred())
   204  
   205  				var found bool
   206  				latestCV, found, err = resourceScope.LatestVersion()
   207  				Expect(err).ToNot(HaveOccurred())
   208  				Expect(found).To(BeTrue())
   209  			})
   210  
   211  			It("gets latest version of resource", func() {
   212  				Expect(latestCV.Version()).To(Equal(db.Version{"ref": "v3"}))
   213  				Expect(latestCV.CheckOrder()).To(Equal(2))
   214  			})
   215  
   216  			It("disabled versions do not affect fetching the latest version", func() {
   217  				err := resourceScope.SaveVersions(nil, []atc.Version{{"version": "1"}})
   218  				Expect(err).ToNot(HaveOccurred())
   219  
   220  				savedRCV, found, err := resourceScope.LatestVersion()
   221  				Expect(err).ToNot(HaveOccurred())
   222  				Expect(found).To(BeTrue())
   223  
   224  				Expect(savedRCV.Version()).To(Equal(db.Version{"version": "1"}))
   225  
   226  				scenario.Run(builder.WithDisabledVersion("some-resource", atc.Version(savedRCV.Version())))
   227  
   228  				latestVR, found, err := resourceScope.LatestVersion()
   229  				Expect(err).ToNot(HaveOccurred())
   230  				Expect(found).To(BeTrue())
   231  				Expect(latestVR.Version()).To(Equal(db.Version{"version": "1"}))
   232  
   233  				scenario.Run(builder.WithEnabledVersion("some-resource", atc.Version(savedRCV.Version())))
   234  
   235  				latestVR, found, err = resourceScope.LatestVersion()
   236  				Expect(err).ToNot(HaveOccurred())
   237  				Expect(found).To(BeTrue())
   238  				Expect(latestVR.Version()).To(Equal(db.Version{"version": "1"}))
   239  			})
   240  
   241  			It("saving versioned resources updates the latest versioned resource", func() {
   242  				err := resourceScope.SaveVersions(nil, []atc.Version{{"ref": "4"}, {"ref": "5"}})
   243  				Expect(err).ToNot(HaveOccurred())
   244  
   245  				savedVR, found, err := resourceScope.LatestVersion()
   246  				Expect(err).ToNot(HaveOccurred())
   247  				Expect(found).To(BeTrue())
   248  
   249  				Expect(savedVR.Version()).To(Equal(db.Version{"ref": "5"}))
   250  			})
   251  		})
   252  	})
   253  
   254  	Describe("FindVersion", func() {
   255  		BeforeEach(func() {
   256  			originalVersionSlice := []atc.Version{
   257  				{"ref": "v1"},
   258  				{"ref": "v3"},
   259  			}
   260  
   261  			err := resourceScope.SaveVersions(nil, originalVersionSlice)
   262  			Expect(err).ToNot(HaveOccurred())
   263  		})
   264  
   265  		Context("when the version exists", func() {
   266  			var latestCV db.ResourceConfigVersion
   267  
   268  			BeforeEach(func() {
   269  				var err error
   270  				var found bool
   271  				latestCV, found, err = resourceScope.FindVersion(atc.Version{"ref": "v1"})
   272  				Expect(err).ToNot(HaveOccurred())
   273  				Expect(found).To(BeTrue())
   274  			})
   275  
   276  			It("gets the version of resource", func() {
   277  				Expect(latestCV.Version()).To(Equal(db.Version{"ref": "v1"}))
   278  				Expect(latestCV.CheckOrder()).To(Equal(1))
   279  			})
   280  		})
   281  
   282  		Context("when the version does not exist", func() {
   283  			var found bool
   284  			var latestCV db.ResourceConfigVersion
   285  
   286  			BeforeEach(func() {
   287  				var err error
   288  				latestCV, found, err = resourceScope.FindVersion(atc.Version{"ref": "v2"})
   289  				Expect(err).ToNot(HaveOccurred())
   290  			})
   291  
   292  			It("does not get the version of resource", func() {
   293  				Expect(found).To(BeFalse())
   294  				Expect(latestCV).To(BeNil())
   295  			})
   296  		})
   297  	})
   298  
   299  	Describe("UpdateLastCheckStartTime", func() {
   300  		It("updates last check start time", func() {
   301  			lastTime := scenario.Resource("some-resource").LastCheckEndTime()
   302  
   303  			updated, err := resourceScope.UpdateLastCheckStartTime()
   304  			Expect(err).ToNot(HaveOccurred())
   305  			Expect(updated).To(BeTrue())
   306  
   307  			Expect(scenario.Resource("some-resource").LastCheckStartTime()).To(BeTemporally(">", lastTime))
   308  		})
   309  	})
   310  
   311  	Describe("UpdateLastCheckEndTime", func() {
   312  		It("updates last check end time", func() {
   313  			lastTime := scenario.Resource("some-resource").LastCheckEndTime()
   314  
   315  			updated, err := resourceScope.UpdateLastCheckEndTime()
   316  			Expect(err).ToNot(HaveOccurred())
   317  			Expect(updated).To(BeTrue())
   318  
   319  			Expect(scenario.Resource("some-resource").LastCheckEndTime()).To(BeTemporally(">", lastTime))
   320  		})
   321  	})
   322  
   323  	Describe("AcquireResourceCheckingLock", func() {
   324  		Context("when there has been a check recently", func() {
   325  			var lock lock.Lock
   326  			var err error
   327  
   328  			BeforeEach(func() {
   329  				var err error
   330  				var acquired bool
   331  				lock, acquired, err = resourceScope.AcquireResourceCheckingLock(logger)
   332  				Expect(err).ToNot(HaveOccurred())
   333  				Expect(acquired).To(BeTrue())
   334  			})
   335  
   336  			AfterEach(func() {
   337  				_ = lock.Release()
   338  			})
   339  
   340  			It("does not get the lock", func() {
   341  				_, acquired, err := resourceScope.AcquireResourceCheckingLock(logger)
   342  				Expect(err).ToNot(HaveOccurred())
   343  				Expect(acquired).To(BeFalse())
   344  			})
   345  
   346  			Context("and the lock gets released", func() {
   347  				BeforeEach(func() {
   348  					err = lock.Release()
   349  					Expect(err).ToNot(HaveOccurred())
   350  				})
   351  
   352  				It("gets the lock", func() {
   353  					lock, acquired, err := resourceScope.AcquireResourceCheckingLock(logger)
   354  					Expect(err).ToNot(HaveOccurred())
   355  					Expect(acquired).To(BeTrue())
   356  
   357  					err = lock.Release()
   358  					Expect(err).ToNot(HaveOccurred())
   359  				})
   360  			})
   361  		})
   362  
   363  		Context("when there has not been a check recently", func() {
   364  			It("gets and keeps the lock and stops others from periodically getting it", func() {
   365  				lock, acquired, err := resourceScope.AcquireResourceCheckingLock(logger)
   366  				Expect(err).ToNot(HaveOccurred())
   367  				Expect(acquired).To(BeTrue())
   368  
   369  				Consistently(func() bool {
   370  					_, acquired, err = resourceScope.AcquireResourceCheckingLock(logger)
   371  					Expect(err).ToNot(HaveOccurred())
   372  
   373  					return acquired
   374  				}, 1500*time.Millisecond, 100*time.Millisecond).Should(BeFalse())
   375  
   376  				err = lock.Release()
   377  				Expect(err).ToNot(HaveOccurred())
   378  
   379  				time.Sleep(time.Second)
   380  
   381  				lock, acquired, err = resourceScope.AcquireResourceCheckingLock(logger)
   382  				Expect(err).ToNot(HaveOccurred())
   383  				Expect(acquired).To(BeTrue())
   384  
   385  				err = lock.Release()
   386  				Expect(err).ToNot(HaveOccurred())
   387  			})
   388  		})
   389  	})
   390  })