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

     1  package gc_test
     2  
     3  import (
     4  	"context"
     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/gc"
     9  
    10  	. "github.com/onsi/ginkgo"
    11  	. "github.com/onsi/gomega"
    12  )
    13  
    14  var _ = Describe("ResourceCacheUseCollector", func() {
    15  	var collector GcCollector
    16  	var buildCollector GcCollector
    17  
    18  	BeforeEach(func() {
    19  		collector = gc.NewResourceCacheUseCollector(resourceCacheLifecycle)
    20  		buildCollector = gc.NewBuildCollector(buildFactory)
    21  	})
    22  
    23  	Describe("Run", func() {
    24  		Describe("cache uses", func() {
    25  			var (
    26  				versionedResourceType atc.VersionedResourceType
    27  			)
    28  
    29  			countResourceCacheUses := func() int {
    30  				tx, err := dbConn.Begin()
    31  				Expect(err).NotTo(HaveOccurred())
    32  				defer func() {
    33  					_ = tx.Rollback()
    34  				}()
    35  
    36  				var result int
    37  				err = psql.Select("count(*)").
    38  					From("resource_cache_uses").
    39  					RunWith(tx).
    40  					QueryRow().
    41  					Scan(&result)
    42  				Expect(err).NotTo(HaveOccurred())
    43  
    44  				return result
    45  			}
    46  
    47  			BeforeEach(func() {
    48  				versionedResourceType = atc.VersionedResourceType{
    49  					ResourceType: atc.ResourceType{
    50  						Name: "some-type",
    51  						Type: "some-base-type",
    52  						Source: atc.Source{
    53  							"some-type": "source-param",
    54  						},
    55  					},
    56  					Version: atc.Version{"some-type": "version"},
    57  				}
    58  			})
    59  
    60  			Describe("for one-off builds", func() {
    61  				BeforeEach(func() {
    62  					_, err = resourceCacheFactory.FindOrCreateResourceCache(
    63  						db.ForBuild(defaultBuild.ID()),
    64  						"some-type",
    65  						atc.Version{"some": "version"},
    66  						atc.Source{
    67  							"some": "source",
    68  						},
    69  						atc.Params{"some": "params"},
    70  						atc.VersionedResourceTypes{
    71  							versionedResourceType,
    72  						},
    73  					)
    74  					Expect(err).NotTo(HaveOccurred())
    75  				})
    76  
    77  				Context("before the build has completed", func() {
    78  					It("does not clean up the uses", func() {
    79  						Expect(countResourceCacheUses()).NotTo(BeZero())
    80  						Expect(collector.Run(context.TODO())).To(Succeed())
    81  						Expect(countResourceCacheUses()).NotTo(BeZero())
    82  					})
    83  				})
    84  
    85  				Context("once the build has completed successfully", func() {
    86  					It("cleans up the uses", func() {
    87  						Expect(countResourceCacheUses()).NotTo(BeZero())
    88  						Expect(defaultBuild.Finish(db.BuildStatusSucceeded)).To(Succeed())
    89  						Expect(buildCollector.Run(context.TODO())).To(Succeed())
    90  						Expect(collector.Run(context.TODO())).To(Succeed())
    91  						Expect(countResourceCacheUses()).To(BeZero())
    92  					})
    93  				})
    94  
    95  				Context("once the build has been aborted", func() {
    96  					It("cleans up the uses", func() {
    97  						Expect(countResourceCacheUses()).NotTo(BeZero())
    98  						Expect(defaultBuild.Finish(db.BuildStatusAborted)).To(Succeed())
    99  						Expect(buildCollector.Run(context.TODO())).To(Succeed())
   100  						Expect(collector.Run(context.TODO())).To(Succeed())
   101  						Expect(countResourceCacheUses()).To(BeZero())
   102  					})
   103  				})
   104  
   105  				Context("once the build has failed", func() {
   106  					Context("when the build is a one-off", func() {
   107  						It("cleans up the uses", func() {
   108  							Expect(countResourceCacheUses()).NotTo(BeZero())
   109  							Expect(defaultBuild.Finish(db.BuildStatusFailed)).To(Succeed())
   110  							Expect(buildCollector.Run(context.TODO())).To(Succeed())
   111  							Expect(collector.Run(context.TODO())).To(Succeed())
   112  							Expect(countResourceCacheUses()).To(BeZero())
   113  						})
   114  					})
   115  				})
   116  			})
   117  
   118  			Context("when the build is for a job", func() {
   119  				var jobBuild db.Build
   120  
   121  				BeforeEach(func() {
   122  					var err error
   123  					jobBuild, err = defaultJob.CreateBuild()
   124  					Expect(err).ToNot(HaveOccurred())
   125  
   126  					_, err = resourceCacheFactory.FindOrCreateResourceCache(
   127  						db.ForBuild(jobBuild.ID()),
   128  						"some-type",
   129  						atc.Version{"some": "version"},
   130  						atc.Source{
   131  							"some": "source",
   132  						},
   133  						atc.Params{"some": "params"},
   134  						atc.VersionedResourceTypes{
   135  							versionedResourceType,
   136  						},
   137  					)
   138  					Expect(err).NotTo(HaveOccurred())
   139  				})
   140  
   141  				Context("when it is the latest failed build", func() {
   142  					It("preserves the uses", func() {
   143  						Expect(countResourceCacheUses()).NotTo(BeZero())
   144  						Expect(jobBuild.Finish(db.BuildStatusFailed)).To(Succeed())
   145  						Expect(buildCollector.Run(context.TODO())).To(Succeed())
   146  						Expect(collector.Run(context.TODO())).To(Succeed())
   147  						Expect(countResourceCacheUses()).NotTo(BeZero())
   148  					})
   149  				})
   150  
   151  				Context("when a later build of the same job has succeeded", func() {
   152  					var secondJobBuild db.Build
   153  
   154  					BeforeEach(func() {
   155  						var err error
   156  						secondJobBuild, err = defaultJob.CreateBuild()
   157  						Expect(err).ToNot(HaveOccurred())
   158  
   159  						_, err = resourceCacheFactory.FindOrCreateResourceCache(
   160  							db.ForBuild(secondJobBuild.ID()),
   161  							"some-type",
   162  							atc.Version{"some": "version"},
   163  							atc.Source{
   164  								"some": "source",
   165  							},
   166  							atc.Params{"some": "params"},
   167  							atc.VersionedResourceTypes{
   168  								versionedResourceType,
   169  							},
   170  						)
   171  						Expect(err).NotTo(HaveOccurred())
   172  					})
   173  
   174  					It("cleans up the uses", func() {
   175  						Expect(jobBuild.Finish(db.BuildStatusFailed)).To(Succeed())
   176  						Expect(buildCollector.Run(context.TODO())).To(Succeed())
   177  						Expect(collector.Run(context.TODO())).To(Succeed())
   178  
   179  						Expect(countResourceCacheUses()).NotTo(BeZero())
   180  
   181  						Expect(secondJobBuild.Finish(db.BuildStatusSucceeded)).To(Succeed())
   182  						Expect(buildCollector.Run(context.TODO())).To(Succeed())
   183  						Expect(collector.Run(context.TODO())).To(Succeed())
   184  
   185  						Expect(countResourceCacheUses()).To(BeZero())
   186  					})
   187  				})
   188  			})
   189  
   190  			Describe("for containers", func() {
   191  				var container db.CreatingContainer
   192  
   193  				BeforeEach(func() {
   194  					worker, err := defaultTeam.SaveWorker(atc.Worker{
   195  						Name: "some-worker",
   196  					}, 0)
   197  					Expect(err).ToNot(HaveOccurred())
   198  
   199  					container, err = worker.CreateContainer(
   200  						db.NewBuildStepContainerOwner(defaultBuild.ID(), "some-plan", defaultTeam.ID()),
   201  						db.ContainerMetadata{},
   202  					)
   203  					Expect(err).ToNot(HaveOccurred())
   204  
   205  					_, err = resourceCacheFactory.FindOrCreateResourceCache(
   206  						db.ForContainer(container.ID()),
   207  						"some-type",
   208  						atc.Version{"some-type": "version"},
   209  						atc.Source{
   210  							"cache": "source",
   211  						},
   212  						atc.Params{"some": "params"},
   213  						atc.VersionedResourceTypes{
   214  							versionedResourceType,
   215  						},
   216  					)
   217  					Expect(err).NotTo(HaveOccurred())
   218  				})
   219  
   220  				Context("while the container is still in use", func() {
   221  					It("does not clean up the uses", func() {
   222  						Expect(countResourceCacheUses()).NotTo(BeZero())
   223  						Expect(collector.Run(context.TODO())).To(Succeed())
   224  						Expect(countResourceCacheUses()).NotTo(BeZero())
   225  					})
   226  				})
   227  
   228  				Context("when the container is removed", func() {
   229  					It("cleans up the uses (except it was actually a cascade delete, not the GC, lol)", func() {
   230  						Expect(countResourceCacheUses()).NotTo(BeZero())
   231  						created, err := container.Created()
   232  						Expect(err).ToNot(HaveOccurred())
   233  						destroying, err := created.Destroying()
   234  						Expect(err).ToNot(HaveOccurred())
   235  						Expect(destroying.Destroy()).To(BeTrue())
   236  						Expect(collector.Run(context.TODO())).To(Succeed())
   237  						Expect(countResourceCacheUses()).To(BeZero())
   238  					})
   239  				})
   240  			})
   241  		})
   242  	})
   243  })