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