github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/fly/integration/check_resource_test.go (about) 1 package integration_test 2 3 import ( 4 "net/http" 5 "os/exec" 6 7 "github.com/pf-qiu/concourse/v6/atc" 8 "github.com/pf-qiu/concourse/v6/atc/event" 9 . "github.com/onsi/ginkgo" 10 . "github.com/onsi/gomega" 11 12 "github.com/onsi/gomega/gbytes" 13 "github.com/onsi/gomega/gexec" 14 "github.com/onsi/gomega/ghttp" 15 ) 16 17 var _ = Describe("CheckResource", func() { 18 var ( 19 flyCmd *exec.Cmd 20 build atc.Build 21 resource atc.Resource 22 resourceTypes atc.VersionedResourceTypes 23 expectedURL string 24 expectedQueryParams string 25 ) 26 27 BeforeEach(func() { 28 build = atc.Build{ 29 ID: 123, 30 Status: "started", 31 StartTime: 100000000000, 32 } 33 34 resource = atc.Resource{ 35 Name: "myresource", 36 Type: "myresourcetype", 37 } 38 39 resourceTypes = atc.VersionedResourceTypes{{ 40 ResourceType: atc.ResourceType{ 41 Name: "myresourcetype", 42 Type: "mybaseresourcetype", 43 }, 44 }} 45 46 expectedURL = "/api/v1/teams/main/pipelines/mypipeline/resources/myresource/check" 47 expectedQueryParams = "instance_vars=%7B%22branch%22%3A%22master%22%7D" 48 }) 49 50 Context("when ATC request succeeds", func() { 51 BeforeEach(func() { 52 atcServer.AppendHandlers( 53 ghttp.CombineHandlers( 54 ghttp.VerifyRequest("POST", expectedURL, expectedQueryParams), 55 ghttp.VerifyJSON(`{"from":{"ref":"fake-ref"}}`), 56 ghttp.RespondWithJSONEncoded(http.StatusOK, build), 57 ), 58 ) 59 }) 60 61 It("sends check resource request to ATC", func() { 62 Expect(func() { 63 flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource", "-r", "mypipeline/branch:master/myresource", "-f", "ref:fake-ref", "-a", "--shallow") 64 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 65 Expect(err).NotTo(HaveOccurred()) 66 67 Eventually(sess).Should(gexec.Exit(0)) 68 Eventually(sess.Out).Should(gbytes.Say("checking mypipeline/branch:master/myresource in build 123")) 69 }).To(Change(func() int { 70 return len(atcServer.ReceivedRequests()) 71 }).By(2)) 72 }) 73 }) 74 75 Context("when version is omitted", func() { 76 BeforeEach(func() { 77 atcServer.AppendHandlers( 78 ghttp.CombineHandlers( 79 ghttp.VerifyRequest("POST", expectedURL, expectedQueryParams), 80 ghttp.VerifyJSON(`{"from":null}`), 81 ghttp.RespondWithJSONEncoded(http.StatusOK, build), 82 ), 83 ) 84 }) 85 86 It("sends check resource request to ATC", func() { 87 Expect(func() { 88 flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource", "-r", "mypipeline/branch:master/myresource", "--shallow", "-a") 89 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 90 Expect(err).NotTo(HaveOccurred()) 91 92 Eventually(sess).Should(gexec.Exit(0)) 93 Eventually(sess.Out).Should(gbytes.Say("checking mypipeline/branch:master/myresource in build 123")) 94 }).To(Change(func() int { 95 return len(atcServer.ReceivedRequests()) 96 }).By(2)) 97 }) 98 }) 99 100 Context("when running without --async", func() { 101 var streaming chan struct{} 102 var events chan atc.Event 103 104 BeforeEach(func() { 105 streaming = make(chan struct{}) 106 events = make(chan atc.Event) 107 108 atcServer.AppendHandlers( 109 ghttp.CombineHandlers( 110 ghttp.VerifyRequest("POST", expectedURL, expectedQueryParams), 111 ghttp.VerifyJSON(`{"from":null}`), 112 ghttp.RespondWithJSONEncoded(http.StatusOK, build), 113 ), 114 BuildEventsHandler(123, streaming, events), 115 ) 116 }) 117 118 It("checks and watches the build", func() { 119 Expect(func() { 120 flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource", "-r", "mypipeline/branch:master/myresource", "--shallow") 121 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 122 Expect(err).NotTo(HaveOccurred()) 123 Eventually(sess.Out).Should(gbytes.Say("checking mypipeline/branch:master/myresource in build 123")) 124 125 AssertEvents(sess, streaming, events) 126 }).To(Change(func() int { 127 return len(atcServer.ReceivedRequests()) 128 }).By(3)) 129 }) 130 }) 131 132 Context("when recursive check succeeds", func() { 133 var parentStreaming chan struct{} 134 var parentEvents chan atc.Event 135 136 BeforeEach(func() { 137 parentStreaming = make(chan struct{}) 138 parentEvents = make(chan atc.Event) 139 140 atcServer.AppendHandlers( 141 ghttp.CombineHandlers( 142 ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines/mypipeline/resources/myresource", expectedQueryParams), 143 ghttp.RespondWithJSONEncoded(http.StatusOK, resource), 144 ), 145 ghttp.CombineHandlers( 146 ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines/mypipeline/resource-types", expectedQueryParams), 147 ghttp.RespondWithJSONEncoded(http.StatusOK, resourceTypes), 148 ), 149 ghttp.CombineHandlers( 150 ghttp.VerifyRequest("GET", "/api/v1/info"), 151 ghttp.RespondWithJSONEncoded(http.StatusOK, atc.Info{Version: atcVersion, WorkerVersion: workerVersion}), 152 ), 153 ghttp.CombineHandlers( 154 ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines/mypipeline/resource-types", expectedQueryParams), 155 ghttp.RespondWithJSONEncoded(http.StatusOK, resourceTypes), 156 ), 157 ghttp.CombineHandlers( 158 ghttp.VerifyRequest("POST", "/api/v1/teams/main/pipelines/mypipeline/resource-types/myresourcetype/check", expectedQueryParams), 159 ghttp.VerifyJSON(`{"from":null}`), 160 ghttp.RespondWithJSONEncoded(http.StatusOK, atc.Build{ 161 ID: 987, 162 Status: "started", 163 }), 164 ), 165 BuildEventsHandler(987, parentStreaming, parentEvents), 166 ghttp.CombineHandlers( 167 ghttp.VerifyRequest("POST", "/api/v1/teams/main/pipelines/mypipeline/resources/myresource/check", expectedQueryParams), 168 ghttp.VerifyJSON(`{"from":null}`), 169 ghttp.RespondWithJSONEncoded(http.StatusOK, build), 170 ), 171 ) 172 }) 173 174 It("sends check resource request to ATC", func() { 175 Expect(func() { 176 flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource", "-r", "mypipeline/branch:master/myresource", "-a") 177 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 178 Expect(err).NotTo(HaveOccurred()) 179 180 Eventually(sess.Out).Should(gbytes.Say("checking mypipeline/branch:master/myresourcetype in build 987")) 181 182 parentEvents <- event.Log{Payload: "sup"} 183 Eventually(sess.Out).Should(gbytes.Say("sup")) 184 close(parentEvents) 185 186 Eventually(sess.Out).Should(gbytes.Say("checking mypipeline/branch:master/myresource in build 123")) 187 188 Eventually(sess).Should(gexec.Exit(0)) 189 }).To(Change(func() int { 190 return len(atcServer.ReceivedRequests()) 191 }).By(8)) 192 }) 193 }) 194 195 Context("when recursive check fails", func() { 196 var parentStreaming chan struct{} 197 var parentEvents chan atc.Event 198 199 BeforeEach(func() { 200 parentStreaming = make(chan struct{}) 201 parentEvents = make(chan atc.Event) 202 203 atcServer.AppendHandlers( 204 ghttp.CombineHandlers( 205 ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines/mypipeline/resources/myresource", expectedQueryParams), 206 ghttp.RespondWithJSONEncoded(http.StatusOK, resource), 207 ), 208 ghttp.CombineHandlers( 209 ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines/mypipeline/resource-types", expectedQueryParams), 210 ghttp.RespondWithJSONEncoded(http.StatusOK, resourceTypes), 211 ), 212 ghttp.CombineHandlers( 213 ghttp.VerifyRequest("GET", "/api/v1/info"), 214 ghttp.RespondWithJSONEncoded(http.StatusOK, atc.Info{Version: atcVersion, WorkerVersion: workerVersion}), 215 ), 216 ghttp.CombineHandlers( 217 ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines/mypipeline/resource-types", expectedQueryParams), 218 ghttp.RespondWithJSONEncoded(http.StatusOK, resourceTypes), 219 ), 220 ghttp.CombineHandlers( 221 ghttp.VerifyRequest("POST", "/api/v1/teams/main/pipelines/mypipeline/resource-types/myresourcetype/check", expectedQueryParams), 222 ghttp.VerifyJSON(`{"from":null}`), 223 ghttp.RespondWithJSONEncoded(http.StatusOK, atc.Build{ 224 ID: 987, 225 Status: "started", 226 }), 227 ), 228 BuildEventsHandler(987, parentStreaming, parentEvents), 229 ) 230 }) 231 232 It("sends check resource request to ATC", func() { 233 Expect(func() { 234 flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource", "-r", "mypipeline/branch:master/myresource") 235 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 236 Expect(err).NotTo(HaveOccurred()) 237 238 Eventually(sess.Out).Should(gbytes.Say("checking mypipeline/branch:master/myresourcetype in build 987")) 239 AssertErrorEvents(sess, parentStreaming, parentEvents) 240 }).To(Change(func() int { 241 return len(atcServer.ReceivedRequests()) 242 }).By(7)) 243 }) 244 }) 245 246 Context("when specifying multiple versions", func() { 247 BeforeEach(func() { 248 atcServer.AppendHandlers( 249 ghttp.CombineHandlers( 250 ghttp.VerifyRequest("POST", expectedURL, expectedQueryParams), 251 ghttp.VerifyJSON(`{"from":{"ref1":"fake-ref-1","ref2":"fake-ref-2"}}`), 252 ghttp.RespondWithJSONEncoded(http.StatusOK, build), 253 ), 254 ) 255 }) 256 257 It("sends correct check resource request to ATC", func() { 258 Expect(func() { 259 flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource", "-r", "mypipeline/branch:master/myresource", "-f", "ref1:fake-ref-1", "-f", "ref2:fake-ref-2", "--shallow", "-a") 260 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 261 Expect(err).NotTo(HaveOccurred()) 262 263 Eventually(sess).Should(gexec.Exit(0)) 264 265 Eventually(sess.Out).Should(gbytes.Say("checking mypipeline/branch:master/myresource in build 123")) 266 }).To(Change(func() int { 267 return len(atcServer.ReceivedRequests()) 268 }).By(2)) 269 }) 270 }) 271 272 Context("when pipeline or resource is not found", func() { 273 BeforeEach(func() { 274 atcServer.AppendHandlers( 275 ghttp.CombineHandlers( 276 ghttp.VerifyRequest("POST", expectedURL, expectedQueryParams), 277 ghttp.RespondWithJSONEncoded(http.StatusNotFound, ""), 278 ), 279 ) 280 }) 281 282 It("fails with error", func() { 283 flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource", "-r", "mypipeline/branch:master/myresource", "--shallow") 284 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 285 Expect(err).NotTo(HaveOccurred()) 286 287 Eventually(sess).Should(gexec.Exit(1)) 288 289 Expect(sess.Err).To(gbytes.Say("pipeline 'mypipeline/branch:master' or resource 'myresource' not found")) 290 }) 291 }) 292 293 Context("When resource check returns internal server error", func() { 294 BeforeEach(func() { 295 atcServer.AppendHandlers( 296 ghttp.CombineHandlers( 297 ghttp.VerifyRequest("POST", expectedURL, expectedQueryParams), 298 ghttp.RespondWith(http.StatusInternalServerError, "unknown server error"), 299 ), 300 ) 301 }) 302 303 It("outputs error in response body", func() { 304 flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource", "-r", "mypipeline/branch:master/myresource", "--shallow") 305 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 306 Expect(err).NotTo(HaveOccurred()) 307 308 Eventually(sess).Should(gexec.Exit(1)) 309 310 Expect(sess.Err).To(gbytes.Say("unknown server error")) 311 312 }) 313 }) 314 })