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

     1  package gc_test
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"time"
     7  
     8  	"github.com/pf-qiu/concourse/v6/atc/db"
     9  	"github.com/pf-qiu/concourse/v6/atc/gc"
    10  
    11  	"code.cloudfoundry.org/lager/lagertest"
    12  	"github.com/pf-qiu/concourse/v6/atc/db/dbfakes"
    13  	. "github.com/onsi/ginkgo"
    14  	. "github.com/onsi/gomega"
    15  )
    16  
    17  var _ = Describe("ContainerCollector", func() {
    18  	var (
    19  		fakeContainerRepository *dbfakes.FakeContainerRepository
    20  		creatingContainer       *dbfakes.FakeCreatingContainer
    21  		createdContainer        *dbfakes.FakeCreatedContainer
    22  		destroyingContainer     *dbfakes.FakeDestroyingContainer
    23  
    24  		collector GcCollector
    25  
    26  		missingContainerGracePeriod time.Duration
    27  		hijackContainerGracePeriod  time.Duration
    28  	)
    29  
    30  	BeforeEach(func() {
    31  		fakeContainerRepository = new(dbfakes.FakeContainerRepository)
    32  		creatingContainer = new(dbfakes.FakeCreatingContainer)
    33  		createdContainer = new(dbfakes.FakeCreatedContainer)
    34  		destroyingContainer = new(dbfakes.FakeDestroyingContainer)
    35  
    36  		logger = lagertest.NewTestLogger("test")
    37  
    38  		missingContainerGracePeriod = 1 * time.Minute
    39  		hijackContainerGracePeriod = 1 * time.Minute
    40  
    41  		collector = gc.NewContainerCollector(
    42  			fakeContainerRepository,
    43  			missingContainerGracePeriod,
    44  			hijackContainerGracePeriod,
    45  		)
    46  	})
    47  
    48  	Describe("Run", func() {
    49  		var (
    50  			err error
    51  		)
    52  
    53  		JustBeforeEach(func() {
    54  			err = collector.Run(context.TODO())
    55  		})
    56  
    57  		It("succeeds", func() {
    58  			Expect(err).NotTo(HaveOccurred())
    59  		})
    60  
    61  		It("always tries to delete expired containers", func() {
    62  			Expect(fakeContainerRepository.RemoveMissingContainersCallCount()).To(Equal(1))
    63  			Expect(fakeContainerRepository.RemoveMissingContainersArgsForCall(0)).To(Equal(missingContainerGracePeriod))
    64  		})
    65  
    66  		Describe("Failed Containers", func() {
    67  			Context("when there are failed containers", func() {
    68  				It("tries to delete them from the database", func() {
    69  					Expect(fakeContainerRepository.DestroyFailedContainersCallCount()).To(Equal(1))
    70  				})
    71  
    72  				Context("when destroying failed containers fails", func() {
    73  					BeforeEach(func() {
    74  						fakeContainerRepository.DestroyFailedContainersReturns(
    75  							0, errors.New("You have to be able to accept failure to get better"),
    76  						)
    77  					})
    78  
    79  					It("still tries to remove the orphaned containers", func() {
    80  						Expect(fakeContainerRepository.FindOrphanedContainersCallCount()).To(Equal(1))
    81  					})
    82  				})
    83  			})
    84  		})
    85  
    86  		Describe("Orphaned Containers", func() {
    87  
    88  			var (
    89  				destroyingContainerFromCreated *dbfakes.FakeDestroyingContainer
    90  			)
    91  
    92  			BeforeEach(func() {
    93  				creatingContainer.HandleReturns("some-handle-1")
    94  				createdContainer.HandleReturns("some-handle-2")
    95  				createdContainer.WorkerNameReturns("foo")
    96  
    97  				destroyingContainerFromCreated = new(dbfakes.FakeDestroyingContainer)
    98  				createdContainer.DestroyingReturns(destroyingContainerFromCreated, nil)
    99  				destroyingContainerFromCreated.HandleReturns("some-handle-2")
   100  				destroyingContainerFromCreated.WorkerNameReturns("foo")
   101  
   102  				destroyingContainer.HandleReturns("some-handle-3")
   103  				destroyingContainer.WorkerNameReturns("bar")
   104  
   105  				fakeContainerRepository.FindOrphanedContainersReturns(
   106  					[]db.CreatingContainer{
   107  						creatingContainer,
   108  					},
   109  					[]db.CreatedContainer{
   110  						createdContainer,
   111  					},
   112  					[]db.DestroyingContainer{
   113  						destroyingContainer,
   114  					},
   115  					nil,
   116  				)
   117  			})
   118  
   119  			Context("when there are created containers that haven't been hijacked", func() {
   120  				BeforeEach(func() {
   121  					createdContainer.LastHijackReturns(time.Time{})
   122  				})
   123  
   124  				It("succeeds", func() {
   125  					Expect(err).ToNot(HaveOccurred())
   126  				})
   127  
   128  				It("marks the container as destroying", func() {
   129  					Expect(createdContainer.DestroyingCallCount()).To(Equal(1))
   130  				})
   131  			})
   132  
   133  			Context("when there are created containers that were hijacked beyond the grace period", func() {
   134  				BeforeEach(func() {
   135  					createdContainer.LastHijackReturns(time.Now().Add(-1 * time.Hour))
   136  				})
   137  
   138  				It("succeeds", func() {
   139  					Expect(err).ToNot(HaveOccurred())
   140  				})
   141  
   142  				It("marks the container as destroying", func() {
   143  					Expect(createdContainer.DestroyingCallCount()).To(Equal(1))
   144  				})
   145  			})
   146  
   147  			Context("when there are created containers hijacked recently", func() {
   148  
   149  				BeforeEach(func() {
   150  					createdContainer.LastHijackReturns(time.Now())
   151  				})
   152  
   153  				It("succeeds", func() {
   154  					Expect(err).ToNot(HaveOccurred())
   155  				})
   156  
   157  				It("does not destroy them", func() {
   158  					Expect(createdContainer.DestroyingCallCount()).To(Equal(0))
   159  				})
   160  			})
   161  
   162  			It("marks all found containers (created and destroying only, no creating) as destroying", func() {
   163  				Expect(fakeContainerRepository.FindOrphanedContainersCallCount()).To(Equal(1))
   164  
   165  				Expect(createdContainer.DestroyingCallCount()).To(Equal(1))
   166  
   167  				Expect(destroyingContainerFromCreated.DestroyCallCount()).To(Equal(0))
   168  
   169  				Expect(destroyingContainer.DestroyCallCount()).To(Equal(0))
   170  			})
   171  
   172  			Context("when finding containers for deletion fails", func() {
   173  				BeforeEach(func() {
   174  					fakeContainerRepository.FindOrphanedContainersReturns(nil, nil, nil, errors.New("some error"))
   175  				})
   176  
   177  				It("returns and logs the error", func() {
   178  					Expect(err.Error()).To(ContainSubstring("some error"))
   179  					Expect(fakeContainerRepository.FindOrphanedContainersCallCount()).To(Equal(1))
   180  				})
   181  			})
   182  		})
   183  	})
   184  })