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