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 })