github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/fly/integration/clear_task_cache_test.go (about)

     1  package integration_test
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"net/http"
     7  	"os/exec"
     8  	"strings"
     9  
    10  	"github.com/pf-qiu/concourse/v6/atc"
    11  	. "github.com/onsi/ginkgo"
    12  	. "github.com/onsi/gomega"
    13  	"github.com/onsi/gomega/gbytes"
    14  	"github.com/onsi/gomega/gexec"
    15  	"github.com/onsi/gomega/ghttp"
    16  )
    17  
    18  var _ = Describe("Fly CLI", func() {
    19  	Describe("clear-task-cache", func() {
    20  		var (
    21  			stdin io.Writer
    22  			args  []string
    23  			sess  *gexec.Session
    24  		)
    25  
    26  		BeforeEach(func() {
    27  			stdin = nil
    28  			args = []string{}
    29  		})
    30  
    31  		JustBeforeEach(func() {
    32  			var err error
    33  
    34  			flyCmd := exec.Command(flyPath, append([]string{"-t", targetName, "clear-task-cache"}, args...)...)
    35  			stdin, err = flyCmd.StdinPipe()
    36  			Expect(err).NotTo(HaveOccurred())
    37  
    38  			sess, err = gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
    39  			Expect(err).NotTo(HaveOccurred())
    40  		})
    41  
    42  		Context("when a job is not specified", func() {
    43  			It("asks the user to specify a job", func() {
    44  				flyCmd := exec.Command(flyPath, "-t", targetName, "clear-task-cache", "-s", "some-task-step")
    45  
    46  				sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
    47  				Expect(err).NotTo(HaveOccurred())
    48  
    49  				Eventually(sess).Should(gexec.Exit(1))
    50  
    51  				Expect(sess.Err).To(gbytes.Say("error: the required flag `" + osFlag("j", "job") + "' was not specified"))
    52  			})
    53  		})
    54  
    55  		Context("when a step is not specified", func() {
    56  			It("asks the user to specify a step", func() {
    57  				flyCmd := exec.Command(flyPath, "-t", targetName, "clear-task-cache", "-j", "some-pipeline/some-job")
    58  
    59  				sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
    60  				Expect(err).NotTo(HaveOccurred())
    61  
    62  				Eventually(sess).Should(gexec.Exit(1))
    63  
    64  				Expect(sess.Err).To(gbytes.Say("error: the required flag `" + osFlag("s", "step") + "' was not specified"))
    65  			})
    66  		})
    67  
    68  		Context("when specifying a job without a pipeline name", func() {
    69  			It("asks the user to specify a pipeline name", func() {
    70  				flyCmd := exec.Command(flyPath, "-t", targetName, "clear-task-cache", "-s", "some-task-step", "-j", "myjob")
    71  
    72  				sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
    73  				Expect(err).NotTo(HaveOccurred())
    74  
    75  				<-sess.Exited
    76  				Expect(sess.ExitCode()).To(Equal(1))
    77  
    78  				Expect(sess.Err).To(gbytes.Say("error: invalid argument for flag `" + osFlag("j", "job")))
    79  				Expect(sess.Err).To(gbytes.Say(`argument format should be <pipeline>/<job>`))
    80  			})
    81  		})
    82  
    83  		Context("when a job and step name are specified", func() {
    84  			var (
    85  				expectedQueryParams []string
    86  				expectedURL         = "/api/v1/teams/main/pipelines/some-pipeline/jobs/some-job/tasks/some-step-name/cache"
    87  			)
    88  
    89  			BeforeEach(func() {
    90  				args = append(args, "-j", "some-pipeline/branch:master/some-job", "-s", "some-step-name")
    91  				expectedQueryParams = []string{"instance_vars=%7B%22branch%22%3A%22master%22%7D"}
    92  			})
    93  
    94  			yes := func() {
    95  				Eventually(sess).Should(gbytes.Say(`are you sure\? \[yN\]: `))
    96  				fmt.Fprintf(stdin, "y\n")
    97  			}
    98  
    99  			no := func() {
   100  				Eventually(sess).Should(gbytes.Say(`are you sure\? \[yN\]: `))
   101  				fmt.Fprintf(stdin, "n\n")
   102  			}
   103  
   104  			It("warns that it's about to do bad things", func() {
   105  				Eventually(sess).Should(gbytes.Say("!!! this will remove the task cache\\(s\\) for `some-pipeline/branch:master/some-job`, task step `some-step-name`"))
   106  			})
   107  
   108  			It("bails out if the user says no", func() {
   109  				no()
   110  				Eventually(sess).Should(gbytes.Say(`bailing out`))
   111  				Eventually(sess).Should(gexec.Exit(0))
   112  			})
   113  
   114  			Context("when the task step exists", func() {
   115  				JustBeforeEach(func() {
   116  					atcServer.AppendHandlers(
   117  						ghttp.CombineHandlers(
   118  							ghttp.VerifyRequest("DELETE", expectedURL, strings.Join(expectedQueryParams, "&")),
   119  							ghttp.RespondWithJSONEncoded(http.StatusOK, atc.ClearTaskCacheResponse{CachesRemoved: 1}),
   120  						),
   121  					)
   122  				})
   123  
   124  				It("succeeds if the user says yes", func() {
   125  					yes()
   126  					Eventually(sess).Should(gbytes.Say("1 caches removed"))
   127  					Eventually(sess).Should(gexec.Exit(0))
   128  				})
   129  
   130  				Context("when run noninteractively", func() {
   131  					BeforeEach(func() {
   132  						args = append(args, "-n")
   133  					})
   134  
   135  					It("destroys the task step cache without confirming", func() {
   136  						Eventually(sess).Should(gbytes.Say("1 caches removed"))
   137  						Eventually(sess).Should(gexec.Exit(0))
   138  					})
   139  				})
   140  
   141  				Context("and a cache path is specified", func() {
   142  					BeforeEach(func() {
   143  						args = append(args, "-c", "path/to/cache")
   144  						expectedQueryParams = append(expectedQueryParams, "cache_path=path/to/cache")
   145  					})
   146  
   147  					It("succeeds if the user says yes", func() {
   148  						yes()
   149  						Eventually(sess).Should(gbytes.Say("1 caches removed"))
   150  						Eventually(sess).Should(gexec.Exit(0))
   151  					})
   152  
   153  				})
   154  			})
   155  
   156  			Context("and the task step does not exist", func() {
   157  				JustBeforeEach(func() {
   158  					atcServer.AppendHandlers(
   159  						ghttp.CombineHandlers(
   160  							ghttp.VerifyRequest("DELETE", expectedURL, strings.Join(expectedQueryParams, "&")),
   161  							ghttp.RespondWithJSONEncoded(http.StatusOK, atc.ClearTaskCacheResponse{CachesRemoved: 0}),
   162  						),
   163  					)
   164  				})
   165  
   166  				It("writes that it did not exist and exits successfully", func() {
   167  					yes()
   168  					Eventually(sess).Should(gbytes.Say("0 caches removed"))
   169  					Eventually(sess).Should(gexec.Exit(0))
   170  				})
   171  			})
   172  
   173  			Context("and the api returns an unexpected status code", func() {
   174  				JustBeforeEach(func() {
   175  					atcServer.AppendHandlers(
   176  						ghttp.CombineHandlers(
   177  							ghttp.VerifyRequest("DELETE", expectedURL, strings.Join(expectedQueryParams, "&")),
   178  							ghttp.RespondWith(402, ""),
   179  						),
   180  					)
   181  				})
   182  
   183  				It("writes an error message to stderr", func() {
   184  					yes()
   185  					Eventually(sess.Err).Should(gbytes.Say("Unexpected Response"))
   186  					Eventually(sess).Should(gexec.Exit(1))
   187  				})
   188  			})
   189  		})
   190  	})
   191  })