github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/gc/resource_config_collector_test.go (about) 1 package gc_test 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 sq "github.com/Masterminds/squirrel" 9 "github.com/pf-qiu/concourse/v6/atc" 10 "github.com/pf-qiu/concourse/v6/atc/db" 11 "github.com/pf-qiu/concourse/v6/atc/db/dbtest" 12 "github.com/pf-qiu/concourse/v6/atc/gc" 13 14 . "github.com/onsi/ginkgo" 15 . "github.com/onsi/gomega" 16 ) 17 18 var _ = Describe("ResourceConfigCollector", func() { 19 var collector GcCollector 20 var gracePeriod = time.Hour 21 22 BeforeEach(func() { 23 collector = gc.NewResourceConfigCollector(resourceConfigFactory, gracePeriod) 24 }) 25 26 Describe("Run", func() { 27 Describe("configs", func() { 28 countResourceConfigs := func() int { 29 tx, err := dbConn.Begin() 30 Expect(err).NotTo(HaveOccurred()) 31 defer tx.Rollback() 32 33 var result int 34 err = psql.Select("count(*)"). 35 From("resource_configs"). 36 RunWith(tx). 37 QueryRow(). 38 Scan(&result) 39 Expect(err).NotTo(HaveOccurred()) 40 41 return result 42 } 43 44 Context("when the config is referenced in resource config check sessions", func() { 45 ownerExpiries := db.ContainerOwnerExpiries{ 46 Min: 5 * time.Minute, 47 Max: 10 * time.Minute, 48 } 49 50 BeforeEach(func() { 51 resourceConfig, err := resourceConfigFactory.FindOrCreateResourceConfig( 52 "some-base-type", 53 atc.Source{ 54 "some": "source", 55 }, 56 atc.VersionedResourceTypes{}, 57 ) 58 Expect(err).NotTo(HaveOccurred()) 59 60 workerFactory := db.NewWorkerFactory(dbConn) 61 defaultWorkerPayload := atc.Worker{ 62 ResourceTypes: []atc.WorkerResourceType{ 63 { 64 Type: "some-base-type", 65 Image: "/path/to/image", 66 Version: "some-brt-version", 67 }, 68 }, 69 Name: "default-worker", 70 GardenAddr: "1.2.3.4:7777", 71 BaggageclaimURL: "5.6.7.8:7878", 72 } 73 worker, err := workerFactory.SaveWorker(defaultWorkerPayload, 0) 74 Expect(err).NotTo(HaveOccurred()) 75 76 _, err = worker.CreateContainer(db.NewResourceConfigCheckSessionContainerOwner(resourceConfig.ID(), resourceConfig.OriginBaseResourceType().ID, ownerExpiries), db.ContainerMetadata{}) 77 Expect(err).NotTo(HaveOccurred()) 78 }) 79 80 It("preserves the config", func() { 81 Expect(countResourceConfigs()).ToNot(BeZero()) 82 Expect(collector.Run(context.TODO())).To(Succeed()) 83 Expect(countResourceConfigs()).ToNot(BeZero()) 84 }) 85 }) 86 87 Context("when config is referenced in resource caches", func() { 88 BeforeEach(func() { 89 _, err = resourceCacheFactory.FindOrCreateResourceCache( 90 db.ForBuild(defaultBuild.ID()), 91 "some-base-type", 92 atc.Version{"some": "version"}, 93 atc.Source{ 94 "some": "source", 95 }, 96 nil, 97 atc.VersionedResourceTypes{}, 98 ) 99 Expect(err).NotTo(HaveOccurred()) 100 }) 101 102 It("preserve the config", func() { 103 Expect(countResourceConfigs()).NotTo(BeZero()) 104 Expect(collector.Run(context.TODO())).To(Succeed()) 105 Expect(countResourceConfigs()).NotTo(BeZero()) 106 }) 107 }) 108 109 Context("when config is not referenced in resource caches", func() { 110 BeforeEach(func() { 111 _, err = resourceCacheFactory.FindOrCreateResourceCache( 112 db.ForBuild(defaultBuild.ID()), 113 "some-base-type", 114 atc.Version{"some": "version"}, 115 atc.Source{ 116 "some": "source", 117 }, 118 nil, 119 atc.VersionedResourceTypes{}, 120 ) 121 Expect(err).NotTo(HaveOccurred()) 122 123 tx, err := dbConn.Begin() 124 Expect(err).NotTo(HaveOccurred()) 125 defer tx.Rollback() 126 _, err = psql.Delete("resource_cache_uses").RunWith(tx).Exec() 127 _, err = psql.Delete("resource_caches").RunWith(tx).Exec() 128 Expect(err).NotTo(HaveOccurred()) 129 Expect(tx.Commit()).To(Succeed()) 130 }) 131 132 It("cleans up the config", func() { 133 Expect(countResourceConfigs()).NotTo(BeZero()) 134 Expect(collector.Run(context.TODO())).To(Succeed()) 135 Expect(countResourceConfigs()).To(BeZero()) 136 }) 137 }) 138 139 Context("when config is referenced in resources", func() { 140 BeforeEach(func() { 141 dbtest.Setup( 142 builder.WithPipeline(atc.Config{ 143 Resources: atc.ResourceConfigs{ 144 { 145 Name: "some-resource", 146 Type: "some-base-type", 147 Source: atc.Source{"some": "source"}, 148 }, 149 }, 150 }), 151 builder.WithResourceVersions("some-resource"), 152 ) 153 }) 154 155 It("preserve the config", func() { 156 Expect(countResourceConfigs()).NotTo(BeZero()) 157 Expect(collector.Run(context.TODO())).To(Succeed()) 158 Expect(countResourceConfigs()).NotTo(BeZero()) 159 }) 160 }) 161 162 Context("when config is not referenced in resources", func() { 163 var resourceConfig db.ResourceConfig 164 165 BeforeEach(func() { 166 var err error 167 resourceConfig, err = resourceConfigFactory.FindOrCreateResourceConfig( 168 "some-base-type", 169 atc.Source{"some": "source"}, 170 atc.VersionedResourceTypes{}, 171 ) 172 Expect(err).NotTo(HaveOccurred()) 173 }) 174 175 It("spares the config until the grace period elapses", func() { 176 Expect(countResourceConfigs()).NotTo(BeZero()) 177 Expect(collector.Run(context.TODO())).To(Succeed()) 178 Expect(countResourceConfigs()).NotTo(BeZero()) 179 180 // tightly coupled but better than a flaky sleep test. :/ 181 _, err := psql.Update("resource_configs"). 182 Set( 183 "last_referenced", 184 sq.Expr(fmt.Sprintf("now() - '%d seconds'::interval", int(gracePeriod.Seconds()))), 185 ). 186 Where(sq.Eq{"id": resourceConfig.ID()}). 187 RunWith(dbConn). 188 Exec() 189 Expect(err).ToNot(HaveOccurred()) 190 191 Expect(collector.Run(context.TODO())).To(Succeed()) 192 Expect(countResourceConfigs()).To(BeZero()) 193 }) 194 }) 195 196 Context("when config is referenced in resource types", func() { 197 BeforeEach(func() { 198 dbtest.Setup( 199 builder.WithPipeline(atc.Config{ 200 ResourceTypes: atc.ResourceTypes{ 201 { 202 Name: "some-resource-type", 203 Type: "some-base-type", 204 Source: atc.Source{"some": "source-type"}, 205 }, 206 }, 207 }), 208 builder.WithResourceTypeVersions("some-resource-type"), 209 ) 210 }) 211 212 It("preserve the config", func() { 213 Expect(countResourceConfigs()).NotTo(BeZero()) 214 Expect(collector.Run(context.TODO())).To(Succeed()) 215 Expect(countResourceConfigs()).NotTo(BeZero()) 216 }) 217 }) 218 219 Context("when config is not referenced in resource types", func() { 220 var resourceConfig db.ResourceConfig 221 222 BeforeEach(func() { 223 var err error 224 resourceConfig, err = resourceConfigFactory.FindOrCreateResourceConfig( 225 "some-base-type", 226 atc.Source{"some": "source-type"}, 227 atc.VersionedResourceTypes{}, 228 ) 229 Expect(err).NotTo(HaveOccurred()) 230 _, err = usedResourceType.Reload() 231 Expect(err).NotTo(HaveOccurred()) 232 }) 233 234 It("spares the config until the grace period elapses", func() { 235 Expect(countResourceConfigs()).NotTo(BeZero()) 236 Expect(collector.Run(context.TODO())).To(Succeed()) 237 Expect(countResourceConfigs()).NotTo(BeZero()) 238 239 // tightly coupled but better than a flaky sleep test. :/ 240 _, err := psql.Update("resource_configs"). 241 Set( 242 "last_referenced", 243 sq.Expr(fmt.Sprintf("now() - '%d seconds'::interval", int(gracePeriod.Seconds()))), 244 ). 245 Where(sq.Eq{"id": resourceConfig.ID()}). 246 RunWith(dbConn). 247 Exec() 248 Expect(err).ToNot(HaveOccurred()) 249 250 Expect(collector.Run(context.TODO())).To(Succeed()) 251 Expect(countResourceConfigs()).To(BeZero()) 252 }) 253 }) 254 }) 255 }) 256 })