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

     1  package integration_test
     2  
     3  import (
     4  	"net/http"
     5  	"os/exec"
     6  
     7  	"github.com/pf-qiu/concourse/v6/atc"
     8  	"github.com/pf-qiu/concourse/v6/atc/event"
     9  	. "github.com/onsi/ginkgo"
    10  	. "github.com/onsi/gomega"
    11  
    12  	"github.com/onsi/gomega/gbytes"
    13  	"github.com/onsi/gomega/gexec"
    14  	"github.com/onsi/gomega/ghttp"
    15  )
    16  
    17  var _ = Describe("CheckResource", func() {
    18  	var (
    19  		flyCmd              *exec.Cmd
    20  		build               atc.Build
    21  		resource            atc.Resource
    22  		resourceTypes       atc.VersionedResourceTypes
    23  		expectedURL         string
    24  		expectedQueryParams string
    25  	)
    26  
    27  	BeforeEach(func() {
    28  		build = atc.Build{
    29  			ID:        123,
    30  			Status:    "started",
    31  			StartTime: 100000000000,
    32  		}
    33  
    34  		resource = atc.Resource{
    35  			Name: "myresource",
    36  			Type: "myresourcetype",
    37  		}
    38  
    39  		resourceTypes = atc.VersionedResourceTypes{{
    40  			ResourceType: atc.ResourceType{
    41  				Name: "myresourcetype",
    42  				Type: "mybaseresourcetype",
    43  			},
    44  		}}
    45  
    46  		expectedURL = "/api/v1/teams/main/pipelines/mypipeline/resources/myresource/check"
    47  		expectedQueryParams = "instance_vars=%7B%22branch%22%3A%22master%22%7D"
    48  	})
    49  
    50  	Context("when ATC request succeeds", func() {
    51  		BeforeEach(func() {
    52  			atcServer.AppendHandlers(
    53  				ghttp.CombineHandlers(
    54  					ghttp.VerifyRequest("POST", expectedURL, expectedQueryParams),
    55  					ghttp.VerifyJSON(`{"from":{"ref":"fake-ref"}}`),
    56  					ghttp.RespondWithJSONEncoded(http.StatusOK, build),
    57  				),
    58  			)
    59  		})
    60  
    61  		It("sends check resource request to ATC", func() {
    62  			Expect(func() {
    63  				flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource", "-r", "mypipeline/branch:master/myresource", "-f", "ref:fake-ref", "-a", "--shallow")
    64  				sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
    65  				Expect(err).NotTo(HaveOccurred())
    66  
    67  				Eventually(sess).Should(gexec.Exit(0))
    68  				Eventually(sess.Out).Should(gbytes.Say("checking mypipeline/branch:master/myresource in build 123"))
    69  			}).To(Change(func() int {
    70  				return len(atcServer.ReceivedRequests())
    71  			}).By(2))
    72  		})
    73  	})
    74  
    75  	Context("when version is omitted", func() {
    76  		BeforeEach(func() {
    77  			atcServer.AppendHandlers(
    78  				ghttp.CombineHandlers(
    79  					ghttp.VerifyRequest("POST", expectedURL, expectedQueryParams),
    80  					ghttp.VerifyJSON(`{"from":null}`),
    81  					ghttp.RespondWithJSONEncoded(http.StatusOK, build),
    82  				),
    83  			)
    84  		})
    85  
    86  		It("sends check resource request to ATC", func() {
    87  			Expect(func() {
    88  				flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource", "-r", "mypipeline/branch:master/myresource", "--shallow", "-a")
    89  				sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
    90  				Expect(err).NotTo(HaveOccurred())
    91  
    92  				Eventually(sess).Should(gexec.Exit(0))
    93  				Eventually(sess.Out).Should(gbytes.Say("checking mypipeline/branch:master/myresource in build 123"))
    94  			}).To(Change(func() int {
    95  				return len(atcServer.ReceivedRequests())
    96  			}).By(2))
    97  		})
    98  	})
    99  
   100  	Context("when running without --async", func() {
   101  		var streaming chan struct{}
   102  		var events chan atc.Event
   103  
   104  		BeforeEach(func() {
   105  			streaming = make(chan struct{})
   106  			events = make(chan atc.Event)
   107  
   108  			atcServer.AppendHandlers(
   109  				ghttp.CombineHandlers(
   110  					ghttp.VerifyRequest("POST", expectedURL, expectedQueryParams),
   111  					ghttp.VerifyJSON(`{"from":null}`),
   112  					ghttp.RespondWithJSONEncoded(http.StatusOK, build),
   113  				),
   114  				BuildEventsHandler(123, streaming, events),
   115  			)
   116  		})
   117  
   118  		It("checks and watches the build", func() {
   119  			Expect(func() {
   120  				flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource", "-r", "mypipeline/branch:master/myresource", "--shallow")
   121  				sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   122  				Expect(err).NotTo(HaveOccurred())
   123  				Eventually(sess.Out).Should(gbytes.Say("checking mypipeline/branch:master/myresource in build 123"))
   124  
   125  				AssertEvents(sess, streaming, events)
   126  			}).To(Change(func() int {
   127  				return len(atcServer.ReceivedRequests())
   128  			}).By(3))
   129  		})
   130  	})
   131  
   132  	Context("when recursive check succeeds", func() {
   133  		var parentStreaming chan struct{}
   134  		var parentEvents chan atc.Event
   135  
   136  		BeforeEach(func() {
   137  			parentStreaming = make(chan struct{})
   138  			parentEvents = make(chan atc.Event)
   139  
   140  			atcServer.AppendHandlers(
   141  				ghttp.CombineHandlers(
   142  					ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines/mypipeline/resources/myresource", expectedQueryParams),
   143  					ghttp.RespondWithJSONEncoded(http.StatusOK, resource),
   144  				),
   145  				ghttp.CombineHandlers(
   146  					ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines/mypipeline/resource-types", expectedQueryParams),
   147  					ghttp.RespondWithJSONEncoded(http.StatusOK, resourceTypes),
   148  				),
   149  				ghttp.CombineHandlers(
   150  					ghttp.VerifyRequest("GET", "/api/v1/info"),
   151  					ghttp.RespondWithJSONEncoded(http.StatusOK, atc.Info{Version: atcVersion, WorkerVersion: workerVersion}),
   152  				),
   153  				ghttp.CombineHandlers(
   154  					ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines/mypipeline/resource-types", expectedQueryParams),
   155  					ghttp.RespondWithJSONEncoded(http.StatusOK, resourceTypes),
   156  				),
   157  				ghttp.CombineHandlers(
   158  					ghttp.VerifyRequest("POST", "/api/v1/teams/main/pipelines/mypipeline/resource-types/myresourcetype/check", expectedQueryParams),
   159  					ghttp.VerifyJSON(`{"from":null}`),
   160  					ghttp.RespondWithJSONEncoded(http.StatusOK, atc.Build{
   161  						ID:     987,
   162  						Status: "started",
   163  					}),
   164  				),
   165  				BuildEventsHandler(987, parentStreaming, parentEvents),
   166  				ghttp.CombineHandlers(
   167  					ghttp.VerifyRequest("POST", "/api/v1/teams/main/pipelines/mypipeline/resources/myresource/check", expectedQueryParams),
   168  					ghttp.VerifyJSON(`{"from":null}`),
   169  					ghttp.RespondWithJSONEncoded(http.StatusOK, build),
   170  				),
   171  			)
   172  		})
   173  
   174  		It("sends check resource request to ATC", func() {
   175  			Expect(func() {
   176  				flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource", "-r", "mypipeline/branch:master/myresource", "-a")
   177  				sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   178  				Expect(err).NotTo(HaveOccurred())
   179  
   180  				Eventually(sess.Out).Should(gbytes.Say("checking mypipeline/branch:master/myresourcetype in build 987"))
   181  
   182  				parentEvents <- event.Log{Payload: "sup"}
   183  				Eventually(sess.Out).Should(gbytes.Say("sup"))
   184  				close(parentEvents)
   185  
   186  				Eventually(sess.Out).Should(gbytes.Say("checking mypipeline/branch:master/myresource in build 123"))
   187  
   188  				Eventually(sess).Should(gexec.Exit(0))
   189  			}).To(Change(func() int {
   190  				return len(atcServer.ReceivedRequests())
   191  			}).By(8))
   192  		})
   193  	})
   194  
   195  	Context("when recursive check fails", func() {
   196  		var parentStreaming chan struct{}
   197  		var parentEvents chan atc.Event
   198  
   199  		BeforeEach(func() {
   200  			parentStreaming = make(chan struct{})
   201  			parentEvents = make(chan atc.Event)
   202  
   203  			atcServer.AppendHandlers(
   204  				ghttp.CombineHandlers(
   205  					ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines/mypipeline/resources/myresource", expectedQueryParams),
   206  					ghttp.RespondWithJSONEncoded(http.StatusOK, resource),
   207  				),
   208  				ghttp.CombineHandlers(
   209  					ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines/mypipeline/resource-types", expectedQueryParams),
   210  					ghttp.RespondWithJSONEncoded(http.StatusOK, resourceTypes),
   211  				),
   212  				ghttp.CombineHandlers(
   213  					ghttp.VerifyRequest("GET", "/api/v1/info"),
   214  					ghttp.RespondWithJSONEncoded(http.StatusOK, atc.Info{Version: atcVersion, WorkerVersion: workerVersion}),
   215  				),
   216  				ghttp.CombineHandlers(
   217  					ghttp.VerifyRequest("GET", "/api/v1/teams/main/pipelines/mypipeline/resource-types", expectedQueryParams),
   218  					ghttp.RespondWithJSONEncoded(http.StatusOK, resourceTypes),
   219  				),
   220  				ghttp.CombineHandlers(
   221  					ghttp.VerifyRequest("POST", "/api/v1/teams/main/pipelines/mypipeline/resource-types/myresourcetype/check", expectedQueryParams),
   222  					ghttp.VerifyJSON(`{"from":null}`),
   223  					ghttp.RespondWithJSONEncoded(http.StatusOK, atc.Build{
   224  						ID:     987,
   225  						Status: "started",
   226  					}),
   227  				),
   228  				BuildEventsHandler(987, parentStreaming, parentEvents),
   229  			)
   230  		})
   231  
   232  		It("sends check resource request to ATC", func() {
   233  			Expect(func() {
   234  				flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource", "-r", "mypipeline/branch:master/myresource")
   235  				sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   236  				Expect(err).NotTo(HaveOccurred())
   237  
   238  				Eventually(sess.Out).Should(gbytes.Say("checking mypipeline/branch:master/myresourcetype in build 987"))
   239  				AssertErrorEvents(sess, parentStreaming, parentEvents)
   240  			}).To(Change(func() int {
   241  				return len(atcServer.ReceivedRequests())
   242  			}).By(7))
   243  		})
   244  	})
   245  
   246  	Context("when specifying multiple versions", func() {
   247  		BeforeEach(func() {
   248  			atcServer.AppendHandlers(
   249  				ghttp.CombineHandlers(
   250  					ghttp.VerifyRequest("POST", expectedURL, expectedQueryParams),
   251  					ghttp.VerifyJSON(`{"from":{"ref1":"fake-ref-1","ref2":"fake-ref-2"}}`),
   252  					ghttp.RespondWithJSONEncoded(http.StatusOK, build),
   253  				),
   254  			)
   255  		})
   256  
   257  		It("sends correct check resource request to ATC", func() {
   258  			Expect(func() {
   259  				flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource", "-r", "mypipeline/branch:master/myresource", "-f", "ref1:fake-ref-1", "-f", "ref2:fake-ref-2", "--shallow", "-a")
   260  				sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   261  				Expect(err).NotTo(HaveOccurred())
   262  
   263  				Eventually(sess).Should(gexec.Exit(0))
   264  
   265  				Eventually(sess.Out).Should(gbytes.Say("checking mypipeline/branch:master/myresource in build 123"))
   266  			}).To(Change(func() int {
   267  				return len(atcServer.ReceivedRequests())
   268  			}).By(2))
   269  		})
   270  	})
   271  
   272  	Context("when pipeline or resource is not found", func() {
   273  		BeforeEach(func() {
   274  			atcServer.AppendHandlers(
   275  				ghttp.CombineHandlers(
   276  					ghttp.VerifyRequest("POST", expectedURL, expectedQueryParams),
   277  					ghttp.RespondWithJSONEncoded(http.StatusNotFound, ""),
   278  				),
   279  			)
   280  		})
   281  
   282  		It("fails with error", func() {
   283  			flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource", "-r", "mypipeline/branch:master/myresource", "--shallow")
   284  			sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   285  			Expect(err).NotTo(HaveOccurred())
   286  
   287  			Eventually(sess).Should(gexec.Exit(1))
   288  
   289  			Expect(sess.Err).To(gbytes.Say("pipeline 'mypipeline/branch:master' or resource 'myresource' not found"))
   290  		})
   291  	})
   292  
   293  	Context("When resource check returns internal server error", func() {
   294  		BeforeEach(func() {
   295  			atcServer.AppendHandlers(
   296  				ghttp.CombineHandlers(
   297  					ghttp.VerifyRequest("POST", expectedURL, expectedQueryParams),
   298  					ghttp.RespondWith(http.StatusInternalServerError, "unknown server error"),
   299  				),
   300  			)
   301  		})
   302  
   303  		It("outputs error in response body", func() {
   304  			flyCmd = exec.Command(flyPath, "-t", targetName, "check-resource", "-r", "mypipeline/branch:master/myresource", "--shallow")
   305  			sess, err := gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
   306  			Expect(err).NotTo(HaveOccurred())
   307  
   308  			Eventually(sess).Should(gexec.Exit(1))
   309  
   310  			Expect(sess.Err).To(gbytes.Say("unknown server error"))
   311  
   312  		})
   313  	})
   314  })