github.com/chenbh/concourse/v6@v6.4.2/fly/integration/archive_pipeline_test.go (about) 1 package integration_test 2 3 import ( 4 "fmt" 5 "io" 6 "net/http" 7 "os/exec" 8 9 "github.com/chenbh/concourse/v6/fly/ui" 10 "github.com/fatih/color" 11 12 . "github.com/onsi/ginkgo" 13 . "github.com/onsi/gomega" 14 15 "github.com/chenbh/concourse/v6/atc" 16 "github.com/onsi/gomega/gbytes" 17 "github.com/onsi/gomega/gexec" 18 "github.com/onsi/gomega/ghttp" 19 "github.com/tedsuo/rata" 20 ) 21 22 var _ = Describe("Fly CLI", func() { 23 yes := func(stdin io.Writer) { 24 fmt.Fprintf(stdin, "y\n") 25 } 26 27 no := func(stdin io.Writer) { 28 fmt.Fprintf(stdin, "n\n") 29 } 30 31 Describe("archive-pipeline", func() { 32 Context("when the pipeline name is specified", func() { 33 var ( 34 path string 35 err error 36 ) 37 38 BeforeEach(func() { 39 path, err = atc.Routes.CreatePathForRoute(atc.ArchivePipeline, rata.Params{"pipeline_name": "awesome-pipeline", "team_name": "main"}) 40 Expect(err).NotTo(HaveOccurred()) 41 }) 42 43 Context("when the pipeline exists", func() { 44 BeforeEach(func() { 45 atcServer.AppendHandlers( 46 ghttp.CombineHandlers( 47 ghttp.VerifyRequest("PUT", path), 48 ghttp.RespondWith(http.StatusOK, nil), 49 ), 50 ) 51 }) 52 53 Context("when the user confirms", func() { 54 It("archives the pipeline", func() { 55 Expect(func() { 56 flyCmd := exec.Command(flyPath, "-t", targetName, "archive-pipeline", "-p", "awesome-pipeline") 57 stdin, err := flyCmd.StdinPipe() 58 Expect(err).NotTo(HaveOccurred()) 59 60 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 61 Expect(err).NotTo(HaveOccurred()) 62 63 Eventually(sess).Should(gbytes.Say("!!! archiving the pipeline will remove its configuration. Build history will be retained.\n\n")) 64 Eventually(sess).Should(gbytes.Say("archive pipeline 'awesome-pipeline'?")) 65 yes(stdin) 66 67 Eventually(sess).Should(gbytes.Say(`archived 'awesome-pipeline'`)) 68 69 <-sess.Exited 70 Expect(sess.ExitCode()).To(Equal(0)) 71 }).To(Change(func() int { 72 return len(atcServer.ReceivedRequests()) 73 }).By(2)) 74 }) 75 }) 76 77 Context("when the user declines", func() { 78 It("does not archive the pipelines", func() { 79 Expect(func() { 80 flyCmd := exec.Command(flyPath, "-t", targetName, "archive-pipeline", "-p", "awesome-pipeline") 81 stdin, err := flyCmd.StdinPipe() 82 Expect(err).NotTo(HaveOccurred()) 83 84 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 85 Expect(err).NotTo(HaveOccurred()) 86 87 Eventually(sess).Should(gbytes.Say("archive pipeline 'awesome-pipeline'?")) 88 no(stdin) 89 90 Eventually(sess).Should(gbytes.Say(`bailing out`)) 91 92 <-sess.Exited 93 Expect(sess.ExitCode()).To(Equal(0)) 94 }).To(Change(func() int { 95 return len(atcServer.ReceivedRequests()) 96 }).By(1)) 97 }) 98 }) 99 100 Context("when running in non-interactive mode", func() { 101 It("does not prompt the user", func() { 102 Expect(func() { 103 flyCmd := exec.Command(flyPath, "-t", targetName, "archive-pipeline", "-n", "-p", "awesome-pipeline") 104 105 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 106 Expect(err).NotTo(HaveOccurred()) 107 108 Eventually(sess).Should(gbytes.Say(`archived 'awesome-pipeline'`)) 109 110 <-sess.Exited 111 Expect(sess.ExitCode()).To(Equal(0)) 112 }).To(Change(func() int { 113 return len(atcServer.ReceivedRequests()) 114 }).By(2)) 115 }) 116 }) 117 }) 118 119 Context("when the pipeline doesn't exist", func() { 120 BeforeEach(func() { 121 atcServer.AppendHandlers( 122 ghttp.CombineHandlers( 123 ghttp.VerifyRequest("PUT", path), 124 ghttp.RespondWith(http.StatusNotFound, nil), 125 ), 126 ) 127 }) 128 129 It("prints helpful message", func() { 130 Expect(func() { 131 flyCmd := exec.Command(flyPath, "-t", targetName, "archive-pipeline", "-n", "-p", "awesome-pipeline") 132 133 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 134 Expect(err).NotTo(HaveOccurred()) 135 136 Eventually(sess.Err).Should(gbytes.Say(`pipeline 'awesome-pipeline' not found`)) 137 138 <-sess.Exited 139 Expect(sess.ExitCode()).To(Equal(1)) 140 }).To(Change(func() int { 141 return len(atcServer.ReceivedRequests()) 142 }).By(2)) 143 }) 144 }) 145 }) 146 147 Context("when the pipeline name or --all is not specified", func() { 148 It("errors", func() { 149 Expect(func() { 150 flyCmd := exec.Command(flyPath, "-t", targetName, "archive-pipeline") 151 152 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 153 Expect(err).NotTo(HaveOccurred()) 154 155 Eventually(sess.Err).Should(gbytes.Say(`one of the flags '-p, --pipeline' or '-a, --all' is required`)) 156 157 <-sess.Exited 158 Expect(sess.ExitCode()).To(Equal(1)) 159 }).To(Change(func() int { 160 return len(atcServer.ReceivedRequests()) 161 }).By(0)) 162 }) 163 }) 164 165 Context("when both the pipeline name and --all are specified", func() { 166 It("errors", func() { 167 Expect(func() { 168 flyCmd := exec.Command(flyPath, "-t", targetName, "archive-pipeline", "-p", "awesome-pipeline", "--all") 169 170 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 171 Expect(err).NotTo(HaveOccurred()) 172 173 Eventually(sess.Err).Should(gbytes.Say(`only one of the flags '-p, --pipeline' or '-a, --all' is allowed`)) 174 175 <-sess.Exited 176 Expect(sess.ExitCode()).To(Equal(1)) 177 }).To(Change(func() int { 178 return len(atcServer.ReceivedRequests()) 179 }).By(0)) 180 }) 181 }) 182 183 Context("when the --all flag is passed, and there are unarchived pipelines", func() { 184 var ( 185 somePath string 186 someOtherPath string 187 err error 188 ) 189 190 BeforeEach(func() { 191 somePath, err = atc.Routes.CreatePathForRoute(atc.ArchivePipeline, rata.Params{"pipeline_name": "awesome-pipeline", "team_name": "main"}) 192 Expect(err).NotTo(HaveOccurred()) 193 194 someOtherPath, err = atc.Routes.CreatePathForRoute(atc.ArchivePipeline, rata.Params{"pipeline_name": "more-awesome-pipeline", "team_name": "main"}) 195 Expect(err).NotTo(HaveOccurred()) 196 197 atcServer.AppendHandlers( 198 ghttp.CombineHandlers( 199 ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines"), 200 ghttp.RespondWithJSONEncoded(200, []atc.Pipeline{ 201 {Name: "awesome-pipeline", Archived: false, Public: false}, 202 {Name: "more-awesome-pipeline", Archived: false, Public: false}, 203 {Name: "already-archived", Archived: true, Public: false}, 204 }), 205 ), 206 ghttp.CombineHandlers( 207 ghttp.VerifyRequest("PUT", somePath), 208 ghttp.RespondWith(http.StatusOK, nil), 209 ), 210 ghttp.CombineHandlers( 211 ghttp.VerifyRequest("PUT", someOtherPath), 212 ghttp.RespondWith(http.StatusOK, nil), 213 ), 214 ) 215 }) 216 217 Context("when the user confirms", func() { 218 It("archives every currently unarchived pipeline", func() { 219 Expect(func() { 220 flyCmd := exec.Command(flyPath, "-t", targetName, "archive-pipeline", "--all") 221 stdin, err := flyCmd.StdinPipe() 222 Expect(err).NotTo(HaveOccurred()) 223 224 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 225 Expect(err).NotTo(HaveOccurred()) 226 227 Eventually(sess.Out).Should(PrintTable(ui.Table{ 228 Headers: ui.TableRow{{Contents: "pipelines", Color: color.New(color.Bold)}}, 229 Data: []ui.TableRow{ 230 {{Contents: "awesome-pipeline"}}, 231 {{Contents: "more-awesome-pipeline"}}, 232 }, 233 })) 234 235 Eventually(sess).Should(gbytes.Say("archive 2 pipelines?")) 236 yes(stdin) 237 238 Eventually(sess).Should(gbytes.Say(`archived 'awesome-pipeline'`)) 239 Eventually(sess).Should(gbytes.Say(`archived 'more-awesome-pipeline'`)) 240 Consistently(sess).ShouldNot(gbytes.Say(`archived 'already-archived'`)) 241 242 <-sess.Exited 243 Expect(sess.ExitCode()).To(Equal(0)) 244 }).To(Change(func() int { 245 return len(atcServer.ReceivedRequests()) 246 }).By(4)) 247 }) 248 }) 249 250 Context("when the user denies", func() { 251 It("does not archive the pipelines", func() { 252 Expect(func() { 253 flyCmd := exec.Command(flyPath, "-t", targetName, "archive-pipeline", "--all") 254 stdin, err := flyCmd.StdinPipe() 255 Expect(err).NotTo(HaveOccurred()) 256 257 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 258 Expect(err).NotTo(HaveOccurred()) 259 260 Eventually(sess).Should(gbytes.Say("archive 2 pipelines?")) 261 no(stdin) 262 263 Eventually(sess).Should(gbytes.Say(`bailing out`)) 264 265 <-sess.Exited 266 Expect(sess.ExitCode()).To(Equal(0)) 267 }).To(Change(func() int { 268 return len(atcServer.ReceivedRequests()) 269 }).By(2)) 270 }) 271 }) 272 273 Context("when running in non-interactive mode", func() { 274 It("does not prompt the user", func() { 275 Expect(func() { 276 flyCmd := exec.Command(flyPath, "-t", targetName, "archive-pipeline", "-n", "--all") 277 278 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 279 Expect(err).NotTo(HaveOccurred()) 280 281 Eventually(sess).Should(gbytes.Say(`archived 'awesome-pipeline'`)) 282 Eventually(sess).Should(gbytes.Say(`archived 'more-awesome-pipeline'`)) 283 284 <-sess.Exited 285 Expect(sess.ExitCode()).To(Equal(0)) 286 }).To(Change(func() int { 287 return len(atcServer.ReceivedRequests()) 288 }).By(4)) 289 }) 290 }) 291 }) 292 293 Context("when the --all flag is passed, but there are no unarchived pipelines", func() { 294 BeforeEach(func() { 295 atcServer.AppendHandlers( 296 ghttp.CombineHandlers( 297 ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines"), 298 ghttp.RespondWithJSONEncoded(200, []atc.Pipeline{ 299 {Name: "already-archived", Archived: true, Public: false}, 300 }), 301 ), 302 ) 303 }) 304 305 It("prints a message and exits", func() { 306 flyCmd := exec.Command(flyPath, "-t", targetName, "archive-pipeline", "--all") 307 308 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 309 Expect(err).NotTo(HaveOccurred()) 310 311 Eventually(sess).Should(gbytes.Say("there are no unarchived pipelines")) 312 Eventually(sess).Should(gbytes.Say("bailing out")) 313 314 <-sess.Exited 315 Expect(sess.ExitCode()).To(Equal(0)) 316 }) 317 }) 318 319 Context("when specifying a pipeline name with a '/' character in it", func() { 320 It("fails and says '/' characters are not allowed", func() { 321 flyCmd := exec.Command(flyPath, "-t", targetName, "archive-pipeline", "-p", "forbidden/pipelinename") 322 323 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 324 Expect(err).NotTo(HaveOccurred()) 325 326 <-sess.Exited 327 Expect(sess.ExitCode()).To(Equal(1)) 328 329 Expect(sess.Err).To(gbytes.Say("error: pipeline name cannot contain '/'")) 330 }) 331 }) 332 }) 333 })