github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/fly/integration/jobs_test.go (about) 1 package integration_test 2 3 import ( 4 "fmt" 5 "net/http" 6 "os/exec" 7 8 "github.com/pf-qiu/concourse/v6/atc" 9 "github.com/pf-qiu/concourse/v6/fly/ui" 10 "github.com/fatih/color" 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("jobs", func() { 20 var ( 21 flyCmd *exec.Cmd 22 ) 23 24 expectedURL := "/api/v1/teams/main/pipelines/pipeline/jobs" 25 sampleJobJsonString := `[ 26 { 27 "id": 1, 28 "name": "job-1", 29 "pipeline_id": 1, 30 "pipeline_name": "pipeline", 31 "pipeline_instance_vars": { 32 "branch": "master" 33 }, 34 "team_name": "main", 35 "next_build": { 36 "id": 0, 37 "team_name": "", 38 "name": "", 39 "status": "started", 40 "api_url": "" 41 }, 42 "finished_build": { 43 "id": 0, 44 "team_name": "", 45 "name": "", 46 "status": "succeeded", 47 "api_url": "" 48 } 49 }, 50 { 51 "id": 2, 52 "name": "job-2", 53 "pipeline_id": 1, 54 "pipeline_name": "pipeline", 55 "pipeline_instance_vars": { 56 "branch": "master" 57 }, 58 "team_name": "main", 59 "paused": true, 60 "next_build": null, 61 "finished_build": { 62 "id": 0, 63 "team_name": "", 64 "name": "", 65 "status": "failed", 66 "api_url": "" 67 } 68 }, 69 { 70 "id": 3, 71 "name": "job-3", 72 "pipeline_id": 1, 73 "pipeline_name": "pipeline", 74 "pipeline_instance_vars": { 75 "branch": "master" 76 }, 77 "team_name": "main", 78 "next_build": null, 79 "finished_build": null 80 } 81 ]` 82 var sampleJobs []atc.Job 83 84 Context("when not specifying a pipeline name", func() { 85 It("fails and says you should give a pipeline name", func() { 86 flyCmd := exec.Command(flyPath, "-t", targetName, "jobs") 87 88 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 89 Expect(err).NotTo(HaveOccurred()) 90 91 <-sess.Exited 92 Expect(sess.ExitCode()).To(Equal(1)) 93 94 Expect(sess.Err).To(gbytes.Say("error: the required flag `" + osFlag("p", "pipeline") + "' was not specified")) 95 }) 96 }) 97 98 Context("when jobs are returned from the API", func() { 99 createJob := func(num int, pipelineRef atc.PipelineRef, paused bool, status, nextStatus atc.BuildStatus) atc.Job { 100 var ( 101 build *atc.Build 102 nextBuild *atc.Build 103 ) 104 if status != "" { 105 build = &atc.Build{Status: status} 106 } 107 if nextStatus != "" { 108 nextBuild = &atc.Build{Status: nextStatus} 109 } 110 111 return atc.Job{ 112 ID: num, 113 Name: fmt.Sprintf("job-%d", num), 114 PipelineID: 1, 115 PipelineName: pipelineRef.Name, 116 PipelineInstanceVars: pipelineRef.InstanceVars, 117 TeamName: teamName, 118 Paused: paused, 119 FinishedBuild: build, 120 NextBuild: nextBuild, 121 } 122 } 123 124 pipelineRef := atc.PipelineRef{ 125 Name: "pipeline", 126 InstanceVars: atc.InstanceVars{"branch": "master"}, 127 } 128 129 sampleJobs = []atc.Job{ 130 createJob(1, pipelineRef, false, atc.StatusSucceeded, atc.StatusStarted), 131 createJob(2, pipelineRef, true, atc.StatusFailed, ""), 132 createJob(3, pipelineRef, false, "", ""), 133 } 134 135 BeforeEach(func() { 136 flyCmd = exec.Command(flyPath, "-t", targetName, "jobs", "--pipeline", "pipeline/branch:master") 137 atcServer.AppendHandlers( 138 ghttp.CombineHandlers( 139 ghttp.VerifyRequest("GET", expectedURL, "instance_vars=%7B%22branch%22%3A%22master%22%7D"), 140 ghttp.RespondWithJSONEncoded(200, sampleJobs), 141 ), 142 ) 143 }) 144 145 Context("when --json is given", func() { 146 BeforeEach(func() { 147 flyCmd.Args = append(flyCmd.Args, "--json") 148 }) 149 150 It("prints response in json as stdout", func() { 151 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 152 Expect(err).NotTo(HaveOccurred()) 153 154 Eventually(sess).Should(gexec.Exit(0)) 155 Expect(sess.Out.Contents()).To(MatchJSON(sampleJobJsonString)) 156 }) 157 }) 158 159 It("shows the pipeline's jobs", func() { 160 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 161 Expect(err).NotTo(HaveOccurred()) 162 Eventually(sess).Should(gexec.Exit(0)) 163 164 Expect(sess.Out).To(PrintTable(ui.Table{ 165 Data: []ui.TableRow{ 166 {{Contents: "job-1"}, {Contents: "no"}, {Contents: "succeeded"}, {Contents: "started", Color: color.New(color.FgGreen)}}, 167 {{Contents: "job-2"}, {Contents: "yes", Color: color.New(color.FgCyan)}, {Contents: "failed", Color: color.New(color.FgRed)}, {Contents: "n/a"}}, 168 {{Contents: "job-3"}, {Contents: "no"}, {Contents: "n/a"}, {Contents: "n/a"}}, 169 }, 170 })) 171 }) 172 }) 173 174 Context("when the api returns an internal server error", func() { 175 BeforeEach(func() { 176 flyCmd = exec.Command(flyPath, "-t", targetName, "jobs", "-p", "pipeline") 177 atcServer.AppendHandlers( 178 ghttp.CombineHandlers( 179 ghttp.VerifyRequest("GET", expectedURL), 180 ghttp.RespondWith(500, ""), 181 ), 182 ) 183 }) 184 185 It("writes an error message to stderr", func() { 186 sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter) 187 Expect(err).NotTo(HaveOccurred()) 188 189 Eventually(sess).Should(gexec.Exit(1)) 190 Eventually(sess.Err).Should(gbytes.Say("Unexpected Response")) 191 }) 192 }) 193 194 Context("jobs for 'other-team'", func() { 195 Context("using --team parameter", func() { 196 BeforeEach(func() { 197 atcServer.AppendHandlers( 198 ghttp.CombineHandlers( 199 ghttp.VerifyRequest("GET", "/api/v1/teams/other-team"), 200 ghttp.RespondWithJSONEncoded(http.StatusOK, atc.Team{Name: "other-team"}), 201 ), 202 ghttp.CombineHandlers( 203 ghttp.VerifyRequest("GET", "/api/v1/teams/other-team/pipelines/pipeline/jobs"), 204 ghttp.RespondWithJSONEncoded(200, sampleJobs), 205 ), 206 ) 207 }) 208 It("can list jobs in 'other-team'", func() { 209 flyJobCmd := exec.Command(flyPath, "-t", targetName, "jobs", "-p", "pipeline", "--team", "other-team", "--json") 210 sess, err := gexec.Start(flyJobCmd, GinkgoWriter, GinkgoWriter) 211 Expect(err).NotTo(HaveOccurred()) 212 213 Eventually(sess).Should(gexec.Exit(0)) 214 Expect(sess.Out.Contents()).To(MatchJSON(sampleJobJsonString)) 215 }) 216 }) 217 }) 218 }) 219 })