github.com/chenbh/concourse/v6@v6.4.2/fly/integration/pipelines_test.go (about)

     1  package integration_test
     2  
     3  import (
     4  	"os"
     5  	"os/exec"
     6  	"time"
     7  
     8  	"github.com/chenbh/concourse/v6/atc"
     9  	"github.com/chenbh/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("pipelines", func() {
    20  		var (
    21  			flyCmd *exec.Cmd
    22  		)
    23  
    24  		JustBeforeEach(func() {
    25  			flyCmd.Args = append([]string{flyCmd.Args[0], "--print-table-headers"}, flyCmd.Args[1:]...)
    26  		})
    27  
    28  		Context("when pipelines are returned from the API", func() {
    29  			BeforeEach(func() {
    30  				flyCmd = exec.Command(flyPath, "-t", targetName, "pipelines")
    31  			})
    32  			Context("when no --all flag is given", func() {
    33  				BeforeEach(func() {
    34  					atcServer.AppendHandlers(
    35  						ghttp.CombineHandlers(
    36  							ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines"),
    37  							ghttp.RespondWithJSONEncoded(200, []atc.Pipeline{
    38  								{Name: "pipeline-1-longer", Paused: false, Public: false, LastUpdated: 1},
    39  								{Name: "pipeline-2", Paused: true, Public: false, LastUpdated: 1},
    40  								{Name: "pipeline-3", Paused: false, Public: true, LastUpdated: 1},
    41  								{Name: "archived-pipeline", Paused: false, Archived: true, Public: true, LastUpdated: 1},
    42  							}),
    43  						),
    44  					)
    45  				})
    46  
    47  				Context("when --json is given", func() {
    48  					BeforeEach(func() {
    49  						flyCmd.Args = append(flyCmd.Args, "--json")
    50  					})
    51  
    52  					It("prints non-archived pipelines in json to stdout", func() {
    53  						sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
    54  						Expect(err).NotTo(HaveOccurred())
    55  
    56  						Eventually(sess).Should(gexec.Exit(0))
    57  						Expect(sess.Out.Contents()).To(MatchJSON(`[
    58                  {
    59                    "id": 0,
    60                    "name": "pipeline-1-longer",
    61                    "paused": false,
    62                    "public": false,
    63                    "archived": false,
    64                    "team_name": "",
    65                    "last_updated": 1
    66                  },
    67                  {
    68                    "id": 0,
    69                    "name": "pipeline-2",
    70                    "paused": true,
    71                    "public": false,
    72                    "archived": false,
    73                    "team_name": "",
    74                    "last_updated": 1
    75                  },
    76                  {
    77                    "id": 0,
    78                    "name": "pipeline-3",
    79                    "paused": false,
    80                    "public": true,
    81                    "archived": false,
    82                    "team_name": "",
    83                    "last_updated": 1
    84                  }
    85                ]`))
    86  					})
    87  				})
    88  
    89  				It("only shows the team's pipelines", func() {
    90  					sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
    91  					Expect(err).NotTo(HaveOccurred())
    92  					Eventually(sess).Should(gexec.Exit(0))
    93  
    94  					Expect(sess.Out).To(PrintTableWithHeaders(ui.Table{
    95  						Headers: ui.TableRow{
    96  							{Contents: "name", Color: color.New(color.Bold)},
    97  							{Contents: "paused", Color: color.New(color.Bold)},
    98  							{Contents: "public", Color: color.New(color.Bold)},
    99  							{Contents: "last updated", Color: color.New(color.Bold)},
   100  						},
   101  						Data: []ui.TableRow{
   102  							{{Contents: "pipeline-1-longer"}, {Contents: "no"}, {Contents: "no"}, {Contents: time.Unix(1, 0).String()}},
   103  							{{Contents: "pipeline-2"}, {Contents: "yes", Color: color.New(color.FgCyan)}, {Contents: "no"}, {Contents: time.Unix(1, 0).String()}},
   104  							{{Contents: "pipeline-3"}, {Contents: "no"}, {Contents: "yes", Color: color.New(color.FgCyan)}, {Contents: time.Unix(1, 0).String()}},
   105  						},
   106  					}))
   107  				})
   108  
   109  				It("does not print archived pipelines", func() {
   110  					sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   111  					Expect(err).NotTo(HaveOccurred())
   112  					Eventually(sess).Should(gexec.Exit(0))
   113  
   114  					Expect(sess.Out).ToNot(gbytes.Say("archived-pipeline"))
   115  				})
   116  			})
   117  
   118  			Context("when --all is specified", func() {
   119  				BeforeEach(func() {
   120  					flyCmd.Args = append(flyCmd.Args, "--all")
   121  					atcServer.AppendHandlers(
   122  						ghttp.CombineHandlers(
   123  							ghttp.VerifyRequest("GET", "/api/v1/pipelines"),
   124  							ghttp.RespondWithJSONEncoded(200, []atc.Pipeline{
   125  								{Name: "pipeline-1-longer", Paused: false, Public: false, TeamName: "main", LastUpdated: 1},
   126  								{Name: "pipeline-2", Paused: true, Public: false, TeamName: "main", LastUpdated: 1},
   127  								{Name: "pipeline-3", Paused: false, Public: true, TeamName: "main", LastUpdated: 1},
   128  								{Name: "archived-pipeline", Paused: false, Archived: true, Public: true, TeamName: "main", LastUpdated: 1},
   129  								{Name: "foreign-pipeline-1", Paused: false, Public: true, TeamName: "other", LastUpdated: 1},
   130  								{Name: "foreign-pipeline-2", Paused: false, Public: true, TeamName: "other", LastUpdated: 1},
   131  								{Name: "foreign-archived-pipeline", Paused: false, Archived: true, Public: true, TeamName: "other", LastUpdated: 1},
   132  							}),
   133  						),
   134  					)
   135  				})
   136  
   137  				Context("when --json is given", func() {
   138  					BeforeEach(func() {
   139  						flyCmd.Args = append(flyCmd.Args, "--json")
   140  					})
   141  
   142  					It("prints non-archived pipelines in json to stdout", func() {
   143  						sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   144  						Expect(err).NotTo(HaveOccurred())
   145  
   146  						Eventually(sess).Should(gexec.Exit(0))
   147  						Expect(sess.Out.Contents()).To(MatchJSON(`[
   148                  {
   149                    "id": 0,
   150                    "name": "pipeline-1-longer",
   151                    "paused": false,
   152                    "public": false,
   153                    "archived": false,
   154                    "team_name": "main",
   155                    "last_updated": 1
   156                  },
   157                  {
   158                    "id": 0,
   159                    "name": "pipeline-2",
   160                    "paused": true,
   161                    "public": false,
   162                    "archived": false,
   163                    "team_name": "main",
   164                    "last_updated": 1
   165                  },
   166                  {
   167                    "id": 0,
   168                    "name": "pipeline-3",
   169                    "paused": false,
   170                    "public": true,
   171                    "archived": false,
   172                    "team_name": "main",
   173                    "last_updated": 1
   174                  },
   175                  {
   176                    "id": 0,
   177                    "name": "foreign-pipeline-1",
   178                    "paused": false,
   179                    "public": true,
   180                    "archived": false,
   181                    "team_name": "other",
   182                    "last_updated": 1
   183                  },
   184                  {
   185                    "id": 0,
   186                    "name": "foreign-pipeline-2",
   187                    "paused": false,
   188                    "public": true,
   189                    "archived": false,
   190                    "team_name": "other",
   191                    "last_updated": 1
   192                  }
   193                ]`))
   194  					})
   195  				})
   196  
   197  				It("outputs pipelines across all teams", func() {
   198  					sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   199  					Expect(err).NotTo(HaveOccurred())
   200  					Eventually(sess).Should(gexec.Exit(0))
   201  
   202  					Expect(sess.Out).To(PrintTableWithHeaders(ui.Table{
   203  						Headers: ui.TableRow{
   204  							{Contents: "name", Color: color.New(color.Bold)},
   205  							{Contents: "team", Color: color.New(color.Bold)},
   206  							{Contents: "paused", Color: color.New(color.Bold)},
   207  							{Contents: "public", Color: color.New(color.Bold)},
   208  							{Contents: "last updated", Color: color.New(color.Bold)},
   209  						},
   210  						Data: []ui.TableRow{
   211  							{{Contents: "pipeline-1-longer"}, {Contents: "main"}, {Contents: "no"}, {Contents: "no"}, {Contents: time.Unix(1, 0).String()}},
   212  							{{Contents: "pipeline-2"}, {Contents: "main"}, {Contents: "yes", Color: color.New(color.FgCyan)}, {Contents: "no"}, {Contents: time.Unix(1, 0).String()}},
   213  							{{Contents: "pipeline-3"}, {Contents: "main"}, {Contents: "no"}, {Contents: "yes", Color: color.New(color.FgCyan)}, {Contents: time.Unix(1, 0).String()}},
   214  							{{Contents: "foreign-pipeline-1"}, {Contents: "other"}, {Contents: "no"}, {Contents: "yes", Color: color.New(color.FgCyan)}, {Contents: time.Unix(1, 0).String()}},
   215  							{{Contents: "foreign-pipeline-2"}, {Contents: "other"}, {Contents: "no"}, {Contents: "yes", Color: color.New(color.FgCyan)}, {Contents: time.Unix(1, 0).String()}},
   216  						},
   217  					}))
   218  				})
   219  
   220  				It("does not print archived pipelines", func() {
   221  					sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   222  					Expect(err).NotTo(HaveOccurred())
   223  					Eventually(sess).Should(gexec.Exit(0))
   224  
   225  					Expect(sess.Out).ToNot(gbytes.Say("archived-pipeline"))
   226  				})
   227  			})
   228  
   229  			Context("when --include-archived is specified", func() {
   230  				BeforeEach(func() {
   231  					flyCmd.Args = append(flyCmd.Args, "--include-archived")
   232  				})
   233  
   234  				It("includes archived pipelines in the output", func() {
   235  					atcServer.AppendHandlers(
   236  						ghttp.CombineHandlers(
   237  							ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines"),
   238  							ghttp.RespondWithJSONEncoded(200, []atc.Pipeline{
   239  								{Name: "pipeline-1-longer", Paused: false, Public: false, TeamName: "main", LastUpdated: 1},
   240  								{Name: "archived-pipeline", Paused: true, Archived: true, Public: true, TeamName: "main", LastUpdated: 1},
   241  							}),
   242  						),
   243  					)
   244  
   245  					sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   246  					Expect(err).NotTo(HaveOccurred())
   247  					Eventually(sess).Should(gexec.Exit(0))
   248  
   249  					Expect(sess.Out).To(PrintTableWithHeaders(ui.Table{
   250  						Headers: ui.TableRow{
   251  							{Contents: "name", Color: color.New(color.Bold)},
   252  							{Contents: "paused", Color: color.New(color.Bold)},
   253  							{Contents: "public", Color: color.New(color.Bold)},
   254  							{Contents: "archived", Color: color.New(color.Bold)},
   255  							{Contents: "last updated", Color: color.New(color.Bold)},
   256  						},
   257  						Data: []ui.TableRow{
   258  							{{Contents: "pipeline-1-longer"}, {Contents: "no"}, {Contents: "no"}, {Contents: "no"}, {Contents: time.Unix(1, 0).String()}},
   259  							{{Contents: "archived-pipeline"}, {Contents: "yes"}, {Contents: "yes", Color: color.New(color.FgCyan)}, {Contents: "yes"}, {Contents: time.Unix(1, 0).String()}},
   260  						},
   261  					}))
   262  				})
   263  			})
   264  
   265  			Context("completion", func() {
   266  				BeforeEach(func() {
   267  					atcServer.AppendHandlers(
   268  						ghttp.CombineHandlers(
   269  							ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines"),
   270  							ghttp.RespondWithJSONEncoded(200, []atc.Pipeline{
   271  								{Name: "some-pipeline-1", Paused: false, Public: false, LastUpdated: 1},
   272  								{Name: "some-pipeline-2", Paused: false, Public: false, LastUpdated: 1},
   273  								{Name: "another-pipeline", Paused: false, Public: false, LastUpdated: 1},
   274  							}),
   275  						),
   276  					)
   277  				})
   278  				It("returns all matching pipelines", func() {
   279  					flyCmd = exec.Command(flyPath, "-t", targetName, "get-pipeline", "-p", "some-")
   280  					flyCmd.Env = append(os.Environ(), "GO_FLAGS_COMPLETION=1")
   281  
   282  					sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   283  					Expect(err).NotTo(HaveOccurred())
   284  					Eventually(sess).Should(gexec.Exit(0))
   285  					Eventually(sess.Out).Should(gbytes.Say("some-pipeline-1"))
   286  					Eventually(sess.Out).Should(gbytes.Say("some-pipeline-2"))
   287  					Eventually(sess.Out).ShouldNot(gbytes.Say("another-pipeline"))
   288  				})
   289  				It("works with other application level flags", func() {
   290  					flyCmd = exec.Command(flyPath, "--verbose", "-t", targetName, "get-pipeline", "-p", "some-")
   291  					flyCmd.Env = append(os.Environ(), "GO_FLAGS_COMPLETION=1")
   292  
   293  					sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   294  					Expect(err).NotTo(HaveOccurred())
   295  					Eventually(sess).Should(gexec.Exit(0))
   296  					Eventually(sess.Out).Should(gbytes.Say("some-pipeline-1"))
   297  					Eventually(sess.Out).Should(gbytes.Say("some-pipeline-2"))
   298  					Eventually(sess.Out).ShouldNot(gbytes.Say("another-pipeline"))
   299  				})
   300  			})
   301  		})
   302  
   303  		Context("when there are no pipelines", func() {
   304  			BeforeEach(func() {
   305  				flyCmd = exec.Command(flyPath, "-t", targetName, "pipelines")
   306  				atcServer.AppendHandlers(
   307  					ghttp.CombineHandlers(
   308  						ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines"),
   309  						ghttp.RespondWithJSONEncoded(200, []atc.Pipeline{}),
   310  					),
   311  				)
   312  			})
   313  
   314  			Context("when --json is given", func() {
   315  				BeforeEach(func() {
   316  					flyCmd.Args = append(flyCmd.Args, "--json")
   317  				})
   318  
   319  				It("prints an empty list", func() {
   320  					sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   321  					Expect(err).NotTo(HaveOccurred())
   322  					Eventually(sess).Should(gexec.Exit(0))
   323  
   324  					Expect(sess.Out.Contents()).To(MatchJSON(`[]`))
   325  				})
   326  			})
   327  		})
   328  
   329  		Context("and the api returns an internal server error", func() {
   330  			BeforeEach(func() {
   331  				flyCmd = exec.Command(flyPath, "-t", targetName, "pipelines")
   332  				atcServer.AppendHandlers(
   333  					ghttp.CombineHandlers(
   334  						ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines"),
   335  						ghttp.RespondWith(500, ""),
   336  					),
   337  				)
   338  			})
   339  
   340  			It("writes an error message to stderr", func() {
   341  				sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   342  				Expect(err).NotTo(HaveOccurred())
   343  
   344  				Eventually(sess).Should(gexec.Exit(1))
   345  				Eventually(sess.Err).Should(gbytes.Say("Unexpected Response"))
   346  			})
   347  		})
   348  	})
   349  })