github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/db/container_test.go (about) 1 package db_test 2 3 import ( 4 sq "github.com/Masterminds/squirrel" 5 "github.com/pf-qiu/concourse/v6/atc" 6 "github.com/pf-qiu/concourse/v6/atc/db" 7 . "github.com/onsi/ginkgo" 8 . "github.com/onsi/gomega" 9 ) 10 11 var _ = Describe("Container", func() { 12 var ( 13 creatingContainer db.CreatingContainer 14 expectedHandles []string 15 build db.Build 16 ) 17 18 var safelyCloseConection = func() { 19 BeforeEach(func() { 20 _ = dbConn.Close() 21 }) 22 AfterEach(func() { 23 dbConn = postgresRunner.OpenConn() 24 }) 25 } 26 27 BeforeEach(func() { 28 var err error 29 build, err = defaultTeam.CreateOneOffBuild() 30 Expect(err).NotTo(HaveOccurred()) 31 32 creatingContainer, err = defaultWorker.CreateContainer( 33 db.NewBuildStepContainerOwner(build.ID(), "some-plan", defaultTeam.ID()), 34 fullMetadata, 35 ) 36 Expect(err).ToNot(HaveOccurred()) 37 }) 38 39 Describe("Metadata", func() { 40 It("returns the container metadata", func() { 41 Expect(creatingContainer.Metadata()).To(Equal(fullMetadata)) 42 }) 43 }) 44 45 Describe("Created", func() { 46 Context("when the container is already created", func() { 47 var createdContainer db.CreatedContainer 48 49 BeforeEach(func() { 50 var err error 51 createdContainer, err = creatingContainer.Created() 52 Expect(err).NotTo(HaveOccurred()) 53 }) 54 55 It("returns a created container and no error", func() { 56 Expect(createdContainer).NotTo(BeNil()) 57 }) 58 59 Describe("Volumes", func() { 60 BeforeEach(func() { 61 creatingVolume1, err := volumeRepository.CreateContainerVolume(defaultTeam.ID(), defaultWorker.Name(), creatingContainer, "some-path-1") 62 Expect(err).NotTo(HaveOccurred()) 63 _, err = creatingVolume1.Created() 64 Expect(err).NotTo(HaveOccurred()) 65 expectedHandles = append(expectedHandles, creatingVolume1.Handle()) 66 67 creatingVolume2, err := volumeRepository.CreateContainerVolume(defaultTeam.ID(), defaultWorker.Name(), creatingContainer, "some-path-2") 68 Expect(err).NotTo(HaveOccurred()) 69 _, err = creatingVolume2.Created() 70 Expect(err).NotTo(HaveOccurred()) 71 expectedHandles = append(expectedHandles, creatingVolume2.Handle()) 72 73 createdContainer, err = creatingContainer.Created() 74 Expect(err).NotTo(HaveOccurred()) 75 }) 76 77 It("returns created container volumes", func() { 78 volumes, err := volumeRepository.FindVolumesForContainer(createdContainer) 79 Expect(err).NotTo(HaveOccurred()) 80 Expect(volumes).To(HaveLen(2)) 81 Expect([]string{volumes[0].Handle(), volumes[1].Handle()}).To(ConsistOf(expectedHandles)) 82 Expect([]string{volumes[0].Path(), volumes[1].Path()}).To(ConsistOf("some-path-1", "some-path-2")) 83 }) 84 }) 85 86 Describe("Metadata", func() { 87 It("returns the container metadata", func() { 88 Expect(createdContainer.Metadata()).To(Equal(fullMetadata)) 89 }) 90 }) 91 }) 92 }) 93 94 Describe("Destroying", func() { 95 Context("when the container is already in destroying state", func() { 96 var createdContainer db.CreatedContainer 97 var destroyingContainer db.DestroyingContainer 98 99 BeforeEach(func() { 100 var err error 101 createdContainer, err = creatingContainer.Created() 102 Expect(err).NotTo(HaveOccurred()) 103 104 destroyingContainer, err = createdContainer.Destroying() 105 Expect(err).NotTo(HaveOccurred()) 106 }) 107 108 It("returns a destroying container and no error", func() { 109 Expect(destroyingContainer).NotTo(BeNil()) 110 }) 111 112 Describe("Metadata", func() { 113 It("returns the container metadata", func() { 114 Expect(destroyingContainer.Metadata()).To(Equal(fullMetadata)) 115 }) 116 }) 117 }) 118 }) 119 120 Describe("Failed", func() { 121 var failedContainer db.FailedContainer 122 var failedErr error 123 var failedContainerHandles []string 124 125 Context("db conn is closed", func() { 126 safelyCloseConection() 127 It("returns an error", func() { 128 failedContainer, failedErr = creatingContainer.Failed() 129 Expect(failedContainer).To(BeNil()) 130 Expect(failedErr).To(HaveOccurred()) 131 }) 132 }) 133 134 Context("db conn is good", func() { 135 JustBeforeEach(func() { 136 By("transition to failed") 137 failedContainer, failedErr = creatingContainer.Failed() 138 139 rows, err := psql.Select("handle"). 140 From("containers"). 141 Where(sq.Eq{"state": atc.ContainerStateFailed}). 142 RunWith(dbConn). 143 Query() 144 Expect(err).NotTo(HaveOccurred()) 145 146 for rows.Next() { 147 var handle = "handle" 148 columns := []interface{}{&handle} 149 150 err = rows.Scan(columns...) 151 Expect(err).NotTo(HaveOccurred()) 152 153 failedContainerHandles = append(failedContainerHandles, handle) 154 } 155 }) 156 157 BeforeEach(func() { 158 failedErr = nil 159 failedContainerHandles = []string{} 160 }) 161 162 Context("when the container is in the creating state", func() { 163 It("makes the state failed", func() { 164 Expect(failedContainerHandles).To(HaveLen(1)) 165 Expect(failedContainerHandles).To(ContainElement(failedContainer.Handle())) 166 }) 167 168 It("does not return an error", func() { 169 Expect(failedErr).ToNot(HaveOccurred()) 170 }) 171 }) 172 173 Context("when the container is already in failed state", func() { 174 BeforeEach(func() { 175 _, err := creatingContainer.Failed() 176 Expect(err).ToNot(HaveOccurred()) 177 }) 178 179 It("keeps the state failed", func() { 180 Expect(failedContainerHandles).To(HaveLen(1)) 181 Expect(failedContainerHandles).To(ContainElement(failedContainer.Handle())) 182 }) 183 184 It("does not return an error", func() { 185 Expect(failedErr).ToNot(HaveOccurred()) 186 }) 187 }) 188 189 Context("when the container is actually in created state", func() { 190 BeforeEach(func() { 191 c, err := creatingContainer.Created() 192 Expect(err).ToNot(HaveOccurred()) 193 Expect(c.Handle()).NotTo(BeNil()) 194 }) 195 196 It("does not mark it as failed", func() { 197 Expect(failedContainerHandles).To(HaveLen(0)) 198 Expect(failedContainer).To(BeNil()) 199 }) 200 }) 201 202 Context("when the container is actually in destroying state", func() { 203 BeforeEach(func() { 204 createdContainer, err := creatingContainer.Created() 205 Expect(err).ToNot(HaveOccurred()) 206 207 _, err = createdContainer.Destroying() 208 Expect(err).ToNot(HaveOccurred()) 209 }) 210 211 It("does not mark it as failed", func() { 212 Expect(failedContainerHandles).To(HaveLen(0)) 213 Expect(failedContainer).To(BeNil()) 214 }) 215 216 It("returns an error", func() { 217 Expect(failedErr).To(HaveOccurred()) 218 }) 219 }) 220 }) 221 }) 222 223 Describe("Destroy", func() { 224 var destroyErr error 225 var destroyed bool 226 227 Context("called on a destroying container", func() { 228 var destroyingContainer db.DestroyingContainer 229 BeforeEach(func() { 230 createdContainer, err := creatingContainer.Created() 231 Expect(err).ToNot(HaveOccurred()) 232 destroyingContainer, err = createdContainer.Destroying() 233 Expect(err).ToNot(HaveOccurred()) 234 }) 235 236 JustBeforeEach(func() { 237 destroyed, destroyErr = destroyingContainer.Destroy() 238 }) 239 240 It("successfully removes the row from the db", func() { 241 Expect(destroyed).To(BeTrue()) 242 Expect(destroyErr).ToNot(HaveOccurred()) 243 }) 244 245 Context("errors", func() { 246 Context("when the db connection is closed", func() { 247 safelyCloseConection() 248 It("returns an error", func() { 249 Expect(destroyErr).To(HaveOccurred()) 250 }) 251 }) 252 Context("when the container dissapears from the db", func() { 253 BeforeEach(func() { 254 _, err := psql.Delete("containers"). 255 Where(sq.Eq{"handle": destroyingContainer.Handle()}). 256 RunWith(dbConn). 257 Exec() 258 Expect(err).NotTo(HaveOccurred()) 259 }) 260 261 It("returns an error", func() { 262 Expect(destroyErr).To(HaveOccurred()) 263 }) 264 }) 265 }) 266 }) 267 268 Context("called on a failed container", func() { 269 var failedContainer db.FailedContainer 270 271 BeforeEach(func() { 272 var err error 273 failedContainer, err = creatingContainer.Failed() 274 Expect(err).ToNot(HaveOccurred()) 275 }) 276 277 JustBeforeEach(func() { 278 destroyed, destroyErr = failedContainer.Destroy() 279 }) 280 281 It("successfully removes the row from the db", func() { 282 Expect(destroyed).To(BeTrue()) 283 Expect(destroyErr).ToNot(HaveOccurred()) 284 }) 285 286 Context("errors", func() { 287 Context("when the db connection is closed", func() { 288 safelyCloseConection() 289 It("returns an error", func() { 290 Expect(destroyErr).To(HaveOccurred()) 291 }) 292 }) 293 294 Context("when the container dissapears from the db", func() { 295 BeforeEach(func() { 296 _, err := failedContainer.Destroy() 297 Expect(err).ToNot(HaveOccurred()) 298 }) 299 300 It("returns an error", func() { 301 Expect(destroyErr).To(HaveOccurred()) 302 }) 303 }) 304 }) 305 }) 306 }) 307 })