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

     1  package integration_test
     2  
     3  import (
     4  	"net/http"
     5  	"os/exec"
     6  
     7  	"github.com/chenbh/concourse/v6/atc"
     8  	"github.com/chenbh/concourse/v6/fly/ui"
     9  	"github.com/fatih/color"
    10  	. "github.com/onsi/ginkgo"
    11  	. "github.com/onsi/gomega"
    12  
    13  	"github.com/onsi/gomega/gbytes"
    14  	"github.com/onsi/gomega/gexec"
    15  	"github.com/onsi/gomega/ghttp"
    16  )
    17  
    18  var _ = Describe("CheckResourceType", func() {
    19  	var (
    20  		flyCmd          *exec.Cmd
    21  		check           atc.Check
    22  		resourceTypes   atc.VersionedResourceTypes
    23  		expectedHeaders ui.TableRow
    24  	)
    25  
    26  	BeforeEach(func() {
    27  		check = atc.Check{
    28  			ID:         123,
    29  			Status:     "started",
    30  			CreateTime: 100000000000,
    31  		}
    32  
    33  		resourceTypes = atc.VersionedResourceTypes{{
    34  			ResourceType: atc.ResourceType{
    35  				Name: "myresource",
    36  				Type: "myresourcetype",
    37  			},
    38  		}, {
    39  			ResourceType: atc.ResourceType{
    40  				Name: "myresourcetype",
    41  				Type: "mybaseresourcetype",
    42  			},
    43  		}}
    44  
    45  		expectedHeaders = ui.TableRow{
    46  			{Contents: "id", Color: color.New(color.Bold)},
    47  			{Contents: "name", Color: color.New(color.Bold)},
    48  			{Contents: "status", Color: color.New(color.Bold)},
    49  			{Contents: "check_error", Color: color.New(color.Bold)},
    50  		}
    51  	})
    52  
    53  	Context("when version is specified", func() {
    54  		BeforeEach(func() {
    55  			expectedURL := "/api/v1/teams/main/pipelines/mypipeline/resource-types/myresource/check"
    56  			atcServer.AppendHandlers(
    57  				ghttp.CombineHandlers(
    58  					ghttp.VerifyRequest("POST", expectedURL),
    59  					ghttp.VerifyJSON(`{"from":{"ref":"fake-ref"}}`),
    60  					ghttp.RespondWithJSONEncoded(http.StatusOK, check),
    61  				),
    62  			)
    63  		})
    64  
    65  		It("sends check resource request to ATC", func() {
    66  			Expect(func() {
    67  				flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource-type", "-r", "mypipeline/myresource", "-f", "ref:fake-ref", "--shallow", "-a")
    68  				sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
    69  				Expect(err).NotTo(HaveOccurred())
    70  
    71  				Eventually(sess).Should(gexec.Exit(0))
    72  
    73  				Eventually(sess.Out).Should(PrintTable(ui.Table{
    74  					Headers: expectedHeaders,
    75  					Data: []ui.TableRow{
    76  						{
    77  							{Contents: "123"},
    78  							{Contents: "myresource"},
    79  							{Contents: "started"},
    80  							{Contents: ""},
    81  						},
    82  					},
    83  				}))
    84  
    85  			}).To(Change(func() int {
    86  				return len(atcServer.ReceivedRequests())
    87  			}).By(2))
    88  		})
    89  	})
    90  
    91  	Context("when version is omitted", func() {
    92  		BeforeEach(func() {
    93  			expectedURL := "/api/v1/teams/main/pipelines/mypipeline/resource-types/myresource/check"
    94  			atcServer.AppendHandlers(
    95  				ghttp.CombineHandlers(
    96  					ghttp.VerifyRequest("POST", expectedURL),
    97  					ghttp.VerifyJSON(`{"from":null}`),
    98  					ghttp.RespondWithJSONEncoded(http.StatusOK, check),
    99  				),
   100  			)
   101  		})
   102  
   103  		It("sends check resource request to ATC", func() {
   104  			Expect(func() {
   105  				flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource-type", "-r", "mypipeline/myresource", "--shallow", "-a")
   106  				sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   107  				Expect(err).NotTo(HaveOccurred())
   108  
   109  				Eventually(sess).Should(gexec.Exit(0))
   110  
   111  				Eventually(sess.Out).Should(PrintTable(ui.Table{
   112  					Headers: expectedHeaders,
   113  					Data: []ui.TableRow{
   114  						{
   115  							{Contents: "123"},
   116  							{Contents: "myresource"},
   117  							{Contents: "started"},
   118  							{Contents: ""},
   119  						},
   120  					},
   121  				}))
   122  
   123  			}).To(Change(func() int {
   124  				return len(atcServer.ReceivedRequests())
   125  			}).By(2))
   126  		})
   127  	})
   128  
   129  	Context("when the check succeed", func() {
   130  		BeforeEach(func() {
   131  			expectedURL := "/api/v1/teams/main/pipelines/mypipeline/resource-types/myresource/check"
   132  			atcServer.AppendHandlers(
   133  				ghttp.CombineHandlers(
   134  					ghttp.VerifyRequest("POST", expectedURL),
   135  					ghttp.VerifyJSON(`{"from":null}`),
   136  					ghttp.RespondWithJSONEncoded(http.StatusOK, check),
   137  				),
   138  				ghttp.CombineHandlers(
   139  					ghttp.VerifyRequest("GET", "/api/v1/checks/123"),
   140  					ghttp.RespondWithJSONEncoded(http.StatusOK, atc.Check{
   141  						ID:         123,
   142  						Status:     "succeeded",
   143  						CreateTime: 100000000000,
   144  						StartTime:  100000000000,
   145  						EndTime:    100000000000,
   146  					}),
   147  				),
   148  			)
   149  		})
   150  
   151  		It("sends check resource request to ATC", func() {
   152  			Expect(func() {
   153  				flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource-type", "-r", "mypipeline/myresource", "--shallow")
   154  				sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   155  				Expect(err).NotTo(HaveOccurred())
   156  
   157  				Eventually(sess).Should(gexec.Exit(0))
   158  
   159  				Eventually(sess.Out).Should(PrintTable(ui.Table{
   160  					Headers: expectedHeaders,
   161  					Data: []ui.TableRow{
   162  						{
   163  							{Contents: "123"},
   164  							{Contents: "myresource"},
   165  							{Contents: "succeeded"},
   166  						},
   167  					},
   168  				}))
   169  
   170  			}).To(Change(func() int {
   171  				return len(atcServer.ReceivedRequests())
   172  			}).By(3))
   173  		})
   174  	})
   175  
   176  	Context("when the check fail", func() {
   177  		BeforeEach(func() {
   178  			expectedURL := "/api/v1/teams/main/pipelines/mypipeline/resource-types/myresource/check"
   179  			atcServer.AppendHandlers(
   180  				ghttp.CombineHandlers(
   181  					ghttp.VerifyRequest("POST", expectedURL),
   182  					ghttp.VerifyJSON(`{"from":null}`),
   183  					ghttp.RespondWithJSONEncoded(http.StatusOK, check),
   184  				),
   185  				ghttp.CombineHandlers(
   186  					ghttp.VerifyRequest("GET", "/api/v1/checks/123"),
   187  					ghttp.RespondWithJSONEncoded(http.StatusOK, atc.Check{
   188  						ID:         123,
   189  						Status:     "errored",
   190  						CreateTime: 100000000000,
   191  						StartTime:  100000000000,
   192  						EndTime:    100000000000,
   193  						CheckError: "some-check-error",
   194  					}),
   195  				),
   196  			)
   197  		})
   198  
   199  		It("sends check resource request to ATC", func() {
   200  			Expect(func() {
   201  				flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource-type", "-r", "mypipeline/myresource", "--shallow")
   202  				sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   203  				Expect(err).NotTo(HaveOccurred())
   204  
   205  				Eventually(sess).Should(gexec.Exit(1))
   206  
   207  				Eventually(sess.Out).Should(PrintTable(ui.Table{
   208  					Headers: expectedHeaders,
   209  					Data: []ui.TableRow{
   210  						{
   211  							{Contents: "123"},
   212  							{Contents: "myresource"},
   213  							{Contents: "errored"},
   214  							{Contents: "some-check-error"},
   215  						},
   216  					},
   217  				}))
   218  
   219  			}).To(Change(func() int {
   220  				return len(atcServer.ReceivedRequests())
   221  			}).By(3))
   222  		})
   223  	})
   224  
   225  	Context("when recursive check succeeds", func() {
   226  		BeforeEach(func() {
   227  			atcServer.AppendHandlers(
   228  				ghttp.CombineHandlers(
   229  					ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines/mypipeline/resource-types"),
   230  					ghttp.RespondWithJSONEncoded(http.StatusOK, resourceTypes),
   231  				),
   232  				ghttp.CombineHandlers(
   233  					ghttp.VerifyRequest("GET", "/api/v1/info"),
   234  					ghttp.RespondWithJSONEncoded(http.StatusOK, atc.Info{Version: atcVersion, WorkerVersion: workerVersion}),
   235  				),
   236  				ghttp.CombineHandlers(
   237  					ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines/mypipeline/resource-types"),
   238  					ghttp.RespondWithJSONEncoded(http.StatusOK, resourceTypes),
   239  				),
   240  				ghttp.CombineHandlers(
   241  					ghttp.VerifyRequest("POST", "/api/v1/teams/main/pipelines/mypipeline/resource-types/myresourcetype/check"),
   242  					ghttp.VerifyJSON(`{"from":null}`),
   243  					ghttp.RespondWithJSONEncoded(http.StatusOK, atc.Check{
   244  						ID:     987,
   245  						Status: "started",
   246  					}),
   247  				),
   248  				ghttp.CombineHandlers(
   249  					ghttp.VerifyRequest("GET", "/api/v1/checks/987"),
   250  					ghttp.RespondWithJSONEncoded(http.StatusOK, atc.Check{
   251  						ID:         987,
   252  						Status:     "succeeded",
   253  						CreateTime: 100000000000,
   254  						StartTime:  100000000000,
   255  						EndTime:    100000000000,
   256  						CheckError: "",
   257  					}),
   258  				),
   259  				ghttp.CombineHandlers(
   260  					ghttp.VerifyRequest("POST", "/api/v1/teams/main/pipelines/mypipeline/resource-types/myresource/check"),
   261  					ghttp.VerifyJSON(`{"from":null}`),
   262  					ghttp.RespondWithJSONEncoded(http.StatusOK, check),
   263  				),
   264  			)
   265  		})
   266  
   267  		It("sends check resource request to ATC", func() {
   268  			Expect(func() {
   269  				flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource-type", "-r", "mypipeline/myresource", "-a")
   270  				sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   271  				Expect(err).NotTo(HaveOccurred())
   272  
   273  				Eventually(sess).Should(gexec.Exit(0))
   274  
   275  				Eventually(sess.Out).Should(PrintTable(ui.Table{
   276  					Headers: expectedHeaders,
   277  					Data: []ui.TableRow{
   278  						{
   279  							{Contents: "987"},
   280  							{Contents: "myresourcetype"},
   281  							{Contents: "succeeded"},
   282  							{Contents: ""},
   283  						},
   284  					},
   285  				}))
   286  
   287  				Eventually(sess.Out).Should(PrintTable(ui.Table{
   288  					Headers: expectedHeaders,
   289  					Data: []ui.TableRow{
   290  						{
   291  							{Contents: "123"},
   292  							{Contents: "myresource"},
   293  							{Contents: "started"},
   294  							{Contents: ""},
   295  						},
   296  					},
   297  				}))
   298  
   299  			}).To(Change(func() int {
   300  				return len(atcServer.ReceivedRequests())
   301  			}).By(7))
   302  		})
   303  	})
   304  
   305  	Context("when recursive check fails", func() {
   306  		BeforeEach(func() {
   307  			atcServer.AppendHandlers(
   308  				ghttp.CombineHandlers(
   309  					ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines/mypipeline/resource-types"),
   310  					ghttp.RespondWithJSONEncoded(http.StatusOK, resourceTypes),
   311  				),
   312  				ghttp.CombineHandlers(
   313  					ghttp.VerifyRequest("GET", "/api/v1/info"),
   314  					ghttp.RespondWithJSONEncoded(http.StatusOK, atc.Info{Version: atcVersion, WorkerVersion: workerVersion}),
   315  				),
   316  				ghttp.CombineHandlers(
   317  					ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines/mypipeline/resource-types"),
   318  					ghttp.RespondWithJSONEncoded(http.StatusOK, resourceTypes),
   319  				),
   320  				ghttp.CombineHandlers(
   321  					ghttp.VerifyRequest("POST", "/api/v1/teams/main/pipelines/mypipeline/resource-types/myresourcetype/check"),
   322  					ghttp.VerifyJSON(`{"from":null}`),
   323  					ghttp.RespondWithJSONEncoded(http.StatusOK, atc.Check{
   324  						ID:     987,
   325  						Status: "started",
   326  					}),
   327  				),
   328  				ghttp.CombineHandlers(
   329  					ghttp.VerifyRequest("GET", "/api/v1/checks/987"),
   330  					ghttp.RespondWithJSONEncoded(http.StatusOK, atc.Check{
   331  						ID:         987,
   332  						Status:     "errored",
   333  						CreateTime: 100000000000,
   334  						StartTime:  100000000000,
   335  						EndTime:    100000000000,
   336  						CheckError: "failed to check",
   337  					}),
   338  				),
   339  			)
   340  		})
   341  
   342  		It("sends check resource request to ATC", func() {
   343  			Expect(func() {
   344  				flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource-type", "-r", "mypipeline/myresource", "-a")
   345  				sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   346  				Expect(err).NotTo(HaveOccurred())
   347  
   348  				Eventually(sess).Should(gexec.Exit(1))
   349  
   350  				Eventually(sess.Out).Should(PrintTable(ui.Table{
   351  					Headers: expectedHeaders,
   352  					Data: []ui.TableRow{
   353  						{
   354  							{Contents: "987"},
   355  							{Contents: "myresourcetype"},
   356  							{Contents: "errored"},
   357  							{Contents: "failed to check"},
   358  						},
   359  					},
   360  				}))
   361  
   362  			}).To(Change(func() int {
   363  				return len(atcServer.ReceivedRequests())
   364  			}).By(6))
   365  		})
   366  	})
   367  
   368  	Context("when pipeline or resource-type is not found", func() {
   369  		BeforeEach(func() {
   370  			expectedURL := "/api/v1/teams/main/pipelines/mypipeline/resource-types/myresource/check"
   371  			atcServer.AppendHandlers(
   372  				ghttp.CombineHandlers(
   373  					ghttp.VerifyRequest("POST", expectedURL),
   374  					ghttp.RespondWithJSONEncoded(http.StatusNotFound, ""),
   375  				),
   376  			)
   377  		})
   378  
   379  		It("fails with error", func() {
   380  			flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource-type", "-r", "mypipeline/myresource", "--shallow")
   381  			sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   382  			Expect(err).NotTo(HaveOccurred())
   383  
   384  			Eventually(sess).Should(gexec.Exit(1))
   385  
   386  			Expect(sess.Err).To(gbytes.Say("pipeline 'mypipeline' or resource-type 'myresource' not found"))
   387  		})
   388  	})
   389  
   390  	Context("When resource-type check returns internal server error", func() {
   391  		BeforeEach(func() {
   392  			expectedURL := "/api/v1/teams/main/pipelines/mypipeline/resource-types/myresource/check"
   393  			atcServer.AppendHandlers(
   394  				ghttp.CombineHandlers(
   395  					ghttp.VerifyRequest("POST", expectedURL),
   396  					ghttp.RespondWith(http.StatusInternalServerError, "unknown server error"),
   397  				),
   398  			)
   399  		})
   400  
   401  		It("outputs error in response body", func() {
   402  			flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource-type", "-r", "mypipeline/myresource", "--shallow")
   403  			sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   404  			Expect(err).NotTo(HaveOccurred())
   405  
   406  			Eventually(sess).Should(gexec.Exit(1))
   407  
   408  			Expect(sess.Err).To(gbytes.Say("unknown server error"))
   409  		})
   410  	})
   411  })